Use native big int

This commit is contained in:
Jordi Baylina 2020-04-18 20:21:16 +02:00
parent 0d57168f30
commit 7b099d2843
No known key found for this signature in database
GPG Key ID: 7480C80C1BE43112
12 changed files with 52 additions and 114 deletions

13
cli.js
View File

@ -25,7 +25,7 @@ const fs = require("fs");
const path = require("path");
const zkSnark = require("./index.js");
const {stringifyBigInts, unstringifyBigInts} = require("./src/utils.js");
const {stringifyBigInts, unstringifyBigInts} = require("ffjavascript").utils;
const loadR1cs = require("r1csfile").load;
const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder;
@ -117,6 +117,11 @@ calculate witness command
--s or --sanitycheck
-s or --sym <symFile>
Filename of the debuging symbols file generated by circom.
Default: circuit.sym
generate a proof command
========================
@ -148,6 +153,10 @@ generate a proof command
Default: public.json
--verbose
Print verbose to screen
verify command
==============
@ -365,7 +374,7 @@ async function run() {
const protocol = provingKey.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, argv.verbose);
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");

View File

@ -33,6 +33,3 @@ exports.kimleeoh = {
isValid: require("./src/verifier_kimleeoh.js")
};
exports.stringifyBigInts = require("./src/utils.js").stringifyBigInts;
exports.unstringifyBigInts = require("./src/utils.js").unstringifyBigInts;

22
package-lock.json generated
View File

@ -232,11 +232,11 @@
}
},
"circom_runtime": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.0.3.tgz",
"integrity": "sha512-z4ypbs9cTQn7+2FHZNTnccMj6kQCcKT2agYqCrm2kdLBJh9LDoxU1JVu5mSnVuOtgc7BclQ7r0xclG0zP2rxhw==",
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.0.4.tgz",
"integrity": "sha512-9QdHo44g6tn3BF11RnlGzgYPByJOBKwmL9iBGHk/OsussOEoli214ooLYNKivn0i2j39bqkwahlU1FpMESQ7lw==",
"requires": {
"big-integer": "^1.6.48",
"ffjavascript": "0.1.0",
"fnv-plus": "^1.3.1"
}
},
@ -596,9 +596,9 @@
"dev": true
},
"ffjavascript": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.0.5.tgz",
"integrity": "sha512-7je6PydOWLDUj3vU8JeCUgeezg4yrG/6qjlukQNuPHeeavnM4REcrN9LA2+xtqIMIPdx/wdUkPMQpixsz+CdIw==",
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.1.0.tgz",
"integrity": "sha512-dmKlUasSfvUcxBm8nCSKl2x7EFJsXA7OVP8XLFA03T2+6mAc3IiVLC2ambEVOcMOhyhl0vJfVZjM9f9d38D1rw==",
"requires": {
"big-integer": "^1.6.48"
}
@ -1571,11 +1571,11 @@
"dev": true
},
"r1csfile": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.3.tgz",
"integrity": "sha512-TNrodnbHw5yAMv2gj0Ezf22XS3q8zGEjdPHZLBmJauIPFxm6QmyzxlB92yZ5WNkjEtJiS7p1hvkO9/RsJXRDjw==",
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.4.tgz",
"integrity": "sha512-1Y/zzzEjQVTR/gPlduRaKi2K+yU+UxqtsS+obDLEEb4WAzwCkKGybRfp037CUW5OApeleS1WdGmtKv9K9FPhsA==",
"requires": {
"big-integer": "^1.6.48"
"ffjavascript": "0.1.0"
}
},
"readdirp": {

View File

@ -28,13 +28,12 @@
"url": "https://github.com/iden3/snarkjs.git"
},
"dependencies": {
"big-integer": "^1.6.43",
"chai": "^4.2.0",
"circom_runtime": "0.0.3",
"circom_runtime": "0.0.4",
"escape-string-regexp": "^1.0.5",
"ffjavascript": "0.0.5",
"ffjavascript": "0.1.0",
"keccak": "^3.0.0",
"r1csfile": "0.0.3",
"r1csfile": "0.0.4",
"yargs": "^12.0.5"
},
"devDependencies": {

View File

@ -1,4 +1,3 @@
const bigInt = require("big-integer");
module.exports = function printR1cs(r1cs, syms) {
for (let i=0; i<r1cs.constraints.length; i++) {
@ -10,23 +9,13 @@ module.exports = function printR1cs(r1cs, syms) {
for (let k in lc) {
let name = syms.varIdx2Name[k];
if (name == "one") name = "";
let v = bigInt(lc[k]);
let vs;
if (!v.lesserOrEquals(r1cs.prime.shiftRight(bigInt(1)))) {
v = r1cs.prime.minus(v);
vs = "-"+v.toString();
} else {
if (S!="") {
vs = "+"+v.toString();
} else {
vs = "";
}
if (vs!="1") {
vs = vs + v.toString();
}
}
S= S + " " + vs + name;
let vs = r1cs.Fr.toString(lc[k]);
if (vs == "1") vs = ""; // Do not show ones
if (vs == "-1") vs = "-"; // Do not show ones
if ((S!="")&&(vs[0]!="-")) vs = "+"+vs;
if (S!="") vs = " "+vs;
S= S + vs + name;
}
return S;
};

View File

@ -27,7 +27,7 @@ const PolF = new PolField(new ZqField(bn128.r));
const G1 = bn128.G1;
const G2 = bn128.G2;
module.exports = function genProof(vk_proof, witness) {
module.exports = function genProof(vk_proof, witness, verbose) {
const proof = {};
@ -57,12 +57,17 @@ module.exports = function genProof(vk_proof, witness) {
proof.pi_b = G2.add( proof.pi_b, G2.mulScalar( vk_proof.B2[s], witness[s]));
pib1 = G1.add( pib1, G1.mulScalar( vk_proof.B1[s], witness[s]));
if ((verbose)&&(s%1000 == 1)) console.log("A, B1, B2: ", s);
}
for (let s= vk_proof.nPublic+1; s< vk_proof.nVars; s++) {
// pi_a = pi_a + A[s] * witness[s];
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( vk_proof.C[s], witness[s]));
if ((verbose)&&(s%1000 == 1)) console.log("C: ", s);
}
proof.pi_a = G1.add( proof.pi_a, vk_proof.vk_alfa_1 );
@ -82,6 +87,8 @@ module.exports = function genProof(vk_proof, witness) {
for (let i = 0; i < h.length; i++) {
// console.log(i + "->" + h[i].toString());
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( vk_proof.hExps[i], h[i]));
if ((verbose)&&(i%1000 == 1)) console.log("H: ", i);
}
// proof.pi_c = G1.affine(proof.pi_c);

View File

@ -23,7 +23,7 @@ const bn128 = require("ffjavascript").bn128;
const PolField = require("ffjavascript").PolField;
const ZqField = require("ffjavascript").ZqField;
const createKeccakHash = require("keccak");
const utils = require("./utils");
const utils = require("ffjavascript").utils;
const PolF = new PolField(new ZqField(bn128.r));

View File

@ -69,13 +69,13 @@ function calculatePolinomials(setup, circuit) {
for (let c=0; c<circuit.nConstraints; c++) {
for (let s in circuit.constraints[c][0]) {
setup.vk_proof.polsA[s][c] = bigInt(circuit.constraints[c][0][s]);
setup.vk_proof.polsA[s][c] = circuit.constraints[c][0][s];
}
for (let s in circuit.constraints[c][1]) {
setup.vk_proof.polsB[s][c] = bigInt(circuit.constraints[c][1][s]);
setup.vk_proof.polsB[s][c] = circuit.constraints[c][1][s];
}
for (let s in circuit.constraints[c][2]) {
setup.vk_proof.polsC[s][c] = bigInt(circuit.constraints[c][2][s]);
setup.vk_proof.polsC[s][c] = circuit.constraints[c][2][s];
}
}

View File

@ -69,13 +69,13 @@ function calculatePolinomials(setup, circuit) {
for (let c=0; c<circuit.nConstraints; c++) {
for (let s in circuit.constraints[c][0]) {
setup.vk_proof.polsA[s][c] = bigInt(circuit.constraints[c][0][s]);
setup.vk_proof.polsA[s][c] = circuit.constraints[c][0][s];
}
for (let s in circuit.constraints[c][1]) {
setup.vk_proof.polsB[s][c] = bigInt(circuit.constraints[c][1][s]);
setup.vk_proof.polsB[s][c] = circuit.constraints[c][1][s];
}
for (let s in circuit.constraints[c][2]) {
setup.vk_proof.polsC[s][c] = bigInt(circuit.constraints[c][2][s]);
setup.vk_proof.polsC[s][c] = circuit.constraints[c][2][s];
}
}

View File

@ -68,13 +68,13 @@ function calculatePolinomials(setup, circuit) {
for (let c=0; c<circuit.nConstraints; c++) {
for (let s in circuit.constraints[c][0]) {
setup.vk_proof.polsA[s][c] = bigInt(circuit.constraints[c][0][s]);
setup.vk_proof.polsA[s][c] = circuit.constraints[c][0][s];
}
for (let s in circuit.constraints[c][1]) {
setup.vk_proof.polsB[s][c] = bigInt(circuit.constraints[c][1][s]);
setup.vk_proof.polsB[s][c] = circuit.constraints[c][1][s];
}
for (let s in circuit.constraints[c][2]) {
setup.vk_proof.polsC[s][c] = bigInt(circuit.constraints[c][2][s]);
setup.vk_proof.polsC[s][c] = circuit.constraints[c][2][s];
}
}

View File

@ -1,63 +0,0 @@
const bigInt = require("big-integer");
module.exports.stringifyBigInts = stringifyBigInts;
module.exports.unstringifyBigInts = unstringifyBigInts;
module.exports.beBuff2int = beBuff2int;
module.exports.beInt2Buff = beInt2Buff;
function beBuff2int(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;
}
function beInt2Buff(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;
}
function stringifyBigInts(o) {
if ((typeof(o) == "bigint") || o.eq !== undefined) {
return o.toString(10);
} else if (Array.isArray(o)) {
return o.map(stringifyBigInts);
} else if (typeof o == "object") {
const res = {};
for (let k in o) {
res[k] = stringifyBigInts(o[k]);
}
return res;
} else {
return o;
}
}
function unstringifyBigInts(o) {
if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
return bigInt(o);
} else if (Array.isArray(o)) {
return o.map(unstringifyBigInts);
} else if (typeof o == "object") {
const res = {};
for (let k in o) {
res[k] = unstringifyBigInts(o[k]);
}
return res;
} else {
return o;
}
}

View File

@ -22,7 +22,7 @@
const bn128 = require("ffjavascript").bn128;
const createKeccakHash = require("keccak");
const utils = require("./utils");
const utils = require("ffjavascript").utils;
const G1 = bn128.G1;
const G2 = bn128.G2;
@ -50,8 +50,8 @@ module.exports = function isValid(vk_verifier, proof, publicSignals) {
const h2 = utils.beBuff2int(h2buff);
// const h1 = bigInt.zero;
// const h2 = bigInt.zero;
// const h1 = bn128.Fr.zero;
// const h2 = bn128.Fr.zero;
// console.log(h1.toString());
// console.log(h2.toString());