mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-06 10:46:45 +01:00
Use native big int
This commit is contained in:
4
cli.js
4
cli.js
@@ -23,7 +23,7 @@
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const bigInt = require("big-integer");
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
|
||||
const compiler = require("./src/compiler");
|
||||
|
||||
@@ -82,7 +82,7 @@ const options = {};
|
||||
options.reduceConstraints = !argv.fast;
|
||||
options.verbose = argv.verbose || false;
|
||||
options.sanityCheck = argv.sanitycheck;
|
||||
options.prime = argv.prime || bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
options.prime = argv.prime ? Scalar.fromString(argv.prime) : Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
|
||||
if (argv.csource) {
|
||||
options.cSourceWriteStream = fs.createWriteStream(cSourceName);
|
||||
|
||||
28
package-lock.json
generated
28
package-lock.json
generated
@@ -221,11 +221,11 @@
|
||||
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
|
||||
},
|
||||
"circom_runtime": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.0.3.tgz",
|
||||
"integrity": "sha512-z4ypbs9cTQn7+2FHZNTnccMj6kQCcKT2agYqCrm2kdLBJh9LDoxU1JVu5mSnVuOtgc7BclQ7r0xclG0zP2rxhw==",
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.0.5.tgz",
|
||||
"integrity": "sha512-WEZHnRO1AJIDI2w1yX6rq4G1/MMKnExT3qirjBQR7x43i9Ww3E/wusBHTbXWLb8aYyxsBU07LGy0YXPywPGYvA==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.48",
|
||||
"ffjavascript": "0.1.0",
|
||||
"fnv-plus": "^1.3.1"
|
||||
}
|
||||
},
|
||||
@@ -592,17 +592,17 @@
|
||||
}
|
||||
},
|
||||
"ffjavascript": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.0.5.tgz",
|
||||
"integrity": "sha512-7je6PydOWLDUj3vU8JeCUgeezg4yrG/6qjlukQNuPHeeavnM4REcrN9LA2+xtqIMIPdx/wdUkPMQpixsz+CdIw==",
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.1.0.tgz",
|
||||
"integrity": "sha512-dmKlUasSfvUcxBm8nCSKl2x7EFJsXA7OVP8XLFA03T2+6mAc3IiVLC2ambEVOcMOhyhl0vJfVZjM9f9d38D1rw==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.48"
|
||||
}
|
||||
},
|
||||
"ffwasm": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/ffwasm/-/ffwasm-0.0.6.tgz",
|
||||
"integrity": "sha512-bEBKYANozdyZBCGE6XLg4s/CaJRZdFGQgbthy7EZ4OhNCIpycgklS5mlf88Bw4fXSddlU1V9iYXI4JwfGO3BhQ==",
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/ffwasm/-/ffwasm-0.0.7.tgz",
|
||||
"integrity": "sha512-17cTLzv7HHAKqZbX8MvHxjSrR0yDdn1sh4TVsTbAvO9e6klhFicnyoVXc/sCuViV/M8g65sCmVrAmoPCZp1YkQ==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.48",
|
||||
"wasmbuilder": "0.0.10"
|
||||
@@ -1123,11 +1123,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"r1csfile": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.3.tgz",
|
||||
"integrity": "sha512-TNrodnbHw5yAMv2gj0Ezf22XS3q8zGEjdPHZLBmJauIPFxm6QmyzxlB92yZ5WNkjEtJiS7p1hvkO9/RsJXRDjw==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.4.tgz",
|
||||
"integrity": "sha512-1Y/zzzEjQVTR/gPlduRaKi2K+yU+UxqtsS+obDLEEb4WAzwCkKGybRfp037CUW5OApeleS1WdGmtKv9K9FPhsA==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.48"
|
||||
"ffjavascript": "0.1.0"
|
||||
}
|
||||
},
|
||||
"regexpp": {
|
||||
|
||||
@@ -29,14 +29,13 @@
|
||||
"url": "https://github.com/iden3/circom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"big-integer": "^1.6.32",
|
||||
"chai": "^4.2.0",
|
||||
"circom_runtime": "0.0.3",
|
||||
"circom_runtime": "0.0.5",
|
||||
"ffiasm": "0.0.2",
|
||||
"ffjavascript": "0.0.5",
|
||||
"ffwasm": "0.0.6",
|
||||
"ffjavascript": "0.1.0",
|
||||
"ffwasm": "0.0.7",
|
||||
"fnv-plus": "^1.3.1",
|
||||
"r1csfile": "0.0.3",
|
||||
"r1csfile": "0.0.4",
|
||||
"tmp-promise": "^2.0.2",
|
||||
"wasmbuilder": "0.0.10"
|
||||
},
|
||||
|
||||
166
parser/jaz.jison
166
parser/jaz.jison
@@ -132,10 +132,8 @@ include { return 'include'; }
|
||||
|
||||
|
||||
%{
|
||||
const bigInt = require('big-integer');
|
||||
const Scalar = require('ffjavascript').Scalar;
|
||||
const util = require('util');
|
||||
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
const __MASK__ = new bigInt(2).pow(253).minus(1);
|
||||
|
||||
function setLines(dst, first, last) {
|
||||
last = last || first;
|
||||
@@ -266,20 +264,12 @@ identifierList
|
||||
ifStatment
|
||||
: 'if' '(' expression ')' statment 'else' statment
|
||||
{
|
||||
if ($3.type == "NUMBER") {
|
||||
$$ = !$3.value.eq(0) ? $5 : $7;
|
||||
} else {
|
||||
$$ = { type: "IF", condition: $3, then: $5, else: $7 };
|
||||
}
|
||||
$$ = { type: "IF", condition: $3, then: $5, else: $7 };
|
||||
setLines($$, @1, @7);
|
||||
}
|
||||
| 'if' '(' expression ')' statment
|
||||
{
|
||||
if ($3.type == "NUMBER") {
|
||||
$$ = !$3.value.eq(0) ? $5 : { type: "NUMBER", value: bigInt(0) };
|
||||
} else {
|
||||
$$ = { type: "IF", condition: $3, then: $5 };
|
||||
}
|
||||
$$ = { type: "IF", condition: $3, then: $5 };
|
||||
setLines($$, @1, @5);
|
||||
}
|
||||
;
|
||||
@@ -451,11 +441,7 @@ e17
|
||||
}
|
||||
| e17 '?' e17 ':' e17 %prec TERCOND
|
||||
{
|
||||
if ($1.type == "NUMBER") {
|
||||
$$ = !$1.value.eq(0) ? $3 : $5;
|
||||
} else {
|
||||
$$ = { type: "OP", op: "?", values: [$1, $3, $5] };
|
||||
}
|
||||
$$ = { type: "OP", op: "?", values: [$1, $3, $5] };
|
||||
setLines($$, @1, @5);
|
||||
}
|
||||
| e16 %prec EMPTY
|
||||
@@ -478,11 +464,7 @@ e16
|
||||
e15
|
||||
: e15 '||' e14
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: !$1.value.eq(0) || !$3.value.eq(0) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "||", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "||", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e14 %prec EMPTY
|
||||
@@ -494,11 +476,7 @@ e15
|
||||
e14
|
||||
: e14 '&&' e13
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: !$1.value.eq(0) && !$3.value.eq(0) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "&&", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "&&", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e13 %prec EMPTY
|
||||
@@ -510,11 +488,7 @@ e14
|
||||
e13
|
||||
: e13 '|' e12
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: $1.value.or($3.value).and(__MASK__) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "|", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "|", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e12 %prec EMPTY
|
||||
@@ -527,11 +501,7 @@ e13
|
||||
e12
|
||||
: e12 '^' e11
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: $1.value.xor($3.value).and(__MASK__) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "^", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "^", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e11 %prec EMPTY
|
||||
@@ -543,11 +513,7 @@ e12
|
||||
e11
|
||||
: e11 '&' e10
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: $1.value.and($3.value).and(__MASK__) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "&", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "&", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e10 %prec EMPTY
|
||||
@@ -562,20 +528,12 @@ e11
|
||||
e10
|
||||
: e10 '==' e9
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: $1.value.equals($3.value) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "==", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "==", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e10 '!=' e9
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: $1.value.eq($3.value) ? bigInt(0) : bigInt(1) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "!=", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "!=", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e9 %prec EMPTY
|
||||
@@ -587,38 +545,22 @@ e10
|
||||
e9
|
||||
: e9 '<=' e7
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: $1.value.lesserOrEquals($3.value) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "<=", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "<=", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e9 '>=' e7
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: $1.value.greaterOrEquals($3.value) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: ">=", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: ">=", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e9 '<' e7
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: $1.value.lesser($3.value) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "<", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "<", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e9 '>' e7
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: $1.value.greater($3.value) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: ">", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: ">", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e7 %prec EMPTY
|
||||
@@ -630,22 +572,12 @@ e9
|
||||
e7
|
||||
: e7 '<<' e6
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
let v = $3.value.greater(256) ? 256 : $3.value.value;
|
||||
$$ = { type: "NUMBER", value: $1.value.shiftLeft(v).and(__MASK__) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "<<", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "<<", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e7 '>>' e6
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
let v = $3.value.greater(256) ? 256 : $3.value.value;
|
||||
$$ = {type: "NUMBER", value: $1.value.shiftRight(v).and(__MASK__) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: ">>", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: ">>", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e6 %prec EMPTY
|
||||
@@ -657,20 +589,12 @@ e7
|
||||
e6
|
||||
: e6 '+' e5
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: ($1.value.plus($3.value)).mod(__P__) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "+", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "+", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e6 '-' e5
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: ($1.value.plus(__P__).minus($3.value)).mod(__P__) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "-", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "-", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e5 %prec EMPTY
|
||||
@@ -683,38 +607,22 @@ e6
|
||||
e5
|
||||
: e5 '*' e4
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: ($1.value.times($3.value)).mod(__P__) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "*", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "*", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e5 '/' e4
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: ($1.value.times($3.value.modInv(__P__))).mod(__P__) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "/", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "/", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e5 '\\' e4
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: ($1.value.divide($3.value)) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "\\", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "\\", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e5 '%' e4
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: $1.value.mod($3.value) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "%", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "%", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e4 %prec EMPTY
|
||||
@@ -726,11 +634,7 @@ e5
|
||||
e4
|
||||
: e4 '**' e3
|
||||
{
|
||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||
$$ = { type: "NUMBER", value: $1.value.modPow($3.value, __P__) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "**", values: [$1, $3] };
|
||||
}
|
||||
$$ = { type: "OP", op: "**", values: [$1, $3] };
|
||||
setLines($$, @1, @3);
|
||||
}
|
||||
| e3 %prec EMPTY
|
||||
@@ -758,29 +662,17 @@ e3
|
||||
}
|
||||
| '-' e3 %prec UMINUS
|
||||
{
|
||||
if ($2.type == "NUMBER") {
|
||||
$$ = { type: "NUMBER", value: __P__.minus($2.value).mod(__P__) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "UMINUS", values: [$2] };
|
||||
}
|
||||
$$ = { type: "OP", op: "UMINUS", values: [$2] };
|
||||
setLines($$, @1, @2);
|
||||
}
|
||||
| '!' e3
|
||||
{
|
||||
if ($2.type == "NUMBER") {
|
||||
$$ = { type: "NUMBER", value: $2.value.eq(0) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "!", values: [$2] };
|
||||
}
|
||||
$$ = { type: "OP", op: "!", values: [$2] };
|
||||
setLines($$, @1, @2);
|
||||
}
|
||||
| '~' e3
|
||||
{
|
||||
if ($2.type == "NUMBER") {
|
||||
$$ = { type: "NUMBER", value: $2.value.xor(__MASK__) };
|
||||
} else {
|
||||
$$ = { type: "OP", op: "~", values: [$2] };
|
||||
}
|
||||
$$ = { type: "OP", op: "~", values: [$2] };
|
||||
setLines($$, @1, @2);
|
||||
}
|
||||
| e2 %prec EMPTY
|
||||
@@ -817,12 +709,12 @@ e0
|
||||
}
|
||||
| DECNUMBER
|
||||
{
|
||||
$$ = {type: "NUMBER", value: bigInt($1).mod(__P__) }
|
||||
$$ = {type: "NUMBER", value: Scalar.fromString($1) }
|
||||
setLines($$, @1);
|
||||
}
|
||||
| HEXNUMBER
|
||||
{
|
||||
$$ = {type: "NUMBER", value: bigInt($1.substr(2).toUpperCase(), 16).mod(__P__) }
|
||||
$$ = {type: "NUMBER", value: Scalar.fromString($1.substr(2).toUpperCase(), 16) }
|
||||
setLines($$, @1);
|
||||
}
|
||||
| '(' expression ')' %prec EMPTY
|
||||
|
||||
168
parser/jaz.js
168
parser/jaz.js
@@ -146,21 +146,13 @@ case 20:
|
||||
break;
|
||||
case 21:
|
||||
|
||||
if ($$[$0-4].type == "NUMBER") {
|
||||
this.$ = !$$[$0-4].value.eq(0) ? $$[$0-2] : $$[$0];
|
||||
} else {
|
||||
this.$ = { type: "IF", condition: $$[$0-4], then: $$[$0-2], else: $$[$0] };
|
||||
}
|
||||
this.$ = { type: "IF", condition: $$[$0-4], then: $$[$0-2], else: $$[$0] };
|
||||
setLines(this.$, _$[$0-6], _$[$0]);
|
||||
|
||||
break;
|
||||
case 22:
|
||||
|
||||
if ($$[$0-2].type == "NUMBER") {
|
||||
this.$ = !$$[$0-2].value.eq(0) ? $$[$0] : { type: "NUMBER", value: bigInt(0) };
|
||||
} else {
|
||||
this.$ = { type: "IF", condition: $$[$0-2], then: $$[$0] };
|
||||
}
|
||||
this.$ = { type: "IF", condition: $$[$0-2], then: $$[$0] };
|
||||
setLines(this.$, _$[$0-4], _$[$0]);
|
||||
|
||||
break;
|
||||
@@ -321,11 +313,7 @@ case 50:
|
||||
break;
|
||||
case 51:
|
||||
|
||||
if ($$[$0-4].type == "NUMBER") {
|
||||
this.$ = !$$[$0-4].value.eq(0) ? $$[$0-2] : $$[$0];
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "?", values: [$$[$0-4], $$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "?", values: [$$[$0-4], $$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-4], _$[$0]);
|
||||
|
||||
break;
|
||||
@@ -336,71 +324,43 @@ case 52: case 53: case 54: case 56: case 58: case 60:
|
||||
break;
|
||||
case 55:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: !$$[$0-2].value.eq(0) || !$$[$0].value.eq(0) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "||", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "||", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 57:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: !$$[$0-2].value.eq(0) && !$$[$0].value.eq(0) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "&&", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "&&", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 59:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.or($$[$0].value).and(__MASK__) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "|", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "|", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 61:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.xor($$[$0].value).and(__MASK__) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "^", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "^", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 63:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.and($$[$0].value).and(__MASK__) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "&", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "&", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 65:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.equals($$[$0].value) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "==", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "==", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 66:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.eq($$[$0].value) ? bigInt(0) : bigInt(1) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "!=", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "!=", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
@@ -411,63 +371,37 @@ case 67: case 72:
|
||||
break;
|
||||
case 68:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.lesserOrEquals($$[$0].value) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "<=", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "<=", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 69:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.greaterOrEquals($$[$0].value) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: ">=", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: ">=", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 70:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.lesser($$[$0].value) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "<", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "<", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 71:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.greater($$[$0].value) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: ">", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: ">", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 73:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
let v = $$[$0].value.greater(256) ? 256 : $$[$0].value.value;
|
||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.shiftLeft(v).and(__MASK__) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "<<", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "<<", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 74:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
let v = $$[$0].value.greater(256) ? 256 : $$[$0].value.value;
|
||||
this.$ = {type: "NUMBER", value: $$[$0-2].value.shiftRight(v).and(__MASK__) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: ">>", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: ">>", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
@@ -478,71 +412,43 @@ case 75:
|
||||
break;
|
||||
case 76:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: ($$[$0-2].value.plus($$[$0].value)).mod(__P__) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "+", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "+", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 77:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: ($$[$0-2].value.plus(__P__).minus($$[$0].value)).mod(__P__) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "-", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "-", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 79:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: ($$[$0-2].value.times($$[$0].value)).mod(__P__) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "*", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "*", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 80:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: ($$[$0-2].value.times($$[$0].value.modInv(__P__))).mod(__P__) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "/", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "/", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 81:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: ($$[$0-2].value.divide($$[$0].value)) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "\\", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "\\", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 82:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.mod($$[$0].value) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "%", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "%", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
case 84:
|
||||
|
||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.modPow($$[$0].value, __P__) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "**", values: [$$[$0-2], $$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "**", values: [$$[$0-2], $$[$0]] };
|
||||
setLines(this.$, _$[$0-2], _$[$0]);
|
||||
|
||||
break;
|
||||
@@ -566,31 +472,19 @@ case 88:
|
||||
break;
|
||||
case 89:
|
||||
|
||||
if ($$[$0].type == "NUMBER") {
|
||||
this.$ = { type: "NUMBER", value: __P__.minus($$[$0].value).mod(__P__) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "UMINUS", values: [$$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "UMINUS", values: [$$[$0]] };
|
||||
setLines(this.$, _$[$0-1], _$[$0]);
|
||||
|
||||
break;
|
||||
case 90:
|
||||
|
||||
if ($$[$0].type == "NUMBER") {
|
||||
this.$ = { type: "NUMBER", value: $$[$0].value.eq(0) ? bigInt(1) : bigInt(0) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "!", values: [$$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "!", values: [$$[$0]] };
|
||||
setLines(this.$, _$[$0-1], _$[$0]);
|
||||
|
||||
break;
|
||||
case 91:
|
||||
|
||||
if ($$[$0].type == "NUMBER") {
|
||||
this.$ = { type: "NUMBER", value: $$[$0].value.xor(__MASK__) };
|
||||
} else {
|
||||
this.$ = { type: "OP", op: "~", values: [$$[$0]] };
|
||||
}
|
||||
this.$ = { type: "OP", op: "~", values: [$$[$0]] };
|
||||
setLines(this.$, _$[$0-1], _$[$0]);
|
||||
|
||||
break;
|
||||
@@ -613,13 +507,13 @@ case 97: case 102: case 103:
|
||||
break;
|
||||
case 98:
|
||||
|
||||
this.$ = {type: "NUMBER", value: bigInt($$[$0]).mod(__P__) }
|
||||
this.$ = {type: "NUMBER", value: Scalar.fromString($$[$0]) }
|
||||
setLines(this.$, _$[$0]);
|
||||
|
||||
break;
|
||||
case 99:
|
||||
|
||||
this.$ = {type: "NUMBER", value: bigInt($$[$0].substr(2).toUpperCase(), 16).mod(__P__) }
|
||||
this.$ = {type: "NUMBER", value: Scalar.fromString($$[$0].substr(2).toUpperCase(), 16) }
|
||||
setLines(this.$, _$[$0]);
|
||||
|
||||
break;
|
||||
@@ -866,10 +760,8 @@ parse: function parse(input) {
|
||||
return true;
|
||||
}};
|
||||
|
||||
const bigInt = require('big-integer');
|
||||
const Scalar = require('ffjavascript').Scalar;
|
||||
const util = require('util');
|
||||
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
const __MASK__ = new bigInt(2).pow(253).minus(1);
|
||||
|
||||
function setLines(dst, first, last) {
|
||||
last = last || first;
|
||||
@@ -1365,7 +1257,7 @@ case 77: console.log("INVALID: " + yy_.yytext); return 'INVALID'
|
||||
break;
|
||||
}
|
||||
},
|
||||
rules: [/^(?:\s+)/,/^(?:\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)/,/^(?:\/\/.*)/,/^(?:var\b)/,/^(?:signal\b)/,/^(?:private\b)/,/^(?:input\b)/,/^(?:output\b)/,/^(?:linearCombination\b)/,/^(?:component\b)/,/^(?:template\b)/,/^(?:function\b)/,/^(?:if\b)/,/^(?:else\b)/,/^(?:for\b)/,/^(?:while\b)/,/^(?:compute\b)/,/^(?:do\b)/,/^(?:return\b)/,/^(?:include\b)/,/^(?:0x[0-9A-Fa-f]*)/,/^(?:[0-9]+)/,/^(?:[a-zA-Z][a-zA-Z$_0-9]*)/,/^(?:"[^"]+")/,/^(?:==>)/,/^(?:<==)/,/^(?:-->)/,/^(?:<--)/,/^(?:===)/,/^(?:>>=)/,/^(?:<<=)/,/^(?:&&)/,/^(?:\|\|)/,/^(?:==)/,/^(?:<=)/,/^(?:>=)/,/^(?:!=)/,/^(?:>>)/,/^(?:<<)/,/^(?:\*\*)/,/^(?:\+\+)/,/^(?:--)/,/^(?:\+=)/,/^(?:-=)/,/^(?:\*=)/,/^(?:\/=)/,/^(?:%=)/,/^(?:\|=)/,/^(?:&=)/,/^(?:\^=)/,/^(?:=)/,/^(?:\+)/,/^(?:-)/,/^(?:\*)/,/^(?:\/)/,/^(?:\\)/,/^(?:%)/,/^(?:\^)/,/^(?:&)/,/^(?:\|)/,/^(?:!)/,/^(?:~)/,/^(?:<)/,/^(?:>)/,/^(?:!)/,/^(?:\?)/,/^(?::)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:;)/,/^(?:,)/,/^(?:\.)/,/^(?:$)/,/^(?:.)/],
|
||||
rules: [/^(?:\s+)/,/^(?:\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/)/,/^(?:\/\/.*)/,/^(?:var\b)/,/^(?:signal\b)/,/^(?:private\b)/,/^(?:input\b)/,/^(?:output\b)/,/^(?:linearCombination\b)/,/^(?:component\b)/,/^(?:template\b)/,/^(?:function\b)/,/^(?:if\b)/,/^(?:else\b)/,/^(?:for\b)/,/^(?:while\b)/,/^(?:compute\b)/,/^(?:do\b)/,/^(?:return\b)/,/^(?:include\b)/,/^(?:0x[0-9A-Fa-f]*)/,/^(?:[0-9]+)/,/^(?:[a-zA-Z][a-zA-Z$_0-9]*)/,/^(?:"[^"]+")/,/^(?:==>)/,/^(?:<==)/,/^(?:-->)/,/^(?:<--)/,/^(?:===)/,/^(?:>>=)/,/^(?:<<=)/,/^(?:&&)/,/^(?:\|\|)/,/^(?:==)/,/^(?:<=)/,/^(?:>=)/,/^(?:!=)/,/^(?:>>)/,/^(?:<<)/,/^(?:\*\*)/,/^(?:\+\+)/,/^(?:--)/,/^(?:\+=)/,/^(?:-=)/,/^(?:\*=)/,/^(?:\/=)/,/^(?:%=)/,/^(?:\|=)/,/^(?:&=)/,/^(?:\^=)/,/^(?:=)/,/^(?:\+)/,/^(?:-)/,/^(?:\*)/,/^(?:\/)/,/^(?:\\)/,/^(?:%)/,/^(?:\^)/,/^(?:&)/,/^(?:\|)/,/^(?:!)/,/^(?:~)/,/^(?:<)/,/^(?:>)/,/^(?:!)/,/^(?:\?)/,/^(?::)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:;)/,/^(?:,)/,/^(?:\.)/,/^(?:$)/,/^(?:.)/],
|
||||
conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77],"inclusive":true}}
|
||||
});
|
||||
return lexer;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
const streamFromMultiArray = require("../../src/streamfromarray_txt.js");
|
||||
const bigInt = require("big-integer");
|
||||
const utils = require("../../src/utils");
|
||||
const assert = require("assert");
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
const F1Field = require("ffjavascript").F1Field;
|
||||
|
||||
function ref2src(c) {
|
||||
if ((c[0] == "R")||(c[0] == "RI")) {
|
||||
@@ -340,7 +341,9 @@ class FunctionBuilderC {
|
||||
}
|
||||
|
||||
class BuilderC {
|
||||
constructor() {
|
||||
constructor(p) {
|
||||
this.F = new F1Field(p);
|
||||
|
||||
this.hashMaps={};
|
||||
this.componentEntriesTables={};
|
||||
this.sizes ={};
|
||||
@@ -348,7 +351,6 @@ class BuilderC {
|
||||
this.functions = [];
|
||||
this.components = [];
|
||||
this.usedConstants = {};
|
||||
|
||||
}
|
||||
|
||||
setHeader(header) {
|
||||
@@ -369,9 +371,9 @@ class BuilderC {
|
||||
}
|
||||
|
||||
addConstant(c) {
|
||||
c = bigInt(c);
|
||||
c = this.F.e(c);
|
||||
const cS = c.toString();
|
||||
if (this.usedConstants[cS]) return this.usedConstants[cS];
|
||||
if (typeof this.usedConstants[cS] != "undefined") return this.usedConstants[cS];
|
||||
this.constants.push(c);
|
||||
this.usedConstants[cS] = this.constants.length - 1;
|
||||
return this.constants.length - 1;
|
||||
@@ -471,8 +473,6 @@ class BuilderC {
|
||||
|
||||
_buildConstants(code) {
|
||||
const self = this;
|
||||
const n64 = Math.floor((self.header.P.bitLength() - 1) / 64)+1;
|
||||
const R = bigInt.one.shiftLeft(n64*64);
|
||||
|
||||
code.push("// Constants");
|
||||
code.push(`FrElement _constants[${self.constants.length}] = {`);
|
||||
@@ -482,12 +482,19 @@ class BuilderC {
|
||||
code.push("};");
|
||||
|
||||
function number2Code(n) {
|
||||
if (n.lt(bigInt("80000000", 16)) ) {
|
||||
return addShortMontgomeryPositive(n);
|
||||
}
|
||||
if (n.geq(self.header.P.minus(bigInt("80000000", 16))) ) {
|
||||
return addShortMontgomeryNegative(n);
|
||||
const minShort = self.F.neg(self.F.e("80000000"));
|
||||
const maxShort = self.F.e("7FFFFFFF", 16);
|
||||
|
||||
if ( (self.F.geq(n, minShort))
|
||||
&&(self.F.leq(n, maxShort)))
|
||||
{
|
||||
if (self.F.geq(n, self.F.zero)) {
|
||||
return addShortMontgomeryPositive(n);
|
||||
} else {
|
||||
return addShortMontgomeryNegative(n);
|
||||
}
|
||||
}
|
||||
|
||||
return addLongMontgomery(n);
|
||||
|
||||
|
||||
@@ -506,25 +513,31 @@ class BuilderC {
|
||||
}
|
||||
|
||||
function getLongString(a) {
|
||||
let r = bigInt(a);
|
||||
let S = "";
|
||||
let i = 0;
|
||||
while (!r.isZero()) {
|
||||
if (S!= "") S = S+",";
|
||||
S += "0x" + r.and(bigInt("FFFFFFFFFFFFFFFF", 16)).toString(16) + "LL";
|
||||
i++;
|
||||
r = r.shiftRight(64);
|
||||
}
|
||||
while (i<n64) {
|
||||
if (S!= "") S = S+",";
|
||||
S += "0LL";
|
||||
i++;
|
||||
const arr = Scalar.toArray(a, 0x100000000);
|
||||
for (let i=0; i<self.F.n64*2; i+=2) {
|
||||
const idx = arr.length-2-i;
|
||||
|
||||
if (i>0) S = S + ",";
|
||||
|
||||
if ( idx >=0) {
|
||||
let msb = arr[idx].toString(16);
|
||||
while (msb.length<8) msb = "0" + msb;
|
||||
|
||||
let lsb = arr[idx+1].toString(16);
|
||||
while (lsb.length<8) lsb = "0" + lsb;
|
||||
|
||||
S += "0x" + msb + lsb + "LL";
|
||||
} else {
|
||||
S += "0LL";
|
||||
}
|
||||
}
|
||||
|
||||
return S;
|
||||
}
|
||||
|
||||
function toMontgomery(a) {
|
||||
return a.times(R).mod(self.header.P);
|
||||
return self.F.mul(a, self.F.R);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,12 +8,14 @@ const compiler = require("../../src/compiler");
|
||||
const util = require("util");
|
||||
const exec = util.promisify(require("child_process").exec);
|
||||
|
||||
const bigInt = require("big-integer");
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
const utils = require("../../src/utils");
|
||||
const loadR1cs = require("r1csfile").load;
|
||||
const ZqField = require("ffjavascript").ZqField;
|
||||
const buildZqField = require("ffiasm").buildZqField;
|
||||
|
||||
const {stringifyBigInts, unstringifyBigInts } = require("ffjavascript").utils;
|
||||
|
||||
module.exports = c_tester;
|
||||
|
||||
|
||||
@@ -31,7 +33,7 @@ async function c_tester(circomFile, _options) {
|
||||
options.symWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".sym"));
|
||||
options.r1csFileName = path.join(dir.path, baseName + ".r1cs");
|
||||
|
||||
options.p = options.p || bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
options.p = options.p || Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
await compiler(circomFile, options);
|
||||
|
||||
const source = await buildZqField(options.p, "Fr");
|
||||
@@ -87,7 +89,7 @@ class CTester {
|
||||
async calculateWitness(input) {
|
||||
await fs.promises.writeFile(
|
||||
path.join(this.dir.path, "in.json"),
|
||||
JSON.stringify(utils.stringifyBigInts(input), null, 1)
|
||||
JSON.stringify(stringifyBigInts(input), null, 1)
|
||||
);
|
||||
const r = await exec(`${path.join(this.dir.path, this.baseName)}` +
|
||||
` ${path.join(this.dir.path, "in.json")}` +
|
||||
@@ -100,7 +102,7 @@ class CTester {
|
||||
path.join(this.dir.path, "out.json")
|
||||
);
|
||||
|
||||
const res = utils.unstringifyBigInts(JSON.parse(resStr));
|
||||
const res = unstringifyBigInts(JSON.parse(resStr));
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -127,7 +129,7 @@ class CTester {
|
||||
const self = this;
|
||||
if (this.constraints) return;
|
||||
const r1cs = await loadR1cs(path.join(this.dir.path, this.baseName + ".r1cs"),true, false);
|
||||
self.field = new ZqField(r1cs.prime);
|
||||
self.F = new ZqField(r1cs.prime);
|
||||
self.nVars = r1cs.nVars;
|
||||
self.constraints = r1cs.constraints;
|
||||
}
|
||||
@@ -152,8 +154,8 @@ class CTester {
|
||||
if (typeof self.symbols[prefix] == "undefined") {
|
||||
assert(false, "Output variable not defined: "+ prefix);
|
||||
}
|
||||
const ba = bigInt(actualOut[self.symbols[prefix].varIdx]).toString();
|
||||
const be = bigInt(eOut).toString();
|
||||
const ba = actualOut[self.symbols[prefix].varIdx].toString();
|
||||
const be = eOut.toString();
|
||||
assert.strictEqual(ba, be, prefix);
|
||||
}
|
||||
}
|
||||
@@ -183,7 +185,7 @@ class CTester {
|
||||
}
|
||||
|
||||
function checkConstraint(constraint) {
|
||||
const F = self.field;
|
||||
const F = self.F;
|
||||
const a = evalLC(constraint[0]);
|
||||
const b = evalLC(constraint[1]);
|
||||
const c = evalLC(constraint[2]);
|
||||
@@ -192,7 +194,7 @@ class CTester {
|
||||
}
|
||||
|
||||
function evalLC(lc) {
|
||||
const F = self.field;
|
||||
const F = self.F;
|
||||
let v = F.zero;
|
||||
for (let w in lc) {
|
||||
v = F.add(
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
const streamFromArrayTxt = require("../../src/streamfromarray_txt");
|
||||
const streamFromArrayBin = require("../../src/streamfromarray_bin");
|
||||
const bigInt = require("big-integer");
|
||||
const assert = require("assert");
|
||||
const ModuleBuilder = require("wasmbuilder").ModuleBuilder;
|
||||
const ModuleBuilderWat = require("wasmbuilder").ModuleBuilderWat;
|
||||
const buildRuntime = require("./build_runtime");
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
const F1Field = require("ffjavascript").F1Field;
|
||||
|
||||
|
||||
const errs = require("./errs");
|
||||
@@ -689,7 +690,8 @@ class FunctionBuilderWasm {
|
||||
}
|
||||
|
||||
class BuilderWasm {
|
||||
constructor() {
|
||||
constructor(p) {
|
||||
this.F = new F1Field(p);
|
||||
this.hashMaps={};
|
||||
this.componentEntriesTables={};
|
||||
this.sizes ={};
|
||||
@@ -701,8 +703,8 @@ class BuilderWasm {
|
||||
this.TYPE_SIGNAL = 1;
|
||||
this.TYPE_COMPONENT = 2;
|
||||
|
||||
this.addConstant(bigInt(0)); // constants[0] = 0;
|
||||
this.addConstant(bigInt(1)); // constants[1] = 1;
|
||||
this.addConstant(Scalar.fromString("0")); // constants[0] = 0;
|
||||
this.addConstant(Scalar.fromString("1")); // constants[1] = 1;
|
||||
|
||||
this.offsetComponentNInputSignals = 12;
|
||||
this.sizeofComponent = 20;
|
||||
@@ -710,7 +712,8 @@ class BuilderWasm {
|
||||
|
||||
setHeader(header) {
|
||||
this.header=header;
|
||||
this.n64 = Math.floor((this.header.P.bitLength() - 1) / 64)+1;
|
||||
|
||||
this.n64 = Math.floor((Scalar.bitLength(this.header.P) - 1) / 64)+1;
|
||||
this.sizeFr = this.n64*8 + 8;
|
||||
}
|
||||
|
||||
@@ -728,9 +731,9 @@ class BuilderWasm {
|
||||
}
|
||||
|
||||
addConstant(c) {
|
||||
c = bigInt(c);
|
||||
c = this.F.e(c);
|
||||
const cS = c.toString();
|
||||
if (this.usedConstants[cS]) return this.usedConstants[cS];
|
||||
if (typeof this.usedConstants[cS] != "undefined") return this.usedConstants[cS];
|
||||
this.constants.push(c);
|
||||
this.usedConstants[cS] = this.constants.length - 1;
|
||||
return this.constants.length - 1;
|
||||
@@ -842,7 +845,6 @@ class BuilderWasm {
|
||||
|
||||
_buildConstants(module) {
|
||||
const self = this;
|
||||
const R = bigInt.one.shiftLeft(this.n64*64);
|
||||
|
||||
const bytes = [];
|
||||
for (let i=0; i<self.constants.length; i++) {
|
||||
@@ -852,19 +854,27 @@ class BuilderWasm {
|
||||
const fBytes = [].concat(...bytes);
|
||||
this.pConstants = module.alloc(fBytes);
|
||||
|
||||
|
||||
function Fr2Bytes(n) {
|
||||
if (n.lt(bigInt("80000000", 16)) ) {
|
||||
return shortMontgomeryPositive(n);
|
||||
}
|
||||
if (n.geq(self.header.P.minus(bigInt("80000000", 16))) ) {
|
||||
return shortMontgomeryNegative(n);
|
||||
const minShort = self.F.neg(self.F.e("80000000"));
|
||||
const maxShort = self.F.e("7FFFFFFF", 16);
|
||||
|
||||
if ( (self.F.geq(n, minShort))
|
||||
&&(self.F.leq(n, maxShort)))
|
||||
{
|
||||
if (self.F.geq(n, self.F.zero)) {
|
||||
return shortMontgomeryPositive(n);
|
||||
} else {
|
||||
return shortMontgomeryNegative(n);
|
||||
}
|
||||
}
|
||||
|
||||
return longMontgomery(n);
|
||||
|
||||
|
||||
function shortMontgomeryPositive(a) {
|
||||
return [
|
||||
...intToBytes32(parseInt(a)),
|
||||
...intToBytes32(Scalar.toNumber(a)),
|
||||
...intToBytes32(0x40000000),
|
||||
...long(toMontgomery(a))
|
||||
];
|
||||
@@ -872,9 +882,9 @@ class BuilderWasm {
|
||||
|
||||
|
||||
function shortMontgomeryNegative(a) {
|
||||
const b = a.minus(self.header.P);
|
||||
const b = -Scalar.toNumber(self.F.neg(a));
|
||||
return [
|
||||
...intToBytes32(parseInt(b)),
|
||||
...intToBytes32(b),
|
||||
...intToBytes32(0x40000000),
|
||||
...long(toMontgomery(a))
|
||||
];
|
||||
@@ -889,27 +899,24 @@ class BuilderWasm {
|
||||
}
|
||||
|
||||
function long(a) {
|
||||
|
||||
const bytes = [];
|
||||
let r = bigInt(a);
|
||||
let S = "";
|
||||
let i = 0;
|
||||
while (!r.isZero()) {
|
||||
S = ("0000000000000000" + r.and(bigInt("FFFFFFFFFFFFFFFF", 16)).toString(16)).substr(-16);
|
||||
bytes.push(hexToBytesR(S));
|
||||
i++;
|
||||
r = r.shiftRight(64);
|
||||
}
|
||||
while (i<self.n64) {
|
||||
bytes.push(hexToBytesR("0000000000000000"));
|
||||
i++;
|
||||
const arr = Scalar.toArray(a, 0x100000000);
|
||||
for (let i=0; i<self.F.n64*2; i++) {
|
||||
const idx = arr.length-1-i;
|
||||
|
||||
if ( idx >=0) {
|
||||
bytes.push(...intToBytes32(arr[idx]));
|
||||
} else {
|
||||
bytes.push(...intToBytes32(0));
|
||||
}
|
||||
}
|
||||
|
||||
const fBytes = [].concat(...bytes);
|
||||
return fBytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
function toMontgomery(a) {
|
||||
return a.times(R).mod(self.header.P);
|
||||
return self.F.mul(a, self.F.R);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ var tmp = require("tmp-promise");
|
||||
const path = require("path");
|
||||
const compiler = require("../../src/compiler");
|
||||
|
||||
const bigInt = require("big-integer");
|
||||
const utils = require("../../src/utils");
|
||||
const loadR1cs = require("r1csfile").load;
|
||||
const ZqField = require("ffjavascript").ZqField;
|
||||
@@ -82,7 +81,7 @@ class WasmTester {
|
||||
const self = this;
|
||||
if (this.constraints) return;
|
||||
const r1cs = await loadR1cs(path.join(this.dir.path, this.baseName + ".r1cs"),true, false);
|
||||
self.field = new ZqField(r1cs.prime);
|
||||
self.F = new ZqField(r1cs.prime);
|
||||
self.nVars = r1cs.nVars;
|
||||
self.constraints = r1cs.constraints;
|
||||
}
|
||||
@@ -107,8 +106,8 @@ class WasmTester {
|
||||
if (typeof self.symbols[prefix] == "undefined") {
|
||||
assert(false, "Output variable not defined: "+ prefix);
|
||||
}
|
||||
const ba = bigInt(actualOut[self.symbols[prefix].varIdx]).toString();
|
||||
const be = bigInt(eOut).toString();
|
||||
const ba = actualOut[self.symbols[prefix].varIdx].toString();
|
||||
const be = eOut.toString();
|
||||
assert.strictEqual(ba, be, prefix);
|
||||
}
|
||||
}
|
||||
@@ -138,16 +137,16 @@ class WasmTester {
|
||||
}
|
||||
|
||||
function checkConstraint(constraint) {
|
||||
const F = self.field;
|
||||
const F = self.F;
|
||||
const a = evalLC(constraint[0]);
|
||||
const b = evalLC(constraint[1]);
|
||||
const c = evalLC(constraint[2]);
|
||||
|
||||
assert (F.sub(F.mul(a,b), c).isZero(), "Constraint doesn't match");
|
||||
assert (F.isZero(F.sub(F.mul(a,b), c)), "Constraint doesn't match");
|
||||
}
|
||||
|
||||
function evalLC(lc) {
|
||||
const F = self.field;
|
||||
const F = self.F;
|
||||
let v = F.zero;
|
||||
for (let w in lc) {
|
||||
v = F.add(
|
||||
|
||||
19
src/build.js
19
src/build.js
@@ -18,7 +18,6 @@
|
||||
*/
|
||||
|
||||
const assert = require("assert");
|
||||
const bigInt = require("big-integer");
|
||||
const utils = require("./utils");
|
||||
const gen = require("./gencode").gen;
|
||||
const createRefs = require("./gencode").createRefs;
|
||||
@@ -35,8 +34,8 @@ function build(ctx) {
|
||||
ctx.definedSizes = {};
|
||||
ctx.addSizes = addSizes;
|
||||
ctx.addConstant = addConstant;
|
||||
ctx.addConstant(bigInt.zero);
|
||||
ctx.addConstant(bigInt.one);
|
||||
ctx.addConstant(ctx.F.zero);
|
||||
ctx.addConstant(ctx.F.one);
|
||||
|
||||
buildHeader(ctx);
|
||||
buildEntryTables(ctx);
|
||||
@@ -209,7 +208,7 @@ function buildHeader(ctx) {
|
||||
NInputs: ctx.components[ ctx.getComponentIdx("main") ].nInSignals,
|
||||
NOutputs: ctx.totals[ ctx.stOUTPUT ],
|
||||
NVars: ctx.totals[ctx.stONE] + ctx.totals[ctx.stOUTPUT] + ctx.totals[ctx.stPUBINPUT] + ctx.totals[ctx.stPRVINPUT] + ctx.totals[ctx.stINTERNAL],
|
||||
P: ctx.field.p
|
||||
P: ctx.F.p
|
||||
});
|
||||
}
|
||||
|
||||
@@ -391,7 +390,7 @@ function hashComponentCall(ctx, cIdx) {
|
||||
// TODO: At the moment generate a diferent function for each instance of the component
|
||||
const constParams = [];
|
||||
for (let p in ctx.components[cIdx].params) {
|
||||
constParams.push(p + "=" + value2str(ctx.components[cIdx].params[p]));
|
||||
constParams.push(p + "=" + value2str(ctx.F, ctx.components[cIdx].params[p]));
|
||||
}
|
||||
|
||||
for (let n in ctx.components[cIdx].names.o) {
|
||||
@@ -399,7 +398,7 @@ function hashComponentCall(ctx, cIdx) {
|
||||
if ((entry.type == "S")&&(ctx.signals[entry.offset].o & ctx.IN)) {
|
||||
travelSizes(n, entry.offset, entry.sizes, (prefix, offset) => {
|
||||
if (utils.isDefined(ctx.signals[offset].v)) {
|
||||
constParams.push(prefix + "=" + bigInt(ctx.signals[offset].value));
|
||||
constParams.push(prefix + "=" + ctx.F.e(ctx.signals[offset].v));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -433,7 +432,7 @@ function hashFunctionCall(ctx, name, paramValues) {
|
||||
const constParams = [];
|
||||
for (let i=0; i<ctx.functions[name].params.length; i++) {
|
||||
if (!paramValues[i].used) {
|
||||
constParams.push(ctx.functions[name].params[i] + utils.accSizes2Str(paramValues[i].sizes) + "=" + value2str(paramValues[i].value));
|
||||
constParams.push(ctx.functions[name].params[i] + utils.accSizes2Str(paramValues[i].sizes) + "=" + value2str(ctx.F, paramValues[i].value));
|
||||
}
|
||||
}
|
||||
let instanceDef = name;
|
||||
@@ -447,16 +446,16 @@ function hashFunctionCall(ctx, name, paramValues) {
|
||||
return {h, instanceDef};
|
||||
}
|
||||
|
||||
function value2str(v) {
|
||||
function value2str(F, v) {
|
||||
if (Array.isArray(v)) {
|
||||
let S="[";
|
||||
for (let i=0; i<v.length; i++) {
|
||||
if (i>0) S+=",";
|
||||
S+=value2str(v[i]);
|
||||
S+=value2str(F, v[i]);
|
||||
}
|
||||
S+="]";
|
||||
return S;
|
||||
} else {
|
||||
return bigInt(v).toString();
|
||||
return F.toString(F.e(v));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,15 +17,13 @@
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const bigInt = require("big-integer");
|
||||
const __P__ = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
const sONE = 0;
|
||||
const build = require("./build");
|
||||
const BuilderC = require("../ports/c/builder.js");
|
||||
const BuilderWasm = require("../ports/wasm/builder.js");
|
||||
const constructionPhase = require("./construction_phase");
|
||||
const Ctx = require("./ctx");
|
||||
const ZqField = require("ffjavascript").ZqField;
|
||||
const utils = require("./utils");
|
||||
const buildR1cs = require("./r1csfile").buildR1cs;
|
||||
const BigArray = require("./bigarray");
|
||||
@@ -34,15 +32,14 @@ const buildSyms = require("./buildsyms");
|
||||
module.exports = compile;
|
||||
|
||||
async function compile(srcFile, options) {
|
||||
options.p = options.p || __P__;
|
||||
options.p = options.p || Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
if (typeof options.reduceConstraints === "undefined") {
|
||||
options.reduceConstraints = true;
|
||||
}
|
||||
const ctx = new Ctx();
|
||||
ctx.field = new ZqField(options.p);
|
||||
const ctx = new Ctx(options.p);
|
||||
ctx.verbose= options.verbose || false;
|
||||
ctx.mainComponent = options.mainComponent || "main";
|
||||
ctx.newThreadTemplates = options.newThreadTemplates;
|
||||
@@ -85,7 +82,7 @@ async function compile(srcFile, options) {
|
||||
}
|
||||
|
||||
if (options.cSourceWriteStream) {
|
||||
ctx.builder = new BuilderC();
|
||||
ctx.builder = new BuilderC(options.p);
|
||||
build(ctx);
|
||||
const rdStream = ctx.builder.build();
|
||||
rdStream.pipe(options.cSourceWriteStream);
|
||||
@@ -94,7 +91,7 @@ async function compile(srcFile, options) {
|
||||
}
|
||||
|
||||
if ((options.wasmWriteStream)||(options.watWriteStream)) {
|
||||
ctx.builder = new BuilderWasm();
|
||||
ctx.builder = new BuilderWasm(options.p);
|
||||
build(ctx);
|
||||
if (options.wasmWriteStream) {
|
||||
const rdStream = ctx.builder.build("wasm");
|
||||
@@ -299,11 +296,11 @@ function reduceConstrains(ctx) {
|
||||
t: "LC",
|
||||
coefs: {}
|
||||
};
|
||||
const invCoef = c.c.coefs[isolatedSignal].modInv(__P__);
|
||||
const invCoef = ctx.F.inv(c.c.coefs[isolatedSignal]);
|
||||
for (const s in c.c.coefs) {
|
||||
if (s != isolatedSignal) {
|
||||
const v = __P__.minus(c.c.coefs[s]).times(invCoef).mod(__P__);
|
||||
if (!v.isZero()) {
|
||||
const v = ctx.F.mul( ctx.F.neg(c.c.coefs[s]), invCoef);
|
||||
if (!ctx.F.isZero(v)) {
|
||||
isolatedSignalEquivalence.coefs[s] = v;
|
||||
}
|
||||
}
|
||||
@@ -395,9 +392,9 @@ function reduceConstrains(ctx) {
|
||||
|
||||
function isConstant(l) {
|
||||
for (let k in l.coefs) {
|
||||
if ((k != sONE) && (!l.coefs[k].isZero())) return false;
|
||||
if ((k != sONE) && (!ctx.F.isZero(l.coefs[k]))) return false;
|
||||
}
|
||||
if (!l.coefs[sONE] || l.coefs[sONE].isZero()) return false;
|
||||
if (!l.coefs[sONE] || ctx.F.isZero(l.coefs[sONE])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,10 +49,11 @@ const assert = require("assert");
|
||||
const iterateAST = require("./iterateast");
|
||||
const utils = require("./utils");
|
||||
|
||||
const bigInt = require("big-integer");
|
||||
|
||||
const LCAlgebra = require("./lcalgebra");
|
||||
const parser = require("../parser/jaz.js").parser;
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
|
||||
const {stringifyBigInts} = require("ffjavascript").utils;
|
||||
|
||||
/* TODO: Add lines information
|
||||
|
||||
@@ -79,7 +80,7 @@ function constructionPhase(ctx, srcFile) {
|
||||
|
||||
assert(ctx.ast.type == "BLOCK");
|
||||
|
||||
ctx.lc = new LCAlgebra(ctx.field);
|
||||
ctx.lc = new LCAlgebra(ctx.F);
|
||||
ctx.filePath= fullFilePath;
|
||||
ctx.fileName= fullFileName;
|
||||
ctx.includedFiles = {};
|
||||
@@ -218,7 +219,7 @@ function execNumber(ctx, ast) {
|
||||
s:[1,0],
|
||||
v: [{
|
||||
t: "N",
|
||||
v: bigInt(ast.value)
|
||||
v: ctx.F.e(ast.value)
|
||||
}]
|
||||
};
|
||||
}
|
||||
@@ -253,7 +254,7 @@ function execDeclareComponent(ctx, ast) {
|
||||
const size = val(ctx, sizeRef);
|
||||
if (size.t != "N") return ctx.throwError( ast.name.selectors[i], "expected a number");
|
||||
|
||||
sizes.push( size.v.toJSNumber() );
|
||||
sizes.push( Scalar.toNumber(size.v) );
|
||||
}
|
||||
|
||||
let cIdx = ctx.addComponent(ast.name.name, sizes);
|
||||
@@ -277,7 +278,7 @@ function execDeclareSignal(ctx, ast) {
|
||||
if (ctx.error) return;
|
||||
if (size.s[0] != 1) return ctx.throwError(ast, "Size cannot be an array");
|
||||
if (size.v[0].t != "N") return ctx.throwError(ast, "Size must be declared in construction time");
|
||||
sizes.push( size.v[0].v.toJSNumber() );
|
||||
sizes.push( Scalar.toNumber(size.v[0].v) );
|
||||
}
|
||||
|
||||
let sIdx = ctx.addSignal(ast.name.name, sizes);
|
||||
@@ -322,7 +323,7 @@ function execDeclareVariable(ctx, ast) {
|
||||
if (ctx.error) return;
|
||||
if (size.s[0] != 1) return ctx.throwError(ast, "Size cannot be an array");
|
||||
if (size.v[0].t != "N") return ctx.throwError(ast, "Size must be declared in construction time");
|
||||
sizes.push( size.v[0].v.toJSNumber() );
|
||||
sizes.push( Scalar.toNumber(size.v[0].v) );
|
||||
}
|
||||
|
||||
const v = ctx.refs[ast.refId];
|
||||
@@ -353,7 +354,7 @@ function execAssignement(ctx, ast) {
|
||||
if (sel.s[0] != 1) return ctx.throwError(ast, "Selector cannot be an array");
|
||||
if (sel.v[0].t != "N") return {t: "NQ"};
|
||||
|
||||
leftSels.push( sel.v[0].v.toJSNumber() );
|
||||
leftSels.push( Scalar.toNumber(sel.v[0].v) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,7 +381,7 @@ function execAssignement(ctx, ast) {
|
||||
} else if (right.t == "S") {
|
||||
for (let i=0; i<right.s[0]; i++) {
|
||||
left.v[o+i]={t: "LC", coefs: {}};
|
||||
left.v[o+i].coefs[right.sIdx+i] = ctx.field.one;
|
||||
left.v[o+i].coefs[right.sIdx+i] = ctx.F.one;
|
||||
}
|
||||
}
|
||||
} else if ( left.t == "S") {
|
||||
@@ -561,14 +562,14 @@ function execFunctionCall(ctx, ast) {
|
||||
if (ev.v) {
|
||||
console.log(ev.v.toString());
|
||||
} else {
|
||||
console.log(JSON.stringify(ev));
|
||||
console.log(JSON.stringify(stringifyBigInts(ev)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ast.name == "assert") {
|
||||
const v = exec(ctx, ast.params[0]);
|
||||
const ev = val(ctx, v, ast);
|
||||
if (ev.isZero()) return ctx.throwError(ast, "Assertion failed");
|
||||
if (ctx.F.isZero(ev)) return ctx.throwError(ast, "Assertion failed");
|
||||
}
|
||||
|
||||
const fnc = ctx.functions[ast.name];
|
||||
@@ -634,7 +635,7 @@ function execVariable(ctx, ast) {
|
||||
if (ctx.error) return;
|
||||
if (sel.s[0] != 1) return ctx.throwError(ast, "Variable selector cannot be an array");
|
||||
if (sel.v[0].t != "N") return NQVAL;
|
||||
sels.push(sel.v[0].v.toJSNumber());
|
||||
sels.push(Scalar.toNumber(sel.v[0].v));
|
||||
}
|
||||
|
||||
let o = 0;
|
||||
@@ -682,7 +683,7 @@ function execPin(ctx, ast) {
|
||||
|
||||
if (sel.s[0] != 1) return ctx.throwError(ast, "Component selector cannot be an array");
|
||||
if (sel.v[0].t != "N") return NQVAL;
|
||||
selsC.push(sel.v[0].v.toJSNumber());
|
||||
selsC.push(Scalar.toNumber(sel.v[0].v));
|
||||
}
|
||||
|
||||
const cIdx = ctx.getComponentIdx(ast.component.name, selsC);
|
||||
@@ -694,7 +695,7 @@ function execPin(ctx, ast) {
|
||||
if (ctx.error) return;
|
||||
if (sel.s[0] != 1) return ctx.throwError(ast, "Signal selector cannot be an array");
|
||||
if (sel.v[0].t != "N") return NQVAL;
|
||||
selsP.push(sel.v[0].v.toJSNumber());
|
||||
selsP.push(Scalar.toNumber(sel.v[0].v));
|
||||
}
|
||||
const sIdx = ctx.components[cIdx].names.getSignalIdx(ast.pin.name, selsP);
|
||||
|
||||
@@ -741,7 +742,7 @@ function execLoop(ctx, ast) {
|
||||
return;
|
||||
}
|
||||
|
||||
while ((!v.v[0].v.isZero())&&(!ctx.returnValue)) {
|
||||
while ((! ctx.F.isZero(v.v[0].v))&&(!ctx.returnValue)) {
|
||||
exec(ctx, ast.body);
|
||||
if (ctx.error) return;
|
||||
|
||||
@@ -784,7 +785,7 @@ function execIf(ctx, ast) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!v.v[0].v.isZero()) {
|
||||
if (!ctx.F.isZero(v.v[0].v)) {
|
||||
exec(ctx, ast.then);
|
||||
} else {
|
||||
if (ast.else) {
|
||||
@@ -811,7 +812,7 @@ function execTerCon(ctx, ast) {
|
||||
return NQVAL;
|
||||
}
|
||||
|
||||
if (!v.v[0].v.isZero()) {
|
||||
if (!ctx.F.isZero(v.v[0].v)) {
|
||||
return exec(ctx, ast.values[1]);
|
||||
} else {
|
||||
return exec(ctx, ast.values[2]);
|
||||
@@ -850,7 +851,7 @@ function execOpOp(ctx, ast, op, lr) {
|
||||
if (sel.s[0] != 1) return ctx.throwError(ast, "Selector cannot be an array");
|
||||
if (sel.v[0].t != "N") return {t: "NQ"};
|
||||
|
||||
leftSels.push( sel.v[0].v.toJSNumber() );
|
||||
leftSels.push( Scalar.toNumber(sel.v[0].v) );
|
||||
}
|
||||
}
|
||||
if (!left.s) return ctx.throwError(ast, "variable. not defined yet");
|
||||
@@ -870,7 +871,7 @@ function execOpOp(ctx, ast, op, lr) {
|
||||
if (ctx.error) return;
|
||||
right = val(ctx, rightRef);
|
||||
} else {
|
||||
right = {t:"N", v: ctx.field.one};
|
||||
right = {t:"N", v: ctx.F.one};
|
||||
}
|
||||
|
||||
if (!right) return ctx.throwError(ast, "adding a no number");
|
||||
@@ -907,7 +908,7 @@ function val(ctx, a, ast) {
|
||||
};
|
||||
let sIdx = a.sIdx;
|
||||
while (ctx.signals[sIdx].e >= 0) sIdx = ctx.signals[sIdx].e;
|
||||
res.coefs[sIdx] = ctx.field.one;
|
||||
res.coefs[sIdx] = ctx.F.one;
|
||||
return res;
|
||||
} else {
|
||||
ctx.throwError(ast, "Invalid type: " + a.t);
|
||||
@@ -979,7 +980,7 @@ function execArray(ctx, ast) {
|
||||
} else if (e.t == "S") {
|
||||
for (let j=0; j<e.v.length;j++) {
|
||||
const sv = {t: "LC", coefs: {}};
|
||||
sv.coefs[e.sIdx+j] = ctx.field.one;
|
||||
sv.coefs[e.sIdx+j] = ctx.F.one;
|
||||
res.v.push(sv);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
const bigInt = require("big-integer");
|
||||
const BigArray = require("./bigarray.js");
|
||||
|
||||
const F1Field = require("ffjavascript").F1Field;
|
||||
|
||||
class TableName {
|
||||
constructor (ctx) {
|
||||
@@ -86,7 +85,9 @@ class TableName {
|
||||
|
||||
module.exports = class Ctx {
|
||||
|
||||
constructor() {
|
||||
constructor(p) {
|
||||
|
||||
this.F = new F1Field(p);
|
||||
|
||||
this.stONE = 1;
|
||||
this.stOUTPUT = 2;
|
||||
@@ -121,7 +122,7 @@ module.exports = class Ctx {
|
||||
|
||||
const oneIdx = this.addSignal("one");
|
||||
this.signals[oneIdx] = {
|
||||
v: bigInt(1),
|
||||
v: this.F.one,
|
||||
o: this.ONE,
|
||||
e: -1,
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const bigInt = require("big-integer");
|
||||
const utils = require("./utils");
|
||||
const assert = require("assert");
|
||||
const iterateAST = require("./iterateast");
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
|
||||
module.exports.gen = gen;
|
||||
module.exports.newRef = newRef;
|
||||
@@ -300,7 +300,7 @@ function genDeclareVariable(ctx, ast) {
|
||||
const size = ctx.refs[sizeRef];
|
||||
if (size.sizes[0] != 1) return ctx.throwError(ast, "A selector cannot be an array");
|
||||
if (size.used) return ctx.throwError(ast, "Variable size variables not allowed");
|
||||
sizes.push(size.value[0]);
|
||||
sizes.push(Scalar.toNumber(size.value[0]));
|
||||
}
|
||||
sizes = utils.accSizes(sizes);
|
||||
} else {
|
||||
@@ -320,7 +320,7 @@ function genDeclareVariable(ctx, ast) {
|
||||
}
|
||||
|
||||
function genNumber(ctx, ast) {
|
||||
return newRef(ctx, "BIGINT", "_num", bigInt(ast.value));
|
||||
return newRef(ctx, "BIGINT", "_num", ctx.F.e(ast.value));
|
||||
}
|
||||
|
||||
|
||||
@@ -950,7 +950,7 @@ function genLoop(ctx, ast) {
|
||||
ctx.codeBuilder.assign(loopCond.label, ["R", cond.label], ["V", 0]);
|
||||
} else {
|
||||
if (!utils.isDefined(cond.value)) return ctx.throwError(ast, "condition value not assigned");
|
||||
if (cond.value[0].isZero()) end=true;
|
||||
if (ctx.F.isZero(cond.value[0])) end=true;
|
||||
}
|
||||
|
||||
|
||||
@@ -993,7 +993,7 @@ function genLoop(ctx, ast) {
|
||||
} else {
|
||||
oldCodeBuilder.concat(ctx.codeBuilder);
|
||||
ctx.codeBuilder = oldCodeBuilder;
|
||||
if (cond2.value[0].isZero()) end=true;
|
||||
if (ctx.F.isZero(cond2.value[0])) end=true;
|
||||
}
|
||||
} else {
|
||||
ctx.codeBuilder.assign(loopCond.label, ["R", cond2.label], ["V", 0]);
|
||||
@@ -1042,7 +1042,7 @@ function genIf(ctx, ast) {
|
||||
|
||||
} else {
|
||||
if (!utils.isDefined(cond.value)) return ctx.throwError(ast, "condition value not assigned");
|
||||
if (!cond.value[0].isZero()) {
|
||||
if (!ctx.F.isZero(cond.value[0])) {
|
||||
gen(ctx, ast.then);
|
||||
} else {
|
||||
if (ast.else) {
|
||||
@@ -1109,9 +1109,9 @@ function genOpOp(ctx, ast, op, lr) {
|
||||
const res = ctx.refs[resRef];
|
||||
if (veval.used) {
|
||||
instantiateRef(ctx, resRef);
|
||||
ctx.codeBuilder.fieldOp(res.label, op, [["R", veval.label], ["C", ctx.addConstant(bigInt.one)]]);
|
||||
ctx.codeBuilder.fieldOp(res.label, op, [["R", veval.label], ["C", ctx.addConstant(ctx.F.one)]]);
|
||||
} else {
|
||||
res.value = [ctx.field[op](veval.value[0], bigInt(1))];
|
||||
res.value = [ctx.F[op](veval.value[0], ctx.F.one)];
|
||||
}
|
||||
genVarAssignment(ctx, ast, vRef, ast.values[0].selectors, resRef);
|
||||
if (lr == "RIGHT") {
|
||||
@@ -1157,10 +1157,10 @@ function genOp(ctx, ast, op, nOps, adjustBool) {
|
||||
} else {
|
||||
const params = [];
|
||||
for (let i=0; i<nOps; i++) {
|
||||
params.push(vals[i].value[0]);
|
||||
params.push(ctx.F.e(vals[i].value[0]));
|
||||
}
|
||||
|
||||
rRef = newRef(ctx, "BIGINT", "_tmp", adjustBool ? (ctx.field[op](...params)?bigInt.one:bigInt.zero) : ctx.field[op](...params));
|
||||
rRef = newRef(ctx, "BIGINT", "_tmp", adjustBool ? (ctx.F[op](...params)?ctx.F.one:ctx.F.zero) : ctx.F[op](...params));
|
||||
}
|
||||
return rRef;
|
||||
}
|
||||
@@ -1242,7 +1242,7 @@ function genTerCon(ctx, ast) {
|
||||
|
||||
} else {
|
||||
if (!utils.isDefined(cond.value)) return ctx.throwError(ast, "condition value not assigned");
|
||||
if (!cond.value[0].isZero()) {
|
||||
if (!ctx.F.isZero(cond.value[0])) {
|
||||
return gen(ctx, ast.values[1]);
|
||||
} else {
|
||||
return gen(ctx, ast.values[2]);
|
||||
|
||||
@@ -76,14 +76,13 @@ QEX QEX NQ NQ NQ
|
||||
NQ NQ NQ NQ NQ
|
||||
*/
|
||||
|
||||
const bigInt = require("big-integer");
|
||||
const utils = require("./utils");
|
||||
const sONE = 0;
|
||||
|
||||
class LCAlgebra {
|
||||
constructor (aField) {
|
||||
const self = this;
|
||||
this.field= aField;
|
||||
this.F= aField;
|
||||
[
|
||||
["idiv",2],
|
||||
["mod",2],
|
||||
@@ -118,7 +117,7 @@ class LCAlgebra {
|
||||
}
|
||||
return {
|
||||
t: "N",
|
||||
v: adjustBool ? ( self.field[op](...operands) ? bigInt.one: bigInt.zero) : self.field[op](...operands)
|
||||
v: adjustBool ? ( self.F[op](...operands) ? self.F.one: self.F.zero) : self.F[op](...operands)
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -129,7 +128,7 @@ class LCAlgebra {
|
||||
t: "LC",
|
||||
coefs: {}
|
||||
};
|
||||
lc.coefs[a.sIdx] = bigInt(1);
|
||||
lc.coefs[a.sIdx] = self.F.one;
|
||||
return lc;
|
||||
} else {
|
||||
return a;
|
||||
@@ -200,17 +199,17 @@ class LCAlgebra {
|
||||
function add_N_N(a,b) {
|
||||
return {
|
||||
t: "N",
|
||||
v: self.field.add(a.v, b.v)
|
||||
v: self.F.add(a.v, b.v)
|
||||
};
|
||||
}
|
||||
|
||||
function add_LC_N(a,b) {
|
||||
let res = self._clone(a);
|
||||
if (b.v.isZero()) return res;
|
||||
if (self.F.isZero(b.v)) return res;
|
||||
if (!utils.isDefined(res.coefs[sONE])) {
|
||||
res.coefs[sONE]= b.v;
|
||||
} else {
|
||||
res.coefs[sONE]= self.field.add(res.coefs[sONE], b.v);
|
||||
res.coefs[sONE]= self.F.add(res.coefs[sONE], b.v);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -221,7 +220,7 @@ class LCAlgebra {
|
||||
if (!utils.isDefined(res.coefs[k])) {
|
||||
res.coefs[k]=b.coefs[k];
|
||||
} else {
|
||||
res.coefs[k]= self.field.add(res.coefs[k], b.coefs[k]);
|
||||
res.coefs[k]= self.F.add(res.coefs[k], b.coefs[k]);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
@@ -283,14 +282,14 @@ class LCAlgebra {
|
||||
function mul_N_N(a,b) {
|
||||
return {
|
||||
t: "N",
|
||||
v: self.field.mul(a.v, b.v)
|
||||
v: self.F.mul(a.v, b.v)
|
||||
};
|
||||
}
|
||||
|
||||
function mul_LC_N(a,b) {
|
||||
let res = self._clone(a);
|
||||
for (let k in res.coefs) {
|
||||
res.coefs[k] = self.field.mul(res.coefs[k], b.v);
|
||||
res.coefs[k] = self.F.mul(res.coefs[k], b.v);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -318,10 +317,10 @@ class LCAlgebra {
|
||||
const a = this._signal2lc(_a);
|
||||
let res = this._clone(a);
|
||||
if (res.t == "N") {
|
||||
res.v = this.field.neg(a.v);
|
||||
res.v = this.F.neg(a.v);
|
||||
} else if (res.t == "LC") {
|
||||
for (let k in res.coefs) {
|
||||
res.coefs[k] = this.field.neg(res.coefs[k]);
|
||||
res.coefs[k] = this.F.neg(res.coefs[k]);
|
||||
}
|
||||
} else if (res.t == "QEX") {
|
||||
res.a = this.neg(res.a);
|
||||
@@ -338,10 +337,10 @@ class LCAlgebra {
|
||||
|
||||
div(a, b) {
|
||||
if (b.t == "N") {
|
||||
if (b.v.isZero()) throw new Error("Division by zero");
|
||||
if (this.F.isZero(b.v)) throw new Error("Division by zero");
|
||||
const inv = {
|
||||
t: "N",
|
||||
v: this.field.inv(b.v)
|
||||
v: this.F.inv(b.v)
|
||||
};
|
||||
return this.mul(a, inv);
|
||||
} else {
|
||||
@@ -351,23 +350,23 @@ class LCAlgebra {
|
||||
|
||||
pow(a, b) {
|
||||
if (b.t == "N") {
|
||||
if (b.v.isZero()) {
|
||||
if (this.F.isZero(b.v)) {
|
||||
if (this.isZero(a)) {
|
||||
throw new Error("Zero to the Zero");
|
||||
}
|
||||
return {
|
||||
t: "N",
|
||||
v: this.field.one
|
||||
v: this.F.one
|
||||
};
|
||||
} else if (b.v.eq(this.field.one)) {
|
||||
} else if (this.F.eq(b.v, this.F.one)) {
|
||||
return a;
|
||||
} else if (b.v.eq(bigInt(2))) {
|
||||
} else if (this.F.eq(b.v, this.F.two)) {
|
||||
return this.mul(a,a);
|
||||
} else {
|
||||
if (a.t=="N") {
|
||||
return {
|
||||
t: "N",
|
||||
v: this.field.pow(a.v, b.v)
|
||||
v: this.F.pow(a.v, b.v)
|
||||
};
|
||||
} else {
|
||||
return {t: "NQ"};
|
||||
@@ -381,18 +380,18 @@ class LCAlgebra {
|
||||
substitute(where, signal, equivalence) {
|
||||
if (equivalence.t != "LC") throw new Error("Equivalence must be a Linear Combination");
|
||||
if (where.t == "LC") {
|
||||
if (!utils.isDefined(where.coefs[signal]) || where.coefs[signal].isZero()) return where;
|
||||
if (!utils.isDefined(where.coefs[signal]) || this.F.isZero(where.coefs[signal])) return where;
|
||||
const res=this._clone(where);
|
||||
const coef = res.coefs[signal];
|
||||
for (let k in equivalence.coefs) {
|
||||
if (k != signal) {
|
||||
const v = this.field.mul( coef, equivalence.coefs[k] );
|
||||
const v = this.F.mul( coef, equivalence.coefs[k] );
|
||||
if (!utils.isDefined(res.coefs[k])) {
|
||||
res.coefs[k]=v;
|
||||
} else {
|
||||
res.coefs[k]= this.field.add(res.coefs[k],v);
|
||||
res.coefs[k]= this.F.add(res.coefs[k],v);
|
||||
}
|
||||
if (res.coefs[k].isZero()) delete res.coefs[k];
|
||||
if (this.F.isZero(res.coefs[k])) delete res.coefs[k];
|
||||
}
|
||||
}
|
||||
delete res.coefs[signal];
|
||||
@@ -436,10 +435,10 @@ class LCAlgebra {
|
||||
|
||||
isZero(a) {
|
||||
if (a.t == "N") {
|
||||
return a.v.isZero();
|
||||
return this.F.isZero(a.v);
|
||||
} else if (a.t == "LC") {
|
||||
for (let k in a.coefs) {
|
||||
if (!a.coefs[k].isZero()) return false;
|
||||
if (!this.F.isZero(a.coefs[k])) return false;
|
||||
}
|
||||
return true;
|
||||
} else if (a.t == "QEX") {
|
||||
@@ -455,16 +454,16 @@ class LCAlgebra {
|
||||
} else if (a.t == "LC") {
|
||||
let S="";
|
||||
for (let k in a.coefs) {
|
||||
if (!a.coefs[k].isZero()) {
|
||||
if (!this.F.isZero(a.coefs[k])) {
|
||||
let c;
|
||||
if (a.coefs[k].greater(this.field.p.divide(2))) {
|
||||
if (a.coefs[k].greater(this.F.p.divide(2))) {
|
||||
S = S + "-";
|
||||
c = this.field.p.minus(a.coefs[k]);
|
||||
c = this.F.p.minus(a.coefs[k]);
|
||||
} else {
|
||||
if (S!="") S=S+" + ";
|
||||
c = a.coefs[k];
|
||||
}
|
||||
if (!c.equals(bigInt.one)) {
|
||||
if (!c.equals(this.F.one)) {
|
||||
S = S + c.toString() + "*";
|
||||
}
|
||||
let sIdx = k;
|
||||
@@ -491,11 +490,11 @@ class LCAlgebra {
|
||||
} else if (n.t == "SIGNAL") {
|
||||
return getSignalValue(ctx, n.sIdx);
|
||||
} else if (n.t == "LC") {
|
||||
let v= this.field.zero;
|
||||
let v= this.F.zero;
|
||||
for (let k in n.coefs) {
|
||||
const s = getSignalValue(ctx, k);
|
||||
if (s === null) return null;
|
||||
v = this.field.add(v, this.field.mul( n.coefs[k], s));
|
||||
v = this.F.add(v, this.F.mul( n.coefs[k], s));
|
||||
}
|
||||
return v;
|
||||
} else if (n.type == "QEX") {
|
||||
@@ -506,7 +505,7 @@ class LCAlgebra {
|
||||
const c = this.evaluate(ctx, n.c);
|
||||
if (c === null) return null;
|
||||
|
||||
return this.field.add(this.field.mul(a,b), c);
|
||||
return this.F.add(this.F.mul(a,b), c);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -529,24 +528,24 @@ class LCAlgebra {
|
||||
let s = k;
|
||||
while (ctx.signals[s].e>=0) s= ctx.signals[s].e;
|
||||
if (utils.isDefined(ctx.signals[s].v)&&(k != sONE)) {
|
||||
const v = this.field.mul(res.coefs[k], ctx.signals[s].v);
|
||||
const v = this.F.mul(res.coefs[k], ctx.signals[s].v);
|
||||
if (!utils.isDefined(res.coefs[sONE])) {
|
||||
res.coefs[sONE]=v;
|
||||
} else {
|
||||
res.coefs[sONE]= this.field.add(res.coefs[sONE], v);
|
||||
res.coefs[sONE]= this.F.add(res.coefs[sONE], v);
|
||||
}
|
||||
delete res.coefs[k];
|
||||
} else if (s != k) {
|
||||
if (!utils.isDefined(res.coefs[s])) {
|
||||
res.coefs[s]=res.coefs[k];
|
||||
} else {
|
||||
res.coefs[s]= this.field.add(res.coefs[s], res.coefs[k]);
|
||||
res.coefs[s]= this.F.add(res.coefs[s], res.coefs[k]);
|
||||
}
|
||||
delete res.coefs[k];
|
||||
}
|
||||
}
|
||||
for (let k in res.coefs) {
|
||||
if (res.coefs[k].isZero()) delete res.coefs[k];
|
||||
if (this.F.isZero(res.coefs[k])) delete res.coefs[k];
|
||||
}
|
||||
return res;
|
||||
} else if (a.t == "QEX") {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
const fs = require("fs");
|
||||
const assert = require("assert");
|
||||
const bigInt = require("big-integer");
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
|
||||
module.exports.buildR1cs = buildR1cs;
|
||||
|
||||
@@ -23,10 +23,10 @@ async function buildR1cs(ctx, fileName) {
|
||||
await writeU64(0); // Temporally set to 0 length
|
||||
|
||||
|
||||
const n8 = (Math.floor( (ctx.field.p.bitLength() - 1) / 64) +1)*8;
|
||||
const n8 = (Math.floor( (ctx.F.bitLength - 1) / 64) +1)*8;
|
||||
// Field Def
|
||||
await writeU32(n8); // Temporally set to 0 length
|
||||
await writeBigInt(ctx.field.p);
|
||||
await writeBigInt(ctx.F.p);
|
||||
|
||||
const NWires =
|
||||
ctx.totals[ctx.stONE] +
|
||||
@@ -136,7 +136,7 @@ async function buildR1cs(ctx, fileName) {
|
||||
async function writeBigInt(n, pos) {
|
||||
const b = Buffer.allocUnsafe(n8);
|
||||
|
||||
const dwords = bigInt(n).toArray(0x100000000).value;
|
||||
const dwords = Scalar.toArray(n, 0x100000000);
|
||||
|
||||
for (let i=0; i<dwords.length; i++) {
|
||||
b.writeUInt32LE(dwords[dwords.length-1-i], i*4, 4 );
|
||||
|
||||
41
src/utils.js
41
src/utils.js
@@ -1,5 +1,4 @@
|
||||
const fnv = require("fnv-plus");
|
||||
const bigInt = require("big-integer");
|
||||
|
||||
module.exports.ident =ident;
|
||||
|
||||
@@ -8,8 +7,6 @@ module.exports.flatArray = flatArray;
|
||||
module.exports.csArr = csArr;
|
||||
module.exports.accSizes = accSizes;
|
||||
module.exports.fnvHash = fnvHash;
|
||||
module.exports.stringifyBigInts = stringifyBigInts;
|
||||
module.exports.unstringifyBigInts = unstringifyBigInts;
|
||||
module.exports.sameSizes = sameSizes;
|
||||
module.exports.isDefined = isDefined;
|
||||
module.exports.accSizes2Str = accSizes2Str;
|
||||
@@ -45,7 +42,7 @@ function flatArray(a) {
|
||||
fillArray(res, a[i]);
|
||||
}
|
||||
} else {
|
||||
res.push(bigInt(a));
|
||||
res.push(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,42 +71,6 @@ function fnvHash(str) {
|
||||
return fnv.hash(str, 64).hex();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function stringifyBigInts(o) {
|
||||
if ((typeof(o) == "bigint") || o.eq !== undefined) {
|
||||
return o.toString(10);
|
||||
} else if (Array.isArray(o)) {
|
||||
return o.map(stringifyBigInts);
|
||||
} else if (typeof o == "object") {
|
||||
const res = {};
|
||||
for (let k in o) {
|
||||
res[k] = stringifyBigInts(o[k]);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function unstringifyBigInts(o) {
|
||||
if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
|
||||
return bigInt(o);
|
||||
} else if (Array.isArray(o)) {
|
||||
return o.map(unstringifyBigInts);
|
||||
} else if (typeof o == "object") {
|
||||
const res = {};
|
||||
for (let k in o) {
|
||||
res[k] = unstringifyBigInts(o[k]);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return bigInt(o);
|
||||
}
|
||||
}
|
||||
|
||||
function sameSizes(s1, s2) {
|
||||
if (!Array.isArray(s1)) return false;
|
||||
if (!Array.isArray(s2)) return false;
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
const path = require("path");
|
||||
|
||||
const bigInt = require("big-integer");
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
const F1Field = require("ffjavascript").F1Field;
|
||||
const c_tester = require("../index.js").c_tester;
|
||||
const wasm_tester = require("../index.js").wasm_tester;
|
||||
|
||||
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
const __P__ = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
|
||||
const Fr = new F1Field(__P__);
|
||||
|
||||
const basicCases = require("./basiccases.json");
|
||||
|
||||
function normalize(o) {
|
||||
if ((typeof(o) == "bigint") || o.isZero !== undefined) {
|
||||
const res = bigInt(o);
|
||||
return norm(res);
|
||||
return Fr.e(o);
|
||||
} else if (Array.isArray(o)) {
|
||||
return o.map(normalize);
|
||||
} else if (typeof o == "object") {
|
||||
@@ -21,15 +23,9 @@ function normalize(o) {
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
const res = bigInt(o);
|
||||
return norm(res);
|
||||
return Fr.e(o);
|
||||
}
|
||||
|
||||
function norm(n) {
|
||||
let res = n.mod(__P__);
|
||||
if (res.isNegative()) res = __P__.add(res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user