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 h2 = PolF.F.zero;
// const h1 = PolF.F.zero; // console.log(h1.toString());
// const h2 = PolF.F.zero; // console.log(h2.toString());
console.log(h1.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)));
}); });

@ -3,17 +3,17 @@
This file is part of zksnark JavaScript library. This file is part of zksnark JavaScript library.
zksnark JavaScript library is a free software: you can redistribute it and/or zksnark JavaScript library is a free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as published by the modify it under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your option) Free Software Foundation, either version 3 of the License, or (at your option)
any later version. any later version.
zksnark JavaScript library is distributed in the hope that it will be useful, zksnark JavaScript library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
zksnark JavaScript library. If not, see <https://www.gnu.org/licenses/>. zksnark JavaScript library. If not, see <https://www.gnu.org/licenses/>.
*/ */
@ -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;

@ -3,24 +3,24 @@
This file is part of zksnark JavaScript library. This file is part of zksnark JavaScript library.
zksnark JavaScript library is a free software: you can redistribute it and/or zksnark JavaScript library is a free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as published by the modify it under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your option) Free Software Foundation, either version 3 of the License, or (at your option)
any later version. any later version.
zksnark JavaScript library is distributed in the hope that it will be useful, zksnark JavaScript library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
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 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");
@ -65,12 +96,12 @@ describe("zkSnark original", () => {
const setup = {}; const setup = {};
setup.vk_proof = unstringifyBigInts(JSON.parse(fs.readFileSync("vk_proof.json", "utf8"))); setup.vk_proof = unstringifyBigInts(JSON.parse(fs.readFileSync("vk_proof.json", "utf8")));
setup.vk_verifier = unstringifyBigInts(JSON.parse(fs.readFileSync("vk_verifier.json", "utf8"))); setup.vk_verifier = unstringifyBigInts(JSON.parse(fs.readFileSync("vk_verifier.json", "utf8")));
*/ * /
const witness = cir.calculateWitness({"a": "33", "b": "34"}); const witness = cir.calculateWitness({"a": "33", "b": "34"});
const {proof, publicSignals} = zkSnark.genProof(setup.vk_proof, witness); const {proof, publicSignals} = zkSnark.genProof(setup.vk_proof, witness);
/* / *
const polA = new Array(cir.nVars); const polA = new Array(cir.nVars);
const polB = new Array(cir.nVars); const polB = new Array(cir.nVars);
const polC = new Array(cir.nVars); const polC = new Array(cir.nVars);
@ -161,10 +192,10 @@ describe("zkSnark original", () => {
assert(G2.equals(gB, proof.pi_b)); assert(G2.equals(gB, proof.pi_b));
assert(G1.equals(gC, proof.pi_c)); assert(G1.equals(gC, proof.pi_c));
// assert(G1.equals(gA, proof.pi_a)); // assert(G1.equals(gA, proof.pi_a));
*/ * /
assert( zkSnark.isValid(setup.vk_verifier, proof, publicSignals)); assert( zkSnark.isValid(setup.vk_verifier, proof, publicSignals));
}).timeout(10000000); }).timeout(10000000);
/* / *
it("validate sha256_2", () => { it("validate sha256_2", () => {
const cirDef = JSON.parse(fs.readFileSync(path.join(__dirname, "circuit", "sha256_2.json"), "utf8")); const cirDef = JSON.parse(fs.readFileSync(path.join(__dirname, "circuit", "sha256_2.json"), "utf8"));
@ -191,6 +222,8 @@ describe("zkSnark original", () => {
console.log("Start verifiying: "+ Date().toString()); console.log("Start verifiying: "+ Date().toString());
assert( zkSnark.isValid(setup.vk_verifier, proof, publicSignals)); assert( zkSnark.isValid(setup.vk_verifier, proof, publicSignals));
}).timeout(10000000); }).timeout(10000000);
*/ * /
}); });
*/

@ -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);
}); });