Use native big int
jump to
@@ -23,7 +23,7 @@ /* eslint-disable no-console */
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);
@@ -221,11 +221,11 @@ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
"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 @@ "yargs": "^15.3.1"
} }, "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 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"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 @@ "type": "git",
"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" },
@@ -132,10 +132,8 @@
%{ -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 @@
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 @@ setLines($$, @1, @3);
} | 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@ setLines($$, @1, @2);
} | '-' 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 @@ $$ = $1
} | 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
@@ -146,21 +146,13 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@ }
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 BuilderC { - constructor() { + constructor(p) { + this.F = new F1Field(p); + this.hashMaps={}; this.componentEntriesTables={}; this.sizes ={};@@ -348,7 +351,6 @@ this.constants = [];
this.functions = []; this.components = []; this.usedConstants = {}; - } setHeader(header) {@@ -369,9 +371,9 @@ this.sizes[name] = accSizes;
} 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 @@ }
_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 @@ }
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 @@ return `0, 0xC0000000, { ${getLongString(toMontgomery(a))} }`;
} 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); + 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"; + } } - while (i<n64) { - if (S!= "") S = S+","; - S += "0LL"; - i++; - } + return S; } function toMontgomery(a) { - return a.times(R).mod(self.header.P); + return self.F.mul(a, self.F.R); } }
@@ -8,11 +8,13 @@ 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 @@ options.cSourceWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".cpp"));
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 @@
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 @@ const resStr = await fs.promises.readFile(
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 @@ async loadConstraints() {
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 @@ } else {
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 @@ checkConstraint(self.constraints[i]);
} 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 @@ assert (F.sub(F.mul(a,b), c).isZero(), "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(
@@ -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 BuilderWasm { - constructor() { + constructor(p) { + this.F = new F1Field(p); this.hashMaps={}; this.componentEntriesTables={}; this.sizes ={};@@ -701,8 +703,8 @@
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 @@ }
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 @@ this.sizes[name] = {table};
} 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 @@
_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 @@
const fBytes = [].concat(...bytes); this.pConstants = module.alloc(fBytes); + function Fr2Bytes(n) { - if (n.lt(bigInt("80000000", 16)) ) { - return shortMontgomeryPositive(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); + } } - if (n.geq(self.header.P.minus(bigInt("80000000", 16))) ) { - 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 @@ }
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 @@ ];
} 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 @@ async loadConstraints() {
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 @@ } else {
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 @@ checkConstraint(self.constraints[i]);
} 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(
@@ -18,7 +18,6 @@ along with circom. If not, see <https://www.gnu.org/licenses/>.
*/ 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 @@ ctx.codes_sizes = [];
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 @@ NComponents: ctx.components.length,
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 @@ const entry = ctx.components[cIdx].names.o[n];
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 @@ // TODO
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 @@ const h = utils.fnvHash(instanceDef);
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 @@ You should have received a copy of the GNU General Public License
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 @@
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 @@ throw(ctx.error);
} 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 @@ // await new Promise(fulfill => options.cSourceWriteStream.on("finish", fulfill));
} 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 @@ const isolatedSignalEquivalence = {
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 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 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 @@ ctx.ast = parser.parse(src);
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 @@ t: "V",
s:[1,0], v: [{ t: "N", - v: bigInt(ast.value) + v: ctx.F.e(ast.value) }] }; }@@ -253,7 +254,7 @@
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 @@ const size = exec(ctx, ast.name.selectors[i]);
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 @@ const size = exec(ctx, ast.name.selectors[i]);
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 @@
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 @@ }
} 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 @@ const ev = val(ctx, v, 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 @@ const sel = exec(ctx, ast.selectors[i]);
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 @@ if (ctx.error) return;
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 @@ const sel = exec(ctx, ast.pin.selectors[i]);
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 @@ // Assert no constraints
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 @@ // Assert no constraints
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 @@ // Assert no constraints
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 @@
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 @@ const rightRef = exec(ctx, ast.values[1]);
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 @@ coefs: {}
}; 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 @@ for (let j=0; j<e.v.length;j++) res.v.push(e.v[j]);
} 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 @@ }
module.exports = class Ctx { - constructor() { + constructor(p) { + + this.F = new F1Field(p); this.stONE = 1; this.stOUTPUT = 2;@@ -121,7 +122,7 @@ this.warnings = [];
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 @@ const sizeRef = gen(ctx, ast.name.selectors[i]);
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 @@ return ast.refId;
} 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 @@ ctx.fnBuilder.definePFrElement(loopCond.label);
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 @@
} 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 @@ leaveConditionalCode(ctx);
} 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 @@ const resRef = newRef(ctx, "BIGINT", "_tmp");
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 @@ ctx.codeBuilder.fieldOp(r.label, op, params);
} 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 @@ return refId;
} 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 @@ operands.push(arguments[i].v);
} 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 @@ const lc = {
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 @@
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 @@ for (let k in b.coefs) {
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 @@
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 @@ neg(_a) {
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 @@ }
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 @@ }
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 @@
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 @@ }
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 @@ return a.v.toString();
} 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 @@ return n.v;
} 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 @@ if (b === null) return null;
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 @@ for (let k in a.coefs) {
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 @@ const pHeaderSize = p;
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 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 );
@@ -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 @@ for (let i=0; i<a.length; i++) {
fillArray(res, a[i]); } } else { - res.push(bigInt(a)); + res.push(a); } } }@@ -72,42 +69,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) {
@@ -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 @@ res[k] = normalize(o[k]);
} 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; - } }