tests works in node 10

This commit is contained in:
Jordi Baylina 2020-03-28 19:40:30 +01:00
parent ab9f9b9479
commit 58f9034286
No known key found for this signature in database
GPG Key ID: 7480C80C1BE43112
38 changed files with 256 additions and 2558 deletions

10
cli.js

@ -313,9 +313,8 @@ async function run() {
if (!zkSnark[protocol]) throw new Error("Invalid protocol"); if (!zkSnark[protocol]) throw new Error("Invalid protocol");
const setup = zkSnark[protocol].setup(cir); const setup = zkSnark[protocol].setup(cir);
fs.writeFileSync(provingKeyName, JSON.stringify(stringifyBigInts(setup.vk_proof), null, 1), "utf-8"); await fs.promises.writeFile(provingKeyName, JSON.stringify(stringifyBigInts(setup.vk_proof), null, 1), "utf-8");
fs.writeFileSync(verificationKeyName, JSON.stringify(stringifyBigInts(setup.vk_verifier), null, 1), "utf-8"); await fs.promises.writeFile(verificationKeyName, JSON.stringify(stringifyBigInts(setup.vk_verifier), null, 1), "utf-8");
process.exit(0);
} else if (argv._[0].toUpperCase() == "CALCULATEWITNESS") { } else if (argv._[0].toUpperCase() == "CALCULATEWITNESS") {
const wasm = await fs.promises.readFile(wasmName); const wasm = await fs.promises.readFile(wasmName);
const input = unstringifyBigInts(JSON.parse(await fs.promises.readFile(inputName, "utf8"))); const input = unstringifyBigInts(JSON.parse(await fs.promises.readFile(inputName, "utf8")));
@ -364,9 +363,8 @@ async function run() {
if (!zkSnark[protocol]) throw new Error("Invalid protocol"); if (!zkSnark[protocol]) throw new Error("Invalid protocol");
const {proof, publicSignals} = zkSnark[protocol].genProof(provingKey, witness); const {proof, publicSignals} = zkSnark[protocol].genProof(provingKey, witness);
fs.writeFileSync(proofName, JSON.stringify(stringifyBigInts(proof), null, 1), "utf-8"); await fs.promises.writeFile(proofName, JSON.stringify(stringifyBigInts(proof), null, 1), "utf-8");
fs.writeFileSync(publicName, JSON.stringify(stringifyBigInts(publicSignals), null, 1), "utf-8"); await fs.promises.writeFile(publicName, JSON.stringify(stringifyBigInts(publicSignals), null, 1), "utf-8");
process.exit(0);
} else if (argv._[0].toUpperCase() == "VERIFY") { } else if (argv._[0].toUpperCase() == "VERIFY") {
const public = unstringifyBigInts(JSON.parse(fs.readFileSync(publicName, "utf8"))); const public = unstringifyBigInts(JSON.parse(fs.readFileSync(publicName, "utf8")));
const verificationKey = unstringifyBigInts(JSON.parse(fs.readFileSync(verificationKeyName, "utf8"))); const verificationKey = unstringifyBigInts(JSON.parse(fs.readFileSync(verificationKeyName, "utf8")));

@ -17,7 +17,6 @@
snarkjs. If not, see <https://www.gnu.org/licenses/>. snarkjs. If not, see <https://www.gnu.org/licenses/>.
*/ */
exports.Circuit = require("./src/circuit.js");
exports.original = { exports.original = {
setup: require("./src/setup_original.js"), setup: require("./src/setup_original.js"),
genProof: require("./src/prover_original.js"), genProof: require("./src/prover_original.js"),
@ -33,8 +32,6 @@ exports.kimleeoh = {
genProof: require("./src/prover_kimleeoh.js"), genProof: require("./src/prover_kimleeoh.js"),
isValid: require("./src/verifier_kimleeoh.js") isValid: require("./src/verifier_kimleeoh.js")
}; };
exports.bigInt = require("./src/bigint.js");
exports.ZqField = require("./src/zqfield.js");
exports.stringifyBigInts = require("./src/stringifybigint.js").stringifyBigInts; exports.stringifyBigInts = require("./src/stringifybigint.js").stringifyBigInts;
exports.unstringifyBigInts = require("./src/stringifybigint.js").unstringifyBigInts; exports.unstringifyBigInts = require("./src/stringifybigint.js").unstringifyBigInts;

8
package-lock.json generated

@ -595,6 +595,14 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true "dev": true
}, },
"ffjavascript": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.0.3.tgz",
"integrity": "sha512-uXbiC7cNbFzNJCdkGlbQf2d7GciY1ICMcBeAA7+D8RHPr9Y5zYiDRWtU5etjAV8TplE7eZQ9Iqd9ieFi0ARJLA==",
"requires": {
"big-integer": "^1.6.48"
}
},
"figures": { "figures": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",

@ -32,6 +32,7 @@
"chai": "^4.2.0", "chai": "^4.2.0",
"circom_runtime": "0.0.3", "circom_runtime": "0.0.3",
"escape-string-regexp": "^1.0.5", "escape-string-regexp": "^1.0.5",
"ffjavascript": "0.0.3",
"keccak": "^3.0.0", "keccak": "^3.0.0",
"r1csfile": "0.0.3", "r1csfile": "0.0.3",
"yargs": "^12.0.5" "yargs": "^12.0.5"

@ -17,9 +17,9 @@
snarkjs. If not, see <https://www.gnu.org/licenses/>. snarkjs. If not, see <https://www.gnu.org/licenses/>.
*/ */
const bigInt = require("./bigint.js"); const bigInt = require("big-integer");
const F1Field = require("./zqfield.js"); const F1Field = require("ffjavascript").ZqField;
const F2Field = require("./f2field.js"); const F2Field = require("./f2field.js");
const F3Field = require("./f3field.js"); const F3Field = require("./f3field.js");
const GCurve = require("./gcurve.js"); const GCurve = require("./gcurve.js");
@ -81,14 +81,14 @@ class BN128 {
this.loop_count_bits = []; // Constant this.loop_count_bits = []; // Constant
while (!lc.isZero()) { while (!lc.isZero()) {
this.loop_count_bits.push( lc.isOdd() ); this.loop_count_bits.push( lc.isOdd() );
lc = lc.shr(1); lc = lc.shiftRight(1);
} }
this.two_inv = this.F1.inverse(bigInt(2)); this.two_inv = this.F1.inv(bigInt(2));
this.coef_b = bigInt(3); this.coef_b = bigInt(3);
this.twist = [bigInt(9) , bigInt(1)]; this.twist = [bigInt(9) , bigInt(1)];
this.twist_coeff_b = this.F2.mulScalar( this.F2.inverse(this.twist), this.coef_b ); this.twist_coeff_b = this.F2.mulScalar( this.F2.inv(this.twist), this.coef_b );
this.frobenius_coeffs_c1_1 = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208582"); this.frobenius_coeffs_c1_1 = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208582");
this.twist_mul_by_q_X = this.twist_mul_by_q_X =
@ -163,12 +163,12 @@ class BN128 {
} }
const Q1 = this.G2.affine(this._g2MulByQ(Qcopy)); const Q1 = this.G2.affine(this._g2MulByQ(Qcopy));
if (!this.F2.equals(Q1[2], this.F2.one)) if (!this.F2.eq(Q1[2], this.F2.one))
{ {
throw new Error("Expected values are not equal"); throw new Error("Expected values are not equal");
} }
const Q2 = this.G2.affine(this._g2MulByQ(Q1)); const Q2 = this.G2.affine(this._g2MulByQ(Q1));
if (!this.F2.equals(Q2[2], this.F2.one)) if (!this.F2.eq(Q2[2], this.F2.one))
{ {
throw new Error("Expected values are not equal"); throw new Error("Expected values are not equal");
} }

@ -17,7 +17,7 @@
snarkjs. If not, see <https://www.gnu.org/licenses/>. snarkjs. If not, see <https://www.gnu.org/licenses/>.
*/ */
const bigInt = require("./bigint"); const bigInt = require("big-integer");
module.exports = calculateWitness; module.exports = calculateWitness;

@ -17,7 +17,7 @@
snarkjs. If not, see <https://www.gnu.org/licenses/>. snarkjs. If not, see <https://www.gnu.org/licenses/>.
*/ */
const bigInt = require("./bigint.js"); const bigInt = require("big-integer");
const __P__ = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const __P__ = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
const __MASK__ = bigInt("28948022309329048855892746252171976963317496166410141009864396001978282409983"); // 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF const __MASK__ = bigInt("28948022309329048855892746252171976963317496166410141009864396001978282409983"); // 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

@ -70,18 +70,18 @@ class F2Field {
this.F.add(aA, bB))]; this.F.add(aA, bB))];
} }
inverse(a) { inv(a) {
const t0 = this.F.square(a[0]); const t0 = this.F.square(a[0]);
const t1 = this.F.square(a[1]); const t1 = this.F.square(a[1]);
const t2 = this.F.sub(t0, this._mulByNonResidue(t1)); const t2 = this.F.sub(t0, this._mulByNonResidue(t1));
const t3 = this.F.inverse(t2); const t3 = this.F.inv(t2);
return [ return [
this.F.mul(a[0], t3), this.F.mul(a[0], t3),
this.F.neg(this.F.mul( a[1], t3)) ]; this.F.neg(this.F.mul( a[1], t3)) ];
} }
div(a, b) { div(a, b) {
return this.mul(a, this.inverse(b)); return this.mul(a, this.inv(b));
} }
square(a) { square(a) {
@ -112,12 +112,8 @@ class F2Field {
return this.F.isZero(a[0]) && this.F.isZero(a[1]); return this.F.isZero(a[0]) && this.F.isZero(a[1]);
} }
equals(a, b) { eq(a, b) {
return this.F.equals(a[0], b[0]) && this.F.equals(a[1], b[1]); return this.F.eq(a[0], b[0]) && this.F.eq(a[1], b[1]);
}
affine(a) {
return [this.F.affine(a[0]), this.F.affine(a[1])];
} }
mulScalar(base, e) { mulScalar(base, e) {

@ -92,7 +92,7 @@ class F3Field {
bB)]; // (a+c)*(A+C)-aA+bB-cC) bB)]; // (a+c)*(A+C)-aA+bB-cC)
} }
inverse(a) { inv(a) {
const t0 = this.F.square(a[0]); // t0 = a^2 ; const t0 = this.F.square(a[0]); // t0 = a^2 ;
const t1 = this.F.square(a[1]); // t1 = b^2 ; const t1 = this.F.square(a[1]); // t1 = b^2 ;
const t2 = this.F.square(a[2]); // t2 = c^2; const t2 = this.F.square(a[2]); // t2 = c^2;
@ -105,9 +105,9 @@ class F3Field {
const c1 = this.F.sub(this._mulByNonResidue(t2), t3); const c1 = this.F.sub(this._mulByNonResidue(t2), t3);
const c2 = this.F.sub(t1, t4); // c2 = t1-t4 const c2 = this.F.sub(t1, t4); // c2 = t1-t4
// t6 = (a * c0 + non_residue * (c * c1 + b * c2)).inverse(); // t6 = (a * c0 + non_residue * (c * c1 + b * c2)).inv();
const t6 = const t6 =
this.F.inverse( this.F.inv(
this.F.add( this.F.add(
this.F.mul(a[0], c0), this.F.mul(a[0], c0),
this._mulByNonResidue( this._mulByNonResidue(
@ -122,7 +122,7 @@ class F3Field {
} }
div(a, b) { div(a, b) {
return this.mul(a, this.inverse(b)); return this.mul(a, this.inv(b));
} }
square(a) { square(a) {
@ -152,8 +152,8 @@ class F3Field {
return this.F.isZero(a[0]) && this.F.isZero(a[1]) && this.F.isZero(a[2]); return this.F.isZero(a[0]) && this.F.isZero(a[1]) && this.F.isZero(a[2]);
} }
equals(a, b) { eq(a, b) {
return this.F.equals(a[0], b[0]) && this.F.equals(a[1], b[1]) && this.F.equals(a[2], b[2]); return this.F.eq(a[0], b[0]) && this.F.eq(a[1], b[1]) && this.F.eq(a[2], b[2]);
} }
affine(a) { affine(a) {

@ -17,7 +17,7 @@
snarkjs. If not, see <https://www.gnu.org/licenses/>. snarkjs. If not, see <https://www.gnu.org/licenses/>.
*/ */
const bigInt = require("./bigint.js"); const bigInt = require("big-integer");
exports.mulScalar = (F, base, e) =>{ exports.mulScalar = (F, base, e) =>{
let res = F.zero; let res = F.zero;
@ -29,7 +29,7 @@ exports.mulScalar = (F, base, e) =>{
res = F.add(res, exp); res = F.add(res, exp);
} }
exp = F.double(exp); exp = F.double(exp);
rem = rem.shr(1); rem = rem.shiftRight(1);
} }
return res; return res;
@ -46,7 +46,7 @@ exports.exp = (F, base, e) =>{
res = F.mul(res, exp); res = F.mul(res, exp);
} }
exp = F.square(exp); exp = F.square(exp);
rem = rem.shr(1); rem = rem.shiftRight(1);
} }
return res; return res;

@ -23,21 +23,17 @@ class GCurve {
constructor(F, g) { constructor(F, g) {
this.F = F; this.F = F;
this.g = [F.copy(g[0]), F.copy(g[1])]; this.g = g;
if (this.g.length == 2) this.g[2] = this.F.one; if (this.g.length == 2) this.g[2] = this.F.one;
this.zero = [this.F.zero, this.F.one, this.F.zero]; this.zero = [this.F.zero, this.F.one, this.F.zero];
} }
isZero(p) {
return this.F.isZero(p[2]);
}
add(p1, p2) { add(p1, p2) {
const F = this.F; const F = this.F;
if (this.isZero(p1)) return p2; if (this.eq(p1, this.zero)) return p2;
if (this.isZero(p2)) return p1; if (this.eq(p2, this.zero)) return p1;
const res = new Array(3); const res = new Array(3);
@ -53,7 +49,7 @@ class GCurve {
const S1 = F.mul( p1[1] , Z2_cubed); // S1 = Y1 * Z2 * Z2Z2 const S1 = F.mul( p1[1] , Z2_cubed); // S1 = Y1 * Z2 * Z2Z2
const S2 = F.mul( p2[1] , Z1_cubed); // S2 = Y2 * Z1 * Z1Z1 const S2 = F.mul( p2[1] , Z1_cubed); // S2 = Y2 * Z1 * Z1Z1
if (F.equals(U1,U2) && F.equals(S1,S2)) { if (F.eq(U1,U2) && F.eq(S1,S2)) {
return this.double(p1); return this.double(p1);
} }
@ -102,7 +98,7 @@ class GCurve {
const res = new Array(3); const res = new Array(3);
if (this.isZero(p)) return p; if (this.eq(p, this.zero)) return p;
const A = F.square( p[0] ); // A = X1^2 const A = F.square( p[0] ); // A = X1^2
const B = F.square( p[1] ); // B = Y1^2 const B = F.square( p[1] ); // B = Y1^2
@ -142,27 +138,27 @@ class GCurve {
affine(p) { affine(p) {
const F = this.F; const F = this.F;
if (this.isZero(p)) { if (this.eq(p, this.zero)) {
return this.zero; return this.zero;
} else { } else {
const Z_inv = F.inverse(p[2]); const Z_inv = F.inv(p[2]);
const Z2_inv = F.square(Z_inv); const Z2_inv = F.square(Z_inv);
const Z3_inv = F.mul(Z2_inv, Z_inv); const Z3_inv = F.mul(Z2_inv, Z_inv);
const res = new Array(3); const res = new Array(3);
res[0] = F.affine( F.mul(p[0],Z2_inv)); res[0] = F.mul(p[0],Z2_inv);
res[1] = F.affine( F.mul(p[1],Z3_inv)); res[1] = F.mul(p[1],Z3_inv);
res[2] = F.one; res[2] = F.one;
return res; return res;
} }
} }
equals(p1, p2) { eq(p1, p2) {
const F = this.F; const F = this.F;
if (this.isZero(p1)) return this.isZero(p2); if (this.F.eq(p1[2], this.F.zero)) return this.F.eq(p2[2], this.F.zero);
if (this.isZero(p2)) return this.isZero(p1); if (this.F.eq(p2[2], this.F.zero)) return false;
const Z1Z1 = F.square( p1[2] ); const Z1Z1 = F.square( p1[2] );
const Z2Z2 = F.square( p2[2] ); const Z2Z2 = F.square( p2[2] );
@ -176,7 +172,7 @@ class GCurve {
const S1 = F.mul( p1[1] , Z2_cubed); const S1 = F.mul( p1[1] , Z2_cubed);
const S2 = F.mul( p2[1] , Z1_cubed); const S2 = F.mul( p2[1] , Z1_cubed);
return (F.equals(U1,U2) && F.equals(S1,S2)); return (F.eq(U1,U2) && F.eq(S1,S2));
} }
toString(p) { toString(p) {

@ -24,26 +24,26 @@
by the array [ p0, p1, p2, ... , pn ]. by the array [ p0, p1, p2, ... , pn ].
*/ */
const bigInt = require("./bigint.js"); const bigInt = require("big-integer");
class PolField { class PolField {
constructor (F) { constructor (F) {
this.F = F; this.F = F;
const q = this.F.q; const q = this.F.p;
let rem = q.sub(bigInt(1)); let rem = q.minus(bigInt(1));
let s = 0; let s = 0;
while (!rem.isOdd()) { while (!rem.isOdd()) {
s ++; s ++;
rem = rem.shr(1); rem = rem.shiftRight(1);
} }
const five = this.F.add(this.F.add(this.F.two, this.F.two), this.F.one); const five = this.F.add(this.F.add(this.F.two, this.F.two), this.F.one);
this.w = new Array(s+1); this.w = new Array(s+1);
this.wi = new Array(s+1); this.wi = new Array(s+1);
this.w[s] = this.F.exp(five, rem); this.w[s] = this.F.pow(five, rem);
this.wi[s] = this.F.inverse(this.w[s]); this.wi[s] = this.F.inv(this.w[s]);
let n=s-1; let n=s-1;
while (n>=0) { while (n>=0) {
@ -106,8 +106,8 @@ class PolField {
} }
mulScalar(p, b) { mulScalar(p, b) {
if (this.F.isZero(b)) return []; if (this.F.eq(b, this.F.zero)) return [];
if (this.F.equals(b, this.F.one)) return p; if (this.F.eq(b, this.F.one)) return p;
const res = new Array(p.length); const res = new Array(p.length);
for (let i=0; i<p.length; i++) { for (let i=0; i<p.length; i++) {
res[i] = this.F.mul(p[i], b); res[i] = this.F.mul(p[i], b);
@ -163,13 +163,13 @@ class PolField {
const res = __fft(this, tres, bitsResult, 0, 1, true); const res = __fft(this, tres, bitsResult, 0, 1, true);
const twoinvm = this.F.inverse( this.F.mulScalar(this.F.one, m) ); const twoinvm = this.F.inv( this.F.mulScalar(this.F.one, m) );
const resn = new Array(m); const resn = new Array(m);
for (let i=0; i<m; i++) { for (let i=0; i<m; i++) {
resn[i] = this.F.mul(res[(m-i)%m], twoinvm); resn[i] = this.F.mul(res[(m-i)%m], twoinvm);
} }
return this.reduce(this.affine(resn)); return this.reduce(resn);
} }
@ -231,7 +231,7 @@ class PolField {
let mpol = this.ruffini(roots, points[i][0]); let mpol = this.ruffini(roots, points[i][0]);
const factor = const factor =
this.F.mul( this.F.mul(
this.F.inverse(this.eval(mpol, points[i][0])), this.F.inv(this.eval(mpol, points[i][0])),
points[i][1]); points[i][1]);
mpol = this.mulScalar(mpol, factor); mpol = this.mulScalar(mpol, factor);
sum = this.add(sum, mpol); sum = this.add(sum, mpol);
@ -260,7 +260,7 @@ class PolField {
const ep = this.extend(p, m); const ep = this.extend(p, m);
const res = __fft(this, ep, bits, 0, 1); const res = __fft(this, ep, bits, 0, 1);
const twoinvm = this.F.inverse( this.F.mulScalar(this.F.one, m) ); const twoinvm = this.F.inv( this.F.mulScalar(this.F.one, m) );
const resn = new Array(m); const resn = new Array(m);
for (let i=0; i<m; i++) { for (let i=0; i<m; i++) {
resn[i] = this.F.mul(res[(m-i)%m], twoinvm); resn[i] = this.F.mul(res[(m-i)%m], twoinvm);
@ -303,26 +303,19 @@ class PolField {
reduce(p) { reduce(p) {
if (p.length == 0) return p; if (p.length == 0) return p;
if (! this.F.isZero(p[p.length-1]) ) return p; if (! this.F.eq(p[p.length-1], this.F.zero) ) return p;
let i=p.length-1; let i=p.length-1;
while( i>0 && this.F.isZero(p[i]) ) i--; while( i>0 && this.F.eq(p[i], this.F.zero) ) i--;
return p.slice(0, i+1); return p.slice(0, i+1);
} }
affine(p) {
for (let i=0; i<p.length; i++) {
p[i] = this.F.affine(p[i]);
}
return p;
}
equals(a, b) { equals(a, b) {
const pa = this.reduce(this.affine(a)); const pa = this.reduce(this.affine(a));
const pb = this.reduce(this.affine(b)); const pb = this.reduce(this.affine(b));
if (pa.length != pb.length) return false; if (pa.length != pb.length) return false;
for (let i=0; i<pb.length; i++) { for (let i=0; i<pb.length; i++) {
if (!this.F.equals(pa[i], pb[i])) return false; if (!this.F.eq(pa[i], pb[i])) return false;
} }
return true; return true;
@ -352,7 +345,7 @@ class PolField {
const ap = this.affine(p); const ap = this.affine(p);
let S = ""; let S = "";
for (let i=ap.length-1; i>=0; i--) { for (let i=ap.length-1; i>=0; i--) {
if (!this.F.isZero(p[i])) { if (!this.F.eq(p[i], this.F.zero)) {
if (S!="") S += " + "; if (S!="") S += " + ";
S = S + p[i].toString(10); S = S + p[i].toString(10);
if (i>0) { if (i>0) {
@ -370,7 +363,7 @@ class PolField {
_reciprocal(p, bits) { _reciprocal(p, bits) {
const k = 1 << bits; const k = 1 << bits;
if (k==1) { if (k==1) {
return [ this.F.inverse(p[0]) ]; return [ this.F.inv(p[0]) ];
} }
const np = this.scaleX(p, -k/2); const np = this.scaleX(p, -k/2);
const q = this._reciprocal(np, bits-1); const q = this._reciprocal(np, bits-1);
@ -464,19 +457,19 @@ class PolField {
computeVanishingPolinomial(bits, t) { computeVanishingPolinomial(bits, t) {
const m = 1 << bits; const m = 1 << bits;
return this.F.sub(this.F.exp(t, bigInt(m)), this.F.one); return this.F.sub(this.F.pow(t, bigInt(m)), this.F.one);
} }
evaluateLagrangePolynomials(bits, t) { evaluateLagrangePolynomials(bits, t) {
const m= 1 << bits; const m= 1 << bits;
const tm = this.F.exp(t, bigInt(m)); const tm = this.F.pow(t, bigInt(m));
const u= new Array(m).fill(this.F.zero); const u= new Array(m).fill(this.F.zero);
this._setRoots(bits); this._setRoots(bits);
const omega = this.w[bits]; const omega = this.w[bits];
if (this.F.equals(tm, this.F.one)) { if (this.F.eq(tm, this.F.one)) {
for (let i = 0; i < m; i++) { for (let i = 0; i < m; i++) {
if (this.F.equals(this.roots[bits][0],t)) { // i.e., t equals omega^i if (this.F.eq(this.roots[bits][0],t)) { // i.e., t equals omega^i
u[i] = this.F.one; u[i] = this.F.one;
return u; return u;
} }
@ -484,10 +477,10 @@ class PolField {
} }
const z = this.F.sub(tm, this.F.one); const z = this.F.sub(tm, this.F.one);
// let l = this.F.mul(z, this.F.exp(this.F.twoinv, m)); // let l = this.F.mul(z, this.F.pow(this.F.twoinv, m));
let l = this.F.mul(z, this.F.inverse(bigInt(m))); let l = this.F.mul(z, this.F.inv(bigInt(m)));
for (let i = 0; i < m; i++) { for (let i = 0; i < m; i++) {
u[i] = this.F.mul(l, this.F.inverse(this.F.sub(t,this.roots[bits][i]))); u[i] = this.F.mul(l, this.F.inv(this.F.sub(t,this.roots[bits][i])));
l = this.F.mul(l, omega); l = this.F.mul(l, omega);
} }

@ -21,7 +21,7 @@
const BN128 = require("./bn128.js"); const BN128 = require("./bn128.js");
const PolField = require("./polfield.js"); const PolField = require("./polfield.js");
const ZqField = require("./zqfield.js"); const ZqField = require("ffjavascript").ZqField;
const bn128 = new BN128(); const bn128 = new BN128();
const PolF = new PolField(new ZqField(bn128.r)); const PolF = new PolField(new ZqField(bn128.r));
@ -90,7 +90,7 @@ module.exports = function genProof(vk_proof, witness) {
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( proof.pi_a, s )); proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( proof.pi_a, s ));
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( pib1, r )); proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( pib1, r ));
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( vk_proof.vk_delta_1, PolF.F.affine(PolF.F.neg(PolF.F.mul(r,s) )))); proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( vk_proof.vk_delta_1, PolF.F.neg(PolF.F.mul(r,s) )));
const publicSignals = witness.slice(1, vk_proof.nPublic+1); const publicSignals = witness.slice(1, vk_proof.nPublic+1);

@ -21,9 +21,10 @@
const BN128 = require("./bn128.js"); const BN128 = require("./bn128.js");
const PolField = require("./polfield.js"); const PolField = require("./polfield.js");
const ZqField = require("./zqfield.js"); const ZqField = require("ffjavascript").ZqField;
const createKeccakHash = require("keccak"); const createKeccakHash = require("keccak");
const bigInt = require("./bigint"); const utils = require("./utils");
const bn128 = new BN128(); const bn128 = new BN128();
const PolF = new PolField(new ZqField(bn128.r)); const PolF = new PolField(new ZqField(bn128.r));
@ -89,26 +90,25 @@ module.exports = function genProof(vk_proof, witness) {
proof.pi_b = G2.affine(proof.pi_b); proof.pi_b = G2.affine(proof.pi_b);
const buff = Buffer.concat([ const buff = Buffer.concat([
proof.pi_a[0].beInt2Buff(32), utils.beInt2Buff(proof.pi_a[0],32),
proof.pi_a[1].beInt2Buff(32), utils.beInt2Buff(proof.pi_a[1],32),
proof.pi_b[0][0].beInt2Buff(32), utils.beInt2Buff(proof.pi_b[0][0],32),
proof.pi_b[0][1].beInt2Buff(32), utils.beInt2Buff(proof.pi_b[0][1],32),
proof.pi_b[1][0].beInt2Buff(32), utils.beInt2Buff(proof.pi_b[1][0],32),
proof.pi_b[1][1].beInt2Buff(32) utils.beInt2Buff(proof.pi_b[1][1],32)
]); ]);
const h1buff = createKeccakHash("keccak256").update(buff).digest(); const h1buff = createKeccakHash("keccak256").update(buff).digest();
const h2buff = createKeccakHash("keccak256").update(h1buff).digest(); const h2buff = createKeccakHash("keccak256").update(h1buff).digest();
const h1 = bigInt.beBuff2int(h1buff); const h1 = utils.beBuff2int(h1buff);
const h2 = bigInt.beBuff2int(h2buff); const h2 = utils.beBuff2int(h2buff);
// const h1 = PolF.F.zero; // const h1 = PolF.F.zero;
// const h2 = PolF.F.zero; // const h2 = PolF.F.zero;
console.log(h1.toString()); // console.log(h1.toString());
console.log(h2.toString()); // console.log(h2.toString());
const h = calculateH(vk_proof, witness); const h = calculateH(vk_proof, witness);
@ -125,7 +125,7 @@ module.exports = function genProof(vk_proof, witness) {
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( proof.pi_a, s )); proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( proof.pi_a, s ));
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( pib1, r )); proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( pib1, r ));
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( G1.g, PolF.F.affine(PolF.F.neg(PolF.F.mul(r,s) )))); proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( G1.g, PolF.F.neg(PolF.F.mul(r,s) )));
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( piadelta, h2 )); proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( piadelta, h2 ));
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( pib1, h1 )); proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( pib1, h1 ));

@ -19,7 +19,7 @@
const BN128 = require("./bn128.js"); const BN128 = require("./bn128.js");
const PolField = require("./polfield.js"); const PolField = require("./polfield.js");
const ZqField = require("./zqfield.js"); const ZqField = require("ffjavascript").ZqField;
const bn128 = new BN128(); const bn128 = new BN128();
const PolF = new PolField(new ZqField(bn128.r)); const PolF = new PolField(new ZqField(bn128.r));
@ -204,7 +204,7 @@ function calculateH(vk_proof, witness, d1, d2, d3) {
H_S[m] = PolF.F.add(H_S[m], d1d2); H_S[m] = PolF.F.add(H_S[m], d1d2);
H_S[0] = PolF.F.sub(H_S[0], d1d2); H_S[0] = PolF.F.sub(H_S[0], d1d2);
H_S = PolF.reduce(PolF.affine(H_S)); H_S = PolF.reduce(H_S);
return H_S; return H_S;
} }

@ -71,7 +71,7 @@ class RatField {
]; ];
} }
inverse(a) { inv(a) {
return [a[1], a[0]]; return [a[1], a[0]];
} }

@ -19,11 +19,11 @@
/* Implementation of this paper: https://eprint.iacr.org/2016/260.pdf */ /* Implementation of this paper: https://eprint.iacr.org/2016/260.pdf */
const bigInt = require("./bigint.js"); const bigInt = require("big-integer");
const BN128 = require("./bn128.js"); const BN128 = require("./bn128.js");
const PolField = require("./polfield.js"); const PolField = require("./polfield.js");
const ZqField = require("./zqfield.js"); const ZqField = require("ffjavascript").ZqField;
const bn128 = new BN128(); const bn128 = new BN128();
const G1 = bn128.G1; const G1 = bn128.G1;
@ -126,15 +126,15 @@ function calculateEncriptedValuesAtT(setup, circuit) {
setup.vk_proof.B1 = new Array(circuit.nVars); setup.vk_proof.B1 = new Array(circuit.nVars);
setup.vk_proof.B2 = new Array(circuit.nVars); setup.vk_proof.B2 = new Array(circuit.nVars);
setup.vk_proof.C = new Array(circuit.nVars); setup.vk_proof.C = new Array(circuit.nVars);
setup.vk_verifier.IC = new Array(circuit.nPublic); setup.vk_verifier.IC = new Array(circuit.nPubInputs + circuit.nOutputs + 1);
setup.toxic.kalfa = F.random(); setup.toxic.kalfa = F.random();
setup.toxic.kbeta = F.random(); setup.toxic.kbeta = F.random();
setup.toxic.kgamma = F.random(); setup.toxic.kgamma = F.random();
setup.toxic.kdelta = F.random(); setup.toxic.kdelta = F.random();
let invDelta = F.inverse(setup.toxic.kdelta); let invDelta = F.inv(setup.toxic.kdelta);
let invGamma = F.inverse(setup.toxic.kgamma); let invGamma = F.inv(setup.toxic.kgamma);
setup.vk_proof.vk_alfa_1 = G1.affine(G1.mulScalar( G1.g, setup.toxic.kalfa)); setup.vk_proof.vk_alfa_1 = G1.affine(G1.mulScalar( G1.g, setup.toxic.kalfa));
setup.vk_proof.vk_beta_1 = G1.affine(G1.mulScalar( G1.g, setup.toxic.kbeta)); setup.vk_proof.vk_beta_1 = G1.affine(G1.mulScalar( G1.g, setup.toxic.kbeta));
@ -150,7 +150,7 @@ function calculateEncriptedValuesAtT(setup, circuit) {
setup.vk_verifier.vk_gamma_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kgamma)); setup.vk_verifier.vk_gamma_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kgamma));
setup.vk_verifier.vk_delta_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kdelta)); setup.vk_verifier.vk_delta_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kdelta));
setup.vk_verifier.vk_alfabeta_12 = bn128.F12.affine(bn128.pairing( setup.vk_verifier.vk_alfa_1 , setup.vk_verifier.vk_beta_2 )); setup.vk_verifier.vk_alfabeta_12 = bn128.pairing( setup.vk_verifier.vk_alfa_1 , setup.vk_verifier.vk_beta_2 );
for (let s=0; s<circuit.nVars; s++) { for (let s=0; s<circuit.nVars; s++) {

@ -19,11 +19,11 @@
/* Implementation of this paper: https://eprint.iacr.org/2016/260.pdf */ /* Implementation of this paper: https://eprint.iacr.org/2016/260.pdf */
const bigInt = require("./bigint.js"); const bigInt = require("big-integer");
const BN128 = require("./bn128.js"); const BN128 = require("./bn128.js");
const PolField = require("./polfield.js"); const PolField = require("./polfield.js");
const ZqField = require("./zqfield.js"); const ZqField = require("ffjavascript").ZqField;
const bn128 = new BN128(); const bn128 = new BN128();
const G1 = bn128.G1; const G1 = bn128.G1;
@ -127,7 +127,7 @@ function calculateEncriptedValuesAtT(setup, circuit) {
setup.vk_proof.B1 = new Array(circuit.nVars); setup.vk_proof.B1 = new Array(circuit.nVars);
setup.vk_proof.B2 = new Array(circuit.nVars); setup.vk_proof.B2 = new Array(circuit.nVars);
setup.vk_proof.C = new Array(circuit.nVars); setup.vk_proof.C = new Array(circuit.nVars);
setup.vk_verifier.IC = new Array(circuit.nPublic); setup.vk_verifier.IC = new Array(circuit.nPubInputs + circuit.nOutputs + 1);
setup.toxic.kalfa = F.random(); setup.toxic.kalfa = F.random();
setup.toxic.kbeta = F.random(); setup.toxic.kbeta = F.random();
@ -150,7 +150,7 @@ function calculateEncriptedValuesAtT(setup, circuit) {
setup.vk_verifier.vk_gamma_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kgamma)); setup.vk_verifier.vk_gamma_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kgamma));
setup.vk_verifier.vk_delta_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kdelta)); setup.vk_verifier.vk_delta_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kdelta));
setup.vk_verifier.vk_alfabeta_12 = bn128.F12.affine(bn128.pairing( setup.vk_verifier.vk_alfa_1 , setup.vk_verifier.vk_beta_2 )); setup.vk_verifier.vk_alfabeta_12 = bn128.pairing( setup.vk_verifier.vk_alfa_1 , setup.vk_verifier.vk_beta_2 );
for (let s=0; s<circuit.nVars; s++) { for (let s=0; s<circuit.nVars; s++) {

@ -17,11 +17,11 @@
snarkjs. If not, see <https://www.gnu.org/licenses/>. snarkjs. If not, see <https://www.gnu.org/licenses/>.
*/ */
const bigInt = require("./bigint.js"); const bigInt = require("big-integer");
const BN128 = require("./bn128.js"); const BN128 = require("./bn128.js");
const PolField = require("./polfield.js"); const PolField = require("./polfield.js");
const ZqField = require("./zqfield.js"); const ZqField = require("ffjavascript").ZqField;
const bn128 = new BN128(); const bn128 = new BN128();
const G1 = bn128.G1; const G1 = bn128.G1;
@ -128,7 +128,8 @@ function calculateEncriptedValuesAtT(setup, circuit) {
setup.vk_proof.Bp = new Array(circuit.nVars+1); setup.vk_proof.Bp = new Array(circuit.nVars+1);
setup.vk_proof.Cp = new Array(circuit.nVars+1); setup.vk_proof.Cp = new Array(circuit.nVars+1);
setup.vk_proof.Kp = new Array(circuit.nVars+3); setup.vk_proof.Kp = new Array(circuit.nVars+3);
setup.vk_verifier.IC = new Array(circuit.nPublic); setup.vk_verifier.IC = new Array(circuit.nPubInputs);
setup.vk_verifier.IC = new Array(circuit.nPubInputs + circuit.nOutputs + 1);
setup.toxic.ka = F.random(); setup.toxic.ka = F.random();
setup.toxic.kb = F.random(); setup.toxic.kb = F.random();
@ -177,7 +178,7 @@ function calculateEncriptedValuesAtT(setup, circuit) {
// K = G1 * (A+B+C) // K = G1 * (A+B+C)
const kt = F.affine(F.add(F.add(raat, rbbt), rcct)); const kt = F.add(F.add(raat, rbbt), rcct);
const K = G1.affine(G1.mulScalar( G1.g, kt)); const K = G1.affine(G1.mulScalar( G1.g, kt));
/* /*

@ -17,7 +17,7 @@
snarkjs. If not, see <https://www.gnu.org/licenses/>. snarkjs. If not, see <https://www.gnu.org/licenses/>.
*/ */
const bigInt = require("./bigint.js"); const bigInt = require("big-integer");
module.exports.stringifyBigInts = stringifyBigInts; module.exports.stringifyBigInts = stringifyBigInts;
module.exports.unstringifyBigInts = unstringifyBigInts; module.exports.unstringifyBigInts = unstringifyBigInts;

24
src/utils.js Normal file

@ -0,0 +1,24 @@
const bigInt = require("big-integer");
exports.beBuff2int = function(buff) {
let res = bigInt.zero;
for (let i=0; i<buff.length; i++) {
const n = bigInt(buff[buff.length - i - 1]);
res = res.add(n.shiftLeft(i*8));
}
return res;
};
exports.beInt2Buff = function(n, len) {
let r = n;
let o =len-1;
const buff = Buffer.alloc(len);
while ((r.gt(bigInt.zero))&&(o>=0)) {
let c = Number(r.and(bigInt("255")));
buff[o] = c;
o--;
r = r.shiftRight(8);
}
if (r.greater(bigInt.zero)) throw new Error("Number does not feed in buffer");
return buff;
};

@ -32,7 +32,7 @@ module.exports = function isValid(vk_verifier, proof, publicSignals) {
cpub = G1.add( cpub, G1.mulScalar( vk_verifier.IC[s+1], publicSignals[s])); cpub = G1.add( cpub, G1.mulScalar( vk_verifier.IC[s+1], publicSignals[s]));
} }
if (! bn128.F12.equals( if (! bn128.F12.eq(
bn128.pairing( proof.pi_a , proof.pi_b ), bn128.pairing( proof.pi_a , proof.pi_b ),
bn128.F12.mul( bn128.F12.mul(
vk_verifier.vk_alfabeta_12, vk_verifier.vk_alfabeta_12,

@ -22,7 +22,7 @@
const BN128 = require("./bn128.js"); const BN128 = require("./bn128.js");
const createKeccakHash = require("keccak"); const createKeccakHash = require("keccak");
const bigInt = require("./bigint"); const utils = require("./utils");
const bn128 = new BN128(); const bn128 = new BN128();
const G1 = bn128.G1; const G1 = bn128.G1;
@ -36,29 +36,29 @@ module.exports = function isValid(vk_verifier, proof, publicSignals) {
} }
const buff = Buffer.concat([ const buff = Buffer.concat([
proof.pi_a[0].beInt2Buff(32), utils.beInt2Buff(proof.pi_a[0], 32),
proof.pi_a[1].beInt2Buff(32), utils.beInt2Buff(proof.pi_a[1], 32),
proof.pi_b[0][0].beInt2Buff(32), utils.beInt2Buff(proof.pi_b[0][0], 32),
proof.pi_b[0][1].beInt2Buff(32), utils.beInt2Buff(proof.pi_b[0][1], 32),
proof.pi_b[1][0].beInt2Buff(32), utils.beInt2Buff(proof.pi_b[1][0], 32),
proof.pi_b[1][1].beInt2Buff(32) utils.beInt2Buff(proof.pi_b[1][1], 32),
]); ]);
const h1buff = createKeccakHash("keccak256").update(buff).digest(); const h1buff = createKeccakHash("keccak256").update(buff).digest();
const h2buff = createKeccakHash("keccak256").update(h1buff).digest(); const h2buff = createKeccakHash("keccak256").update(h1buff).digest();
const h1 = bigInt.beBuff2int(h1buff); const h1 = utils.beBuff2int(h1buff);
const h2 = bigInt.beBuff2int(h2buff); const h2 = utils.beBuff2int(h2buff);
// const h1 = bigInt.zero; // const h1 = bigInt.zero;
// const h2 = bigInt.zero; // const h2 = bigInt.zero;
console.log(h1.toString()); // console.log(h1.toString());
console.log(h2.toString()); // console.log(h2.toString());
if (! bn128.F12.equals( if (! bn128.F12.eq(
bn128.pairing( bn128.pairing(
G1.add(proof.pi_a, G1.mulScalar(G1.g, h1)), G1.add(proof.pi_a, G1.mulScalar(G1.g, h1)),
G2.add(proof.pi_b, G2.mulScalar(vk_verifier.vk_delta_2, h2)) G2.add(proof.pi_b, G2.mulScalar(vk_verifier.vk_delta_2, h2))

@ -32,22 +32,22 @@ module.exports = function isValid(vk_verifier, proof, publicSignals) {
full_pi_a = G1.add( full_pi_a, proof.pi_a); full_pi_a = G1.add( full_pi_a, proof.pi_a);
if (! bn128.F12.equals( if (! bn128.F12.eq(
bn128.pairing( proof.pi_a , vk_verifier.vk_a ), bn128.pairing( proof.pi_a , vk_verifier.vk_a ),
bn128.pairing( proof.pi_ap , G2.g ))) bn128.pairing( proof.pi_ap , G2.g )))
return false; return false;
if (! bn128.F12.equals( if (! bn128.F12.eq(
bn128.pairing( vk_verifier.vk_b, proof.pi_b ), bn128.pairing( vk_verifier.vk_b, proof.pi_b ),
bn128.pairing( proof.pi_bp , G2.g ))) bn128.pairing( proof.pi_bp , G2.g )))
return false; return false;
if (! bn128.F12.equals( if (! bn128.F12.eq(
bn128.pairing( proof.pi_c , vk_verifier.vk_c ), bn128.pairing( proof.pi_c , vk_verifier.vk_c ),
bn128.pairing( proof.pi_cp , G2.g ))) bn128.pairing( proof.pi_cp , G2.g )))
return false; return false;
if (! bn128.F12.equals( if (! bn128.F12.eq(
bn128.F12.mul( bn128.F12.mul(
bn128.pairing( G1.add(full_pi_a, proof.pi_c) , vk_verifier.vk_gb_2 ), bn128.pairing( G1.add(full_pi_a, proof.pi_c) , vk_verifier.vk_gb_2 ),
bn128.pairing( vk_verifier.vk_gb_1 , proof.pi_b ) bn128.pairing( vk_verifier.vk_gb_1 , proof.pi_b )
@ -55,7 +55,7 @@ module.exports = function isValid(vk_verifier, proof, publicSignals) {
bn128.pairing( proof.pi_kp , vk_verifier.vk_g ))) bn128.pairing( proof.pi_kp , vk_verifier.vk_g )))
return false; return false;
if (! bn128.F12.equals( if (! bn128.F12.eq(
bn128.pairing( full_pi_a , proof.pi_b ), bn128.pairing( full_pi_a , proof.pi_b ),
bn128.F12.mul( bn128.F12.mul(
bn128.pairing( proof.pi_h , vk_verifier.vk_z ), bn128.pairing( proof.pi_h , vk_verifier.vk_z ),

@ -17,7 +17,7 @@
snarkjs. If not, see <https://www.gnu.org/licenses/>. snarkjs. If not, see <https://www.gnu.org/licenses/>.
*/ */
const bigInt = require("./bigint"); const bigInt = require("big-integer");
const fUtils = require("./futils.js"); const fUtils = require("./futils.js");
function getRandomByte() { function getRandomByte() {

@ -19,9 +19,9 @@
const chai = require("chai"); const chai = require("chai");
const bigInt = require("../src/bigint.js"); const bigInt = require("big-integer");
const BN128 = require("../src/bn128.js"); const BN128 = require("../src/bn128.js");
const F1Field = require("../src/zqfield.js"); const F1Field = require("ffjavascript").ZqField;
const assert = chai.assert; const assert = chai.assert;
@ -29,7 +29,7 @@ const assert = chai.assert;
describe("F1 testing", () => { describe("F1 testing", () => {
it("Should compute euclidean", () => { it("Should compute euclidean", () => {
const F = new F1Field(bigInt(7)); const F = new F1Field(bigInt(7));
const res = F.inverse(bigInt(4)); const res = F.inv(bigInt(4));
assert(F.equals(res, bigInt(2))); assert(F.equals(res, bigInt(2)));
}); });

@ -23,7 +23,7 @@ const path = require("path");
const Circuit = require("../src/circuit.js"); const Circuit = require("../src/circuit.js");
const BN128 = require("../src/bn128.js"); const BN128 = require("../src/bn128.js");
const F1Field = require("../src/zqfield.js"); const F1Field = require("ffjavascript").ZqField;
const assert = chai.assert; const assert = chai.assert;

@ -0,0 +1,16 @@
template Multiplier(n) {
signal private input a;
signal private input b;
signal output c;
signal int[n];
int[0] <== a*a + b;
for (var i=1; i<n; i++) {
int[i] <== int[i-1]*int[i-1] + b;
}
c <== int[n-1];
}
component main = Multiplier(1000);

BIN
test/circuit/circuit.r1cs Normal file

Binary file not shown.

BIN
test/circuit/circuit.wasm Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

@ -19,9 +19,9 @@
const chai = require("chai"); const chai = require("chai");
const bigInt = require("../src/bigint.js"); const bigInt = require("big-integer");
const PolField = require("../src/polfield.js"); const PolField = require("../src/polfield.js");
const ZqField = require("../src/zqfield"); const ZqField = require("ffjavascript").ZqField;
const assert = chai.assert; const assert = chai.assert;

@ -19,8 +19,8 @@
const chai = require("chai"); const chai = require("chai");
const bigInt = require("../src/bigint.js"); const bigInt = require("big-integer");
const ZqField = require("../src/zqfield.js"); const ZqField = require("ffjavascript").ZqField;
const RatField = require("../src/ratfield.js"); const RatField = require("../src/ratfield.js");
const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");

@ -17,16 +17,47 @@
zksnark JavaScript library. If not, see <https://www.gnu.org/licenses/>. zksnark JavaScript library. If not, see <https://www.gnu.org/licenses/>.
*/ */
const chai = require("chai"); const chai = require("chai");
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const bigInt = require("../src/bigint.js"); const loadR1cs = require("r1csfile").load;
const zkSnark = require("../index.js");
const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder;
const assert = chai.assert;
describe("zkSnark Groth", () => {
it("Load a circuit, create trusted setup, create a proof and validate it", async () => {
const cir = await loadR1cs(path.join(__dirname, "circuit", "circuit.r1cs"), true);
const setup = zkSnark.original.setup(cir);
const wasm = await fs.promises.readFile(path.join(__dirname, "circuit", "circuit.wasm"));
const wc = await WitnessCalculatorBuilder(wasm, {sanityCheck: true});
const witness = await wc.calculateWitness({"a": "33", "b": "34"});
const {proof, publicSignals} = zkSnark.original.genProof(setup.vk_proof, witness);
assert( zkSnark.original.isValid(setup.vk_verifier, proof, publicSignals));
}).timeout(10000000);
});
/*
const chai = require("chai");
const fs = require("fs");
const path = require("path");
const bigInt = require("big-integer");
const Circuit = require("../src/circuit.js"); const Circuit = require("../src/circuit.js");
const zkSnark = require("../index.js").original; const zkSnark = require("../index.js").original;
const BN128 = require("../src/bn128.js"); const BN128 = require("../src/bn128.js");
const PolField = require("../src/polfield.js"); const PolField = require("../src/polfield.js");
const ZqField = require("../src/zqfield.js"); const ZqField = require("ffjavascript").ZqField;
const {stringifyBigInts, unstringifyBigInts} = require("../src/stringifybigint.js"); const {stringifyBigInts, unstringifyBigInts} = require("../src/stringifybigint.js");
@ -194,3 +225,5 @@ describe("zkSnark original", () => {
* / * /
}); });
*/

@ -20,25 +20,27 @@
const chai = require("chai"); const chai = require("chai");
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const loadR1cs = require("r1csfile").load;
const Circuit = require("../src/circuit.js"); const zkSnark = require("../index.js");
const zkSnark = require("../index.js").groth; const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder;
const assert = chai.assert; const assert = chai.assert;
describe("zkSnark Groth", () => { describe("zkSnark Groth", () => {
it("Load a circuit, create trusted setup, create a proof and validate it", () => { it("Load a circuit, create trusted setup, create a proof and validate it", async () => {
const cir = await loadR1cs(path.join(__dirname, "circuit", "circuit.r1cs"), true);
const setup = zkSnark.groth.setup(cir);
const cirDef = JSON.parse(fs.readFileSync(path.join(__dirname, "circuit", "sum.json"), "utf8")); const wasm = await fs.promises.readFile(path.join(__dirname, "circuit", "circuit.wasm"));
const cir = new Circuit(cirDef);
const setup = zkSnark.setup(cir); const wc = await WitnessCalculatorBuilder(wasm, {sanityCheck: true});
const witness = cir.calculateWitness({"a": "33", "b": "34"}); const witness = await wc.calculateWitness({"a": "33", "b": "34"});
const {proof, publicSignals} = zkSnark.genProof(setup.vk_proof, witness); const {proof, publicSignals} = zkSnark.groth.genProof(setup.vk_proof, witness);
assert( zkSnark.isValid(setup.vk_verifier, proof, publicSignals)); assert( zkSnark.groth.isValid(setup.vk_verifier, proof, publicSignals));
}).timeout(10000000); }).timeout(10000000);
}); });

@ -17,28 +17,32 @@
zksnark JavaScript library. If not, see <https://www.gnu.org/licenses/>. zksnark JavaScript library. If not, see <https://www.gnu.org/licenses/>.
*/ */
const chai = require("chai"); const chai = require("chai");
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const loadR1cs = require("r1csfile").load;
const Circuit = require("../src/circuit.js"); const zkSnark = require("../index.js");
const zkSnark = require("../index.js").kimleeoh; const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder;
const assert = chai.assert; const assert = chai.assert;
describe("zkSnark KimLeeOh", () => { describe("zkSnark kimleeoh", () => {
it("Load a circuit, create trusted setup, create a proof and validate it", () => { it("Load a circuit, create trusted setup, create a proof and validate it", async () => {
const cir = await loadR1cs(path.join(__dirname, "circuit", "circuit.r1cs"), true);
const setup = zkSnark.kimleeoh.setup(cir);
const cirDef = JSON.parse(fs.readFileSync(path.join(__dirname, "circuit", "sum.json"), "utf8")); const wasm = await fs.promises.readFile(path.join(__dirname, "circuit", "circuit.wasm"));
const cir = new Circuit(cirDef);
const setup = zkSnark.setup(cir); const wc = await WitnessCalculatorBuilder(wasm, {sanityCheck: true});
const witness = cir.calculateWitness({"a": "33", "b": "34"}); const witness = await wc.calculateWitness({"a": "33", "b": "34"});
const {proof, publicSignals} = zkSnark.genProof(setup.vk_proof, witness); const {proof, publicSignals} = zkSnark.kimleeoh.genProof(setup.vk_proof, witness);
assert( zkSnark.isValid(setup.vk_verifier, proof, publicSignals)); assert( zkSnark.kimleeoh.isValid(setup.vk_verifier, proof, publicSignals));
}).timeout(10000000); }).timeout(10000000);
}); });