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");
const setup = zkSnark[protocol].setup(cir);
fs.writeFileSync(provingKeyName, JSON.stringify(stringifyBigInts(setup.vk_proof), null, 1), "utf-8");
fs.writeFileSync(verificationKeyName, JSON.stringify(stringifyBigInts(setup.vk_verifier), null, 1), "utf-8");
process.exit(0);
await fs.promises.writeFile(provingKeyName, JSON.stringify(stringifyBigInts(setup.vk_proof), null, 1), "utf-8");
await fs.promises.writeFile(verificationKeyName, JSON.stringify(stringifyBigInts(setup.vk_verifier), null, 1), "utf-8");
} else if (argv._[0].toUpperCase() == "CALCULATEWITNESS") {
const wasm = await fs.promises.readFile(wasmName);
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");
const {proof, publicSignals} = zkSnark[protocol].genProof(provingKey, witness);
fs.writeFileSync(proofName, JSON.stringify(stringifyBigInts(proof), null, 1), "utf-8");
fs.writeFileSync(publicName, JSON.stringify(stringifyBigInts(publicSignals), null, 1), "utf-8");
process.exit(0);
await fs.promises.writeFile(proofName, JSON.stringify(stringifyBigInts(proof), null, 1), "utf-8");
await fs.promises.writeFile(publicName, JSON.stringify(stringifyBigInts(publicSignals), null, 1), "utf-8");
} else if (argv._[0].toUpperCase() == "VERIFY") {
const public = unstringifyBigInts(JSON.parse(fs.readFileSync(publicName, "utf8")));
const verificationKey = unstringifyBigInts(JSON.parse(fs.readFileSync(verificationKeyName, "utf8")));

@ -17,7 +17,6 @@
snarkjs. If not, see <https://www.gnu.org/licenses/>.
*/
exports.Circuit = require("./src/circuit.js");
exports.original = {
setup: require("./src/setup_original.js"),
genProof: require("./src/prover_original.js"),
@ -33,8 +32,6 @@ exports.kimleeoh = {
genProof: require("./src/prover_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.unstringifyBigInts = require("./src/stringifybigint.js").unstringifyBigInts;

8
package-lock.json generated

@ -595,6 +595,14 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"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": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",

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

@ -17,9 +17,9 @@
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 F3Field = require("./f3field.js");
const GCurve = require("./gcurve.js");
@ -81,14 +81,14 @@ class BN128 {
this.loop_count_bits = []; // Constant
while (!lc.isZero()) {
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.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.twist_mul_by_q_X =
@ -163,12 +163,12 @@ class BN128 {
}
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");
}
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");
}

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

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

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

@ -92,7 +92,7 @@ class F3Field {
bB)]; // (a+c)*(A+C)-aA+bB-cC)
}
inverse(a) {
inv(a) {
const t0 = this.F.square(a[0]); // t0 = a^2 ;
const t1 = this.F.square(a[1]); // t1 = b^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 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 =
this.F.inverse(
this.F.inv(
this.F.add(
this.F.mul(a[0], c0),
this._mulByNonResidue(
@ -122,7 +122,7 @@ class F3Field {
}
div(a, b) {
return this.mul(a, this.inverse(b));
return this.mul(a, this.inv(b));
}
square(a) {
@ -152,8 +152,8 @@ class F3Field {
return this.F.isZero(a[0]) && this.F.isZero(a[1]) && this.F.isZero(a[2]);
}
equals(a, b) {
return this.F.equals(a[0], b[0]) && this.F.equals(a[1], b[1]) && this.F.equals(a[2], b[2]);
eq(a, b) {
return this.F.eq(a[0], b[0]) && this.F.eq(a[1], b[1]) && this.F.eq(a[2], b[2]);
}
affine(a) {

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

@ -23,21 +23,17 @@ class GCurve {
constructor(F, g) {
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;
this.zero = [this.F.zero, this.F.one, this.F.zero];
}
isZero(p) {
return this.F.isZero(p[2]);
}
add(p1, p2) {
const F = this.F;
if (this.isZero(p1)) return p2;
if (this.isZero(p2)) return p1;
if (this.eq(p1, this.zero)) return p2;
if (this.eq(p2, this.zero)) return p1;
const res = new Array(3);
@ -53,7 +49,7 @@ class GCurve {
const S1 = F.mul( p1[1] , Z2_cubed); // S1 = Y1 * Z2 * Z2Z2
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);
}
@ -102,7 +98,7 @@ class GCurve {
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 B = F.square( p[1] ); // B = Y1^2
@ -142,27 +138,27 @@ class GCurve {
affine(p) {
const F = this.F;
if (this.isZero(p)) {
if (this.eq(p, this.zero)) {
return this.zero;
} else {
const Z_inv = F.inverse(p[2]);
const Z_inv = F.inv(p[2]);
const Z2_inv = F.square(Z_inv);
const Z3_inv = F.mul(Z2_inv, Z_inv);
const res = new Array(3);
res[0] = F.affine( F.mul(p[0],Z2_inv));
res[1] = F.affine( F.mul(p[1],Z3_inv));
res[0] = F.mul(p[0],Z2_inv);
res[1] = F.mul(p[1],Z3_inv);
res[2] = F.one;
return res;
}
}
equals(p1, p2) {
eq(p1, p2) {
const F = this.F;
if (this.isZero(p1)) return this.isZero(p2);
if (this.isZero(p2)) return this.isZero(p1);
if (this.F.eq(p1[2], this.F.zero)) return this.F.eq(p2[2], this.F.zero);
if (this.F.eq(p2[2], this.F.zero)) return false;
const Z1Z1 = F.square( p1[2] );
const Z2Z2 = F.square( p2[2] );
@ -176,7 +172,7 @@ class GCurve {
const S1 = F.mul( p1[1] , Z2_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) {

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

@ -21,7 +21,7 @@
const BN128 = require("./bn128.js");
const PolField = require("./polfield.js");
const ZqField = require("./zqfield.js");
const ZqField = require("ffjavascript").ZqField;
const bn128 = new BN128();
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( 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);

@ -21,9 +21,10 @@
const BN128 = require("./bn128.js");
const PolField = require("./polfield.js");
const ZqField = require("./zqfield.js");
const ZqField = require("ffjavascript").ZqField;
const createKeccakHash = require("keccak");
const bigInt = require("./bigint");
const utils = require("./utils");
const bn128 = new BN128();
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);
const buff = Buffer.concat([
proof.pi_a[0].beInt2Buff(32),
proof.pi_a[1].beInt2Buff(32),
proof.pi_b[0][0].beInt2Buff(32),
proof.pi_b[0][1].beInt2Buff(32),
proof.pi_b[1][0].beInt2Buff(32),
proof.pi_b[1][1].beInt2Buff(32)
utils.beInt2Buff(proof.pi_a[0],32),
utils.beInt2Buff(proof.pi_a[1],32),
utils.beInt2Buff(proof.pi_b[0][0],32),
utils.beInt2Buff(proof.pi_b[0][1],32),
utils.beInt2Buff(proof.pi_b[1][0],32),
utils.beInt2Buff(proof.pi_b[1][1],32)
]);
const h1buff = createKeccakHash("keccak256").update(buff).digest();
const h2buff = createKeccakHash("keccak256").update(h1buff).digest();
const h1 = bigInt.beBuff2int(h1buff);
const h2 = bigInt.beBuff2int(h2buff);
const h1 = utils.beBuff2int(h1buff);
const h2 = utils.beBuff2int(h2buff);
// const h1 = PolF.F.zero;
// const h2 = PolF.F.zero;
// const h1 = PolF.F.zero;
// const h2 = PolF.F.zero;
console.log(h1.toString());
console.log(h2.toString());
// console.log(h1.toString());
// console.log(h2.toString());
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( 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( pib1, h1 ));

@ -19,7 +19,7 @@
const BN128 = require("./bn128.js");
const PolField = require("./polfield.js");
const ZqField = require("./zqfield.js");
const ZqField = require("ffjavascript").ZqField;
const bn128 = new BN128();
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[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;
}

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

@ -19,11 +19,11 @@
/* 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 PolField = require("./polfield.js");
const ZqField = require("./zqfield.js");
const ZqField = require("ffjavascript").ZqField;
const bn128 = new BN128();
const G1 = bn128.G1;
@ -126,15 +126,15 @@ function calculateEncriptedValuesAtT(setup, circuit) {
setup.vk_proof.B1 = new Array(circuit.nVars);
setup.vk_proof.B2 = 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.kbeta = F.random();
setup.toxic.kgamma = F.random();
setup.toxic.kdelta = F.random();
let invDelta = F.inverse(setup.toxic.kdelta);
let invGamma = F.inverse(setup.toxic.kgamma);
let invDelta = F.inv(setup.toxic.kdelta);
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_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_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++) {

@ -19,11 +19,11 @@
/* 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 PolField = require("./polfield.js");
const ZqField = require("./zqfield.js");
const ZqField = require("ffjavascript").ZqField;
const bn128 = new BN128();
const G1 = bn128.G1;
@ -127,7 +127,7 @@ function calculateEncriptedValuesAtT(setup, circuit) {
setup.vk_proof.B1 = new Array(circuit.nVars);
setup.vk_proof.B2 = 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.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_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++) {

@ -17,11 +17,11 @@
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 PolField = require("./polfield.js");
const ZqField = require("./zqfield.js");
const ZqField = require("ffjavascript").ZqField;
const bn128 = new BN128();
const G1 = bn128.G1;
@ -128,7 +128,8 @@ function calculateEncriptedValuesAtT(setup, circuit) {
setup.vk_proof.Bp = 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_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.kb = F.random();
@ -177,7 +178,7 @@ function calculateEncriptedValuesAtT(setup, circuit) {
// 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));
/*

@ -17,7 +17,7 @@
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.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]));
}
if (! bn128.F12.equals(
if (! bn128.F12.eq(
bn128.pairing( proof.pi_a , proof.pi_b ),
bn128.F12.mul(
vk_verifier.vk_alfabeta_12,

@ -22,7 +22,7 @@
const BN128 = require("./bn128.js");
const createKeccakHash = require("keccak");
const bigInt = require("./bigint");
const utils = require("./utils");
const bn128 = new BN128();
const G1 = bn128.G1;
@ -36,29 +36,29 @@ module.exports = function isValid(vk_verifier, proof, publicSignals) {
}
const buff = Buffer.concat([
proof.pi_a[0].beInt2Buff(32),
proof.pi_a[1].beInt2Buff(32),
proof.pi_b[0][0].beInt2Buff(32),
proof.pi_b[0][1].beInt2Buff(32),
proof.pi_b[1][0].beInt2Buff(32),
proof.pi_b[1][1].beInt2Buff(32)
utils.beInt2Buff(proof.pi_a[0], 32),
utils.beInt2Buff(proof.pi_a[1], 32),
utils.beInt2Buff(proof.pi_b[0][0], 32),
utils.beInt2Buff(proof.pi_b[0][1], 32),
utils.beInt2Buff(proof.pi_b[1][0], 32),
utils.beInt2Buff(proof.pi_b[1][1], 32),
]);
const h1buff = createKeccakHash("keccak256").update(buff).digest();
const h2buff = createKeccakHash("keccak256").update(h1buff).digest();
const h1 = bigInt.beBuff2int(h1buff);
const h2 = bigInt.beBuff2int(h2buff);
const h1 = utils.beBuff2int(h1buff);
const h2 = utils.beBuff2int(h2buff);
// const h1 = bigInt.zero;
// const h2 = bigInt.zero;
// const h1 = bigInt.zero;
// const h2 = bigInt.zero;
console.log(h1.toString());
console.log(h2.toString());
// console.log(h1.toString());
// console.log(h2.toString());
if (! bn128.F12.equals(
if (! bn128.F12.eq(
bn128.pairing(
G1.add(proof.pi_a, G1.mulScalar(G1.g, h1)),
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);
if (! bn128.F12.equals(
if (! bn128.F12.eq(
bn128.pairing( proof.pi_a , vk_verifier.vk_a ),
bn128.pairing( proof.pi_ap , G2.g )))
return false;
if (! bn128.F12.equals(
if (! bn128.F12.eq(
bn128.pairing( vk_verifier.vk_b, proof.pi_b ),
bn128.pairing( proof.pi_bp , G2.g )))
return false;
if (! bn128.F12.equals(
if (! bn128.F12.eq(
bn128.pairing( proof.pi_c , vk_verifier.vk_c ),
bn128.pairing( proof.pi_cp , G2.g )))
return false;
if (! bn128.F12.equals(
if (! bn128.F12.eq(
bn128.F12.mul(
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 )
@ -55,7 +55,7 @@ module.exports = function isValid(vk_verifier, proof, publicSignals) {
bn128.pairing( proof.pi_kp , vk_verifier.vk_g )))
return false;
if (! bn128.F12.equals(
if (! bn128.F12.eq(
bn128.pairing( full_pi_a , proof.pi_b ),
bn128.F12.mul(
bn128.pairing( proof.pi_h , vk_verifier.vk_z ),

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

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

@ -3,17 +3,17 @@
This file is part of zksnark JavaScript library.
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
Free Software Foundation, either version 3 of the License, or (at your option)
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
Free Software Foundation, either version 3 of the License, or (at your option)
any later version.
zksnark JavaScript library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
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/>.
*/
@ -23,7 +23,7 @@ const path = require("path");
const Circuit = require("../src/circuit.js");
const BN128 = require("../src/bn128.js");
const F1Field = require("../src/zqfield.js");
const F1Field = require("ffjavascript").ZqField;
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 bigInt = require("../src/bigint.js");
const bigInt = require("big-integer");
const PolField = require("../src/polfield.js");
const ZqField = require("../src/zqfield");
const ZqField = require("ffjavascript").ZqField;
const assert = chai.assert;

@ -3,24 +3,24 @@
This file is part of zksnark JavaScript library.
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
Free Software Foundation, either version 3 of the License, or (at your option)
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
Free Software Foundation, either version 3 of the License, or (at your option)
any later version.
zksnark JavaScript library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
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/>.
*/
const chai = require("chai");
const bigInt = require("../src/bigint.js");
const ZqField = require("../src/zqfield.js");
const bigInt = require("big-integer");
const ZqField = require("ffjavascript").ZqField;
const RatField = require("../src/ratfield.js");
const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");

@ -17,16 +17,47 @@
zksnark JavaScript library. If not, see <https://www.gnu.org/licenses/>.
*/
const chai = require("chai");
const fs = require("fs");
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 zkSnark = require("../index.js").original;
const BN128 = require("../src/bn128.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");
@ -65,12 +96,12 @@ describe("zkSnark original", () => {
const setup = {};
setup.vk_proof = unstringifyBigInts(JSON.parse(fs.readFileSync("vk_proof.json", "utf8")));
setup.vk_verifier = unstringifyBigInts(JSON.parse(fs.readFileSync("vk_verifier.json", "utf8")));
*/
* /
const witness = cir.calculateWitness({"a": "33", "b": "34"});
const {proof, publicSignals} = zkSnark.genProof(setup.vk_proof, witness);
/*
/ *
const polA = new Array(cir.nVars);
const polB = 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(G1.equals(gC, proof.pi_c));
// assert(G1.equals(gA, proof.pi_a));
*/
* /
assert( zkSnark.isValid(setup.vk_verifier, proof, publicSignals));
}).timeout(10000000);
/*
/ *
it("validate sha256_2", () => {
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());
assert( zkSnark.isValid(setup.vk_verifier, proof, publicSignals));
}).timeout(10000000);
*/
* /
});
*/

@ -20,25 +20,27 @@
const chai = require("chai");
const fs = require("fs");
const path = require("path");
const loadR1cs = require("r1csfile").load;
const Circuit = require("../src/circuit.js");
const zkSnark = require("../index.js").groth;
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", () => {
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 cir = new Circuit(cirDef);
const wasm = await fs.promises.readFile(path.join(__dirname, "circuit", "circuit.wasm"));
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);
});

@ -17,28 +17,32 @@
zksnark JavaScript library. If not, see <https://www.gnu.org/licenses/>.
*/
const chai = require("chai");
const fs = require("fs");
const path = require("path");
const loadR1cs = require("r1csfile").load;
const Circuit = require("../src/circuit.js");
const zkSnark = require("../index.js").kimleeoh;
const zkSnark = require("../index.js");
const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder;
const assert = chai.assert;
describe("zkSnark KimLeeOh", () => {
it("Load a circuit, create trusted setup, create a proof and validate it", () => {
describe("zkSnark kimleeoh", () => {
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 cir = new Circuit(cirDef);
const wasm = await fs.promises.readFile(path.join(__dirname, "circuit", "circuit.wasm"));
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);
});