bls12-381 working
This commit is contained in:
parent
8bc56a54a6
commit
6b08298526
118
cli.js
118
cli.js
@ -33,13 +33,12 @@ const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuil
|
|||||||
const wtnsFile = require("./src/wtnsfile");
|
const wtnsFile = require("./src/wtnsfile");
|
||||||
|
|
||||||
const loadSyms = require("./src/loadsyms");
|
const loadSyms = require("./src/loadsyms");
|
||||||
const printR1cs = require("./src/printr1cs");
|
const r1cs = require("./src/r1cs");
|
||||||
|
|
||||||
const clProcessor = require("./src/clprocessor");
|
const clProcessor = require("./src/clprocessor");
|
||||||
|
|
||||||
const powersOfTaw = require("./src/powersoftau");
|
const powersOfTaw = require("./src/powersoftau");
|
||||||
|
|
||||||
const bn128 = require("ffjavascript").bn128;
|
|
||||||
const solidityGenerator = require("./src/soliditygenerator.js");
|
const solidityGenerator = require("./src/soliditygenerator.js");
|
||||||
|
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
@ -64,18 +63,32 @@ const commands = [
|
|||||||
action: r1csPrint
|
action: r1csPrint
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cmd: "witness calculate [circuit.wasm] [input.json] [witness.wtns]",
|
cmd: "r1cs export json [circuit.r1cs] [circuit.json]",
|
||||||
description: "Caclculate specific witness of a circuit given an input",
|
description: "Export r1cs to JSON file",
|
||||||
alias: ["wc", "calculatewitness -ws|wasm:circuit.wasm -i|input:input.json -wt|witness:witness.wtns"],
|
alias: ["rej"],
|
||||||
action: witnessCalculate
|
action: r1csExportJSON
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cmd: "witness debug [circuit.wasm] [input.json] [witness.wtns] [circuit.sym]",
|
cmd: "wtns calculate [circuit.wasm] [input.json] [witness.wtns]",
|
||||||
|
description: "Caclculate specific witness of a circuit given an input",
|
||||||
|
alias: ["wc", "calculatewitness -ws|wasm:circuit.wasm -i|input:input.json -wt|witness:witness.wtns"],
|
||||||
|
action: wtnsCalculate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cmd: "wtns debug [circuit.wasm] [input.json] [witness.wtns] [circuit.sym]",
|
||||||
description: "Calculate the witness with debug info.",
|
description: "Calculate the witness with debug info.",
|
||||||
longDescription: "Calculate the witness with debug info. \nOptions:\n-g or --g : Log signal gets\n-s or --s : Log signal sets\n-t or --trigger : Log triggers ",
|
longDescription: "Calculate the witness with debug info. \nOptions:\n-g or --g : Log signal gets\n-s or --s : Log signal sets\n-t or --trigger : Log triggers ",
|
||||||
options: "-get|g -set|s -trigger|t",
|
options: "-get|g -set|s -trigger|t",
|
||||||
alias: ["wd"],
|
alias: ["wd"],
|
||||||
action: witnessDebug
|
action: wtnsDebug
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cmd: "wtns export json [witness.wtns] [witnes.json]",
|
||||||
|
description: "Calculate the witness with debug info.",
|
||||||
|
longDescription: "Calculate the witness with debug info. \nOptions:\n-g or --g : Log signal gets\n-s or --s : Log signal sets\n-t or --trigger : Log triggers ",
|
||||||
|
options: "-get|g -set|s -trigger|t",
|
||||||
|
alias: ["wej"],
|
||||||
|
action: wtnsExportJson
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cmd: "zksnark setup [circuit.r1cs] [circuit.zkey] [verification_key.json]",
|
cmd: "zksnark setup [circuit.r1cs] [circuit.zkey] [verification_key.json]",
|
||||||
@ -110,7 +123,7 @@ const commands = [
|
|||||||
action: solidityGenCall
|
action: solidityGenCall
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cmd: "powersoftau new <power> [powersoftau_0000.ptau]",
|
cmd: "powersoftau new <curve> <power> [powersoftau_0000.ptau]",
|
||||||
description: "Starts a powers of tau ceremony",
|
description: "Starts a powers of tau ceremony",
|
||||||
alias: ["ptn"],
|
alias: ["ptn"],
|
||||||
options: "-verbose|v",
|
options: "-verbose|v",
|
||||||
@ -314,13 +327,8 @@ function changeExt(fileName, newExt) {
|
|||||||
async function r1csInfo(params, options) {
|
async function r1csInfo(params, options) {
|
||||||
const r1csName = params[0] || "circuit.r1cs";
|
const r1csName = params[0] || "circuit.r1cs";
|
||||||
|
|
||||||
const cir = await loadR1cs(r1csName);
|
await r1cs.info(r1csName);
|
||||||
|
|
||||||
console.log(`# Wires: ${cir.nVars}`);
|
|
||||||
console.log(`# Constraints: ${cir.nConstraints}`);
|
|
||||||
console.log(`# Private Inputs: ${cir.nPrvInputs}`);
|
|
||||||
console.log(`# Public Inputs: ${cir.nPubInputs}`);
|
|
||||||
console.log(`# Outputs: ${cir.nOutputs}`);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -328,18 +336,29 @@ async function r1csInfo(params, options) {
|
|||||||
// r1cs print [circuit.r1cs] [circuit.sym]
|
// r1cs print [circuit.r1cs] [circuit.sym]
|
||||||
async function r1csPrint(params, options) {
|
async function r1csPrint(params, options) {
|
||||||
const r1csName = params[0] || "circuit.r1cs";
|
const r1csName = params[0] || "circuit.r1cs";
|
||||||
const symName = params[2] || changeExt(r1csName, "sym");
|
const symName = params[1] || changeExt(r1csName, "sym");
|
||||||
const cir = await loadR1cs(r1csName, true, true);
|
const cir = await loadR1cs(r1csName, true, true);
|
||||||
|
|
||||||
const sym = await loadSyms(symName);
|
const sym = await loadSyms(symName);
|
||||||
|
|
||||||
printR1cs(cir, sym);
|
await r1cs.print(cir, sym);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// witness calculate <circuit.wasm> <input.json> <witness.wtns>
|
|
||||||
async function witnessCalculate(params, options) {
|
// r1cs export json [circuit.r1cs] [circuit.json]
|
||||||
|
async function r1csExportJSON(params, options) {
|
||||||
|
const r1csName = params[0] || "circuit.r1cs";
|
||||||
|
const jsonName = params[1] || changeExt(r1csName, "json");
|
||||||
|
|
||||||
|
await r1cs.exportJson(r1csName, jsonName);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wtns calculate <circuit.wasm> <input.json> <witness.wtns>
|
||||||
|
async function wtnsCalculate(params, options) {
|
||||||
const wasmName = params[0] || "circuit.wasm";
|
const wasmName = params[0] || "circuit.wasm";
|
||||||
const inputName = params[1] || "input.json";
|
const inputName = params[1] || "input.json";
|
||||||
const witnessName = params[2] || "witness.wtns";
|
const witnessName = params[2] || "witness.wtns";
|
||||||
@ -361,9 +380,9 @@ async function witnessCalculate(params, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// witness debug <circuit.wasm> <input.json> <witness.wtns> <circuit.sym>
|
// wtns debug <circuit.wasm> <input.json> <witness.wtns> <circuit.sym>
|
||||||
// -get|g -set|s -trigger|t
|
// -get|g -set|s -trigger|t
|
||||||
async function witnessDebug(params, options) {
|
async function wtnsDebug(params, options) {
|
||||||
const wasmName = params[0] || "circuit.wasm";
|
const wasmName = params[0] || "circuit.wasm";
|
||||||
const inputName = params[1] || "input.json";
|
const inputName = params[1] || "input.json";
|
||||||
const witnessName = params[2] || "witness.wtns";
|
const witnessName = params[2] || "witness.wtns";
|
||||||
@ -410,6 +429,21 @@ async function witnessDebug(params, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// wtns export json [witness.wtns] [witness.json]
|
||||||
|
// -get|g -set|s -trigger|t
|
||||||
|
async function wtnsExportJson(params, options) {
|
||||||
|
const wtnsName = params[0] || "witness.wtns";
|
||||||
|
const jsonName = params[1] || "witness.json";
|
||||||
|
|
||||||
|
const w = await wtnsFile.read(wtnsName);
|
||||||
|
|
||||||
|
await fs.promises.writeFile(jsonName, JSON.stringify(stringifyBigInts(w), null, 1));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// zksnark setup [circuit.r1cs] [circuit.zkey] [verification_key.json]
|
// zksnark setup [circuit.r1cs] [circuit.zkey] [verification_key.json]
|
||||||
async function zksnarkSetup(params, options) {
|
async function zksnarkSetup(params, options) {
|
||||||
|
|
||||||
@ -511,31 +545,7 @@ async function zkeyExportVKey(params) {
|
|||||||
const zkeyName = params[0] || "circuit.zkey";
|
const zkeyName = params[0] || "circuit.zkey";
|
||||||
const verificationKeyName = params[2] || "verification_key.json";
|
const verificationKeyName = params[2] || "verification_key.json";
|
||||||
|
|
||||||
const zKey = await zkey.utils.read(zkeyName);
|
return await zkey.exportVerificationKey(zkeyName, verificationKeyName);
|
||||||
|
|
||||||
let curve;
|
|
||||||
if (Scalar.eq(zKey.q, bn128.q)) {
|
|
||||||
curve = bn128;
|
|
||||||
} else {
|
|
||||||
assert(false, " Curve not supported");
|
|
||||||
}
|
|
||||||
const vKey = {
|
|
||||||
protocol: zKey.protocol,
|
|
||||||
nPublic: zKey.nPublic,
|
|
||||||
IC: zKey.IC,
|
|
||||||
|
|
||||||
|
|
||||||
vk_alpha_1: zKey.vk_alpha_1,
|
|
||||||
|
|
||||||
vk_beta_2: zKey.vk_beta_2,
|
|
||||||
vk_gamma_2: zKey.vk_gamma_2,
|
|
||||||
vk_delta_2: zKey.vk_delta_2,
|
|
||||||
|
|
||||||
vk_alphabeta_12: await curve.pairing( zKey.vk_alpha_1 , zKey.vk_beta_2 )
|
|
||||||
};
|
|
||||||
|
|
||||||
await fs.promises.writeFile(verificationKeyName, JSON.stringify(stringifyBigInts(vKey), null, 1), "utf-8");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// zkey export json [circuit.zkey] [circuit.zkey.json]",
|
// zkey export json [circuit.zkey] [circuit.zkey.json]",
|
||||||
@ -634,22 +644,28 @@ async function solidityGenCall(params, options) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// powersoftau new <curve> <power> [powersoftau_0000.ptau]",
|
||||||
async function powersOfTawNew(params, options) {
|
async function powersOfTawNew(params, options) {
|
||||||
|
let curveName;
|
||||||
let power;
|
let power;
|
||||||
let ptauName;
|
let ptauName;
|
||||||
|
|
||||||
power = parseInt(params[0]);
|
curveName = params[0];
|
||||||
|
|
||||||
|
power = parseInt(params[1]);
|
||||||
if ((power<1) || (power>28)) {
|
if ((power<1) || (power>28)) {
|
||||||
throw new Error("Power must be between 1 and 28");
|
throw new Error("Power must be between 1 and 28");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.length < 2) {
|
if (params.length < 3) {
|
||||||
ptauName = "powersOfTaw" + power + "_0000.ptau";
|
ptauName = "powersOfTaw" + power + "_0000.ptau";
|
||||||
} else {
|
} else {
|
||||||
ptauName = params[1];
|
ptauName = params[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
return await powersOfTaw.newAccumulator(bn128, power, ptauName, options.verbose);
|
const curve = await curves.getCurveFromName(curveName);
|
||||||
|
|
||||||
|
return await powersOfTaw.newAccumulator(curve, power, ptauName, options.verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function powersOfTawExportChallange(params, options) {
|
async function powersOfTawExportChallange(params, options) {
|
||||||
@ -672,7 +688,7 @@ async function powersOfTawChallangeContribute(params, options) {
|
|||||||
let challangeName;
|
let challangeName;
|
||||||
let responseName;
|
let responseName;
|
||||||
|
|
||||||
const curve = curves.getCurveFromName(params[0]);
|
const curve = await curves.getCurveFromName(params[0]);
|
||||||
|
|
||||||
challangeName = params[1];
|
challangeName = params[1];
|
||||||
|
|
||||||
|
@ -1,21 +1,44 @@
|
|||||||
const Scalar = require("ffjavascript").Scalar;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
const bn128 = require("ffjavascript").bn128;
|
const buildBn128 = require("ffjavascript").buildBn128;
|
||||||
|
const buildBls12381 = require("ffjavascript").buildBls12381;
|
||||||
|
|
||||||
module.exports.getCurveFromQ = function getCurveFromQ(q) {
|
const bls12381r = Scalar.e("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", 16);
|
||||||
|
const bn128r = Scalar.e("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
|
|
||||||
|
const bls12381q = Scalar.e("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", 16);
|
||||||
|
const bn128q = Scalar.e("21888242871839275222246405745257275088696311157297823662689037894645226208583");
|
||||||
|
|
||||||
|
module.exports.getCurveFromR = async function getCurveFromR(r) {
|
||||||
let curve;
|
let curve;
|
||||||
if (Scalar.eq(q, bn128.q)) {
|
if (Scalar.eq(r, bn128r)) {
|
||||||
curve = bn128;
|
curve = await buildBn128();
|
||||||
|
} else if (Scalar.eq(r, bls12381r)) {
|
||||||
|
curve = await buildBls12381();
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Curve not supported: ${q.toString()}`);
|
throw new Error(`Curve not supported: ${Scalar.toString(r)}`);
|
||||||
}
|
}
|
||||||
return curve;
|
return curve;
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.getCurveFromName = function getCurveFromName(name) {
|
module.exports.getCurveFromQ = async function getCurveFromQ(q) {
|
||||||
|
let curve;
|
||||||
|
if (Scalar.eq(q, bn128q)) {
|
||||||
|
curve = await buildBn128();
|
||||||
|
} else if (Scalar.eq(q, bls12381q)) {
|
||||||
|
curve = await buildBls12381();
|
||||||
|
} else {
|
||||||
|
throw new Error(`Curve not supported: ${Scalar.toString(q)}`);
|
||||||
|
}
|
||||||
|
return curve;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.getCurveFromName = async function getCurveFromName(name) {
|
||||||
let curve;
|
let curve;
|
||||||
const normName = normalizeName(name);
|
const normName = normalizeName(name);
|
||||||
if (["BN128", "BN254", "ALTBN128"].indexOf(normName) >= 0) {
|
if (["BN128", "BN254", "ALTBN128"].indexOf(normName) >= 0) {
|
||||||
curve = bn128;
|
curve = await buildBn128();
|
||||||
|
} else if (["BLS12381"].indexOf(normName) >= 0) {
|
||||||
|
curve = await buildBls12381();
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Curve not supported: ${name}`);
|
throw new Error(`Curve not supported: ${name}`);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
|
|
||||||
const bn128 = require("ffjavascript").bn128;
|
|
||||||
const utils = require("ffjavascript").utils;
|
|
||||||
|
|
||||||
const blake2b = require("blake2b-wasm");
|
const blake2b = require("blake2b-wasm");
|
||||||
|
|
||||||
const ChaCha = require("ffjavascript").ChaCha;
|
const ChaCha = require("ffjavascript").ChaCha;
|
||||||
|
|
||||||
function hashToG2(hash) {
|
function hashToG2(curve, hash) {
|
||||||
const hashV = new DataView(hash.buffer, hash.byteOffset, hash.byteLength);
|
const hashV = new DataView(hash.buffer, hash.byteOffset, hash.byteLength);
|
||||||
const seed = [];
|
const seed = [];
|
||||||
for (let i=0; i<8; i++) {
|
for (let i=0; i<8; i++) {
|
||||||
@ -15,30 +12,31 @@ function hashToG2(hash) {
|
|||||||
|
|
||||||
const rng = new ChaCha(seed);
|
const rng = new ChaCha(seed);
|
||||||
|
|
||||||
const g2_sp = bn128.G2.fromRng(rng);
|
const g2_sp = curve.G2.fromRng(rng);
|
||||||
|
|
||||||
return g2_sp;
|
return g2_sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getG2sp(persinalization, challange, g1s, g1sx) {
|
function getG2sp(curve, persinalization, challange, g1s, g1sx) {
|
||||||
|
|
||||||
const h = blake2b(64);
|
const h = blake2b(64);
|
||||||
h.update(Buffer.from([persinalization]));
|
const b1 = new Uint8Array([persinalization]);
|
||||||
|
h.update(b1);
|
||||||
h.update(challange);
|
h.update(challange);
|
||||||
h.update( utils.beInt2Buff(g1s[0],32));
|
const b3 = curve.G1.toUncompressed(g1s);
|
||||||
h.update( utils.beInt2Buff(g1s[1],32));
|
h.update( b3);
|
||||||
h.update( utils.beInt2Buff(g1sx[0],32));
|
const b4 = curve.G1.toUncompressed(g1sx);
|
||||||
h.update( utils.beInt2Buff(g1sx[1],32));
|
h.update( b4);
|
||||||
const hash = Buffer.from(h.digest());
|
const hash =h.digest();
|
||||||
|
|
||||||
return hashToG2(hash);
|
return hashToG2(curve, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculatePubKey(k, curve, personalization, challangeHash, rng ) {
|
function calculatePubKey(k, curve, personalization, challangeHash, rng ) {
|
||||||
k.g1_s = curve.G1.affine(curve.G1.fromRng(rng));
|
k.g1_s = curve.G1.toAffine(curve.G1.fromRng(rng));
|
||||||
k.g1_sx = curve.G1.affine(curve.G1.mulScalar(k.g1_s, k.prvKey));
|
k.g1_sx = curve.G1.toAffine(curve.G1.timesFr(k.g1_s, k.prvKey));
|
||||||
k.g2_sp = curve.G2.affine(getG2sp(personalization, challangeHash, k.g1_s, k.g1_sx));
|
k.g2_sp = curve.G2.toAffine(getG2sp(curve, personalization, challangeHash, k.g1_s, k.g1_sx));
|
||||||
k.g2_spx = curve.G2.affine(curve.G2.mulScalar(k.g2_sp, k.prvKey));
|
k.g2_spx = curve.G2.toAffine(curve.G2.timesFr(k.g2_sp, k.prvKey));
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,10 +58,10 @@ function createPTauKey(curve, challangeHash, rng) {
|
|||||||
function createDeltaKey(curve, transcript, rng) {
|
function createDeltaKey(curve, transcript, rng) {
|
||||||
const delta = {};
|
const delta = {};
|
||||||
delta.prvKey = curve.Fr.fromRng(rng);
|
delta.prvKey = curve.Fr.fromRng(rng);
|
||||||
delta.g1_s = curve.G1.affine(curve.G1.fromRng(rng));
|
delta.g1_s = curve.G1.toAffine(curve.G1.fromRng(rng));
|
||||||
delta.g1_sx = curve.G1.affine(curve.G1.mulScalar(delta.g1_s, delta.prvKey));
|
delta.g1_sx = curve.G1.toAffine(curve.G1.timesScalar(delta.g1_s, delta.prvKey));
|
||||||
delta.g2_sp = hashToG2(transcript);
|
delta.g2_sp = hashToG2(curve, transcript);
|
||||||
delta.g2_spx = curve.G2.affine(curve.G2.mulScalar(delta.g2_sp, delta.prvKey));
|
delta.g2_spx = curve.G2.toAffine(curve.G2.timesScalar(delta.g2_sp, delta.prvKey));
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,9 +53,9 @@ async function applyKeyToChallangeSection(fdOld, fdNew, responseHasher, curve, g
|
|||||||
buffOut = await G.batchLEMtoU(buffOutLEM);
|
buffOut = await G.batchLEMtoU(buffOutLEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseHasher) responseHasher.update(buffOutC);
|
if (responseHasher) responseHasher.update(buffOut);
|
||||||
await fdNew.write(buffOut);
|
await fdNew.write(buffOut);
|
||||||
t = curve.Fr.mul(t, curve.Fr.pow(inc, n));
|
t = curve.Fr.mul(t, curve.Fr.exp(inc, n));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ async function beacon(oldPtauFilename, newPTauFilename, name, numIterationsExp,
|
|||||||
if (i==0) // Return the 2 first points.
|
if (i==0) // Return the 2 first points.
|
||||||
for (let j=0; j<Math.min(2, NPoints); j++)
|
for (let j=0; j<Math.min(2, NPoints); j++)
|
||||||
res.push(G.fromRprLEM(buffOutLEM, j*sG));
|
res.push(G.fromRprLEM(buffOutLEM, j*sG));
|
||||||
t = curve.Fr.mul(t, curve.Fr.pow(inc, n));
|
t = curve.Fr.mul(t, curve.Fr.exp(inc, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
await binFileUtils.endWriteSection(fdNew);
|
await binFileUtils.endWriteSection(fdNew);
|
||||||
|
@ -131,7 +131,7 @@ async function contribute(oldPtauFilename, newPTauFilename, name, entropy, verbo
|
|||||||
if (i==0) // Return the 2 first points.
|
if (i==0) // Return the 2 first points.
|
||||||
for (let j=0; j<Math.min(2, NPoints); j++)
|
for (let j=0; j<Math.min(2, NPoints); j++)
|
||||||
res.push(G.fromRprLEM(buffOutLEM, j*sG));
|
res.push(G.fromRprLEM(buffOutLEM, j*sG));
|
||||||
t = curve.Fr.mul(t, curve.Fr.pow(inc, n));
|
t = curve.Fr.mul(t, curve.Fr.exp(inc, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
await binFileUtils.endWriteSection(fdNew);
|
await binFileUtils.endWriteSection(fdNew);
|
||||||
|
@ -60,10 +60,8 @@ async function newAccumulator(curve, power, fileName, verbose) {
|
|||||||
|
|
||||||
await ptauUtils.writePTauHeader(fd, curve, power, 0);
|
await ptauUtils.writePTauHeader(fd, curve, power, 0);
|
||||||
|
|
||||||
const buffG1 = new Uint8Array(curve.G1.F.n8*2);
|
const buffG1 = curve.G1.oneAffine;
|
||||||
const buffG2 = new Uint8Array(curve.G2.F.n8*2);
|
const buffG2 = curve.G2.oneAffine;
|
||||||
curve.G1.toRprLEM(buffG1, 0, curve.G1.g);
|
|
||||||
curve.G2.toRprLEM(buffG2, 0, curve.G2.g);
|
|
||||||
|
|
||||||
// Write tauG1
|
// Write tauG1
|
||||||
///////////
|
///////////
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
const assert = require("assert");
|
const assert = require("assert");
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
const bn128 = require("ffjavascript").bn128;
|
|
||||||
const Blake2b = require("blake2b-wasm");
|
const Blake2b = require("blake2b-wasm");
|
||||||
const keyPair = require("./keypair");
|
const keyPair = require("./keypair");
|
||||||
const misc = require("./misc");
|
const misc = require("./misc");
|
||||||
|
const {getCurveFromQ} = require("./curves");
|
||||||
|
|
||||||
async function writePTauHeader(fd, curve, power, ceremonyPower) {
|
async function writePTauHeader(fd, curve, power, ceremonyPower) {
|
||||||
// Write the header
|
// Write the header
|
||||||
@ -39,12 +39,9 @@ async function readPTauHeader(fd, sections) {
|
|||||||
const n8 = await fd.readULE32();
|
const n8 = await fd.readULE32();
|
||||||
const buff = await fd.read(n8);
|
const buff = await fd.read(n8);
|
||||||
const q = Scalar.fromRprLE(buff);
|
const q = Scalar.fromRprLE(buff);
|
||||||
let curve;
|
|
||||||
if (Scalar.eq(q, bn128.q)) {
|
const curve = await getCurveFromQ(q);
|
||||||
curve = bn128;
|
|
||||||
} else {
|
|
||||||
assert(false, fd.fileName +": Curve not supported");
|
|
||||||
}
|
|
||||||
assert(curve.F1.n64*8 == n8, fd.fileName +": Invalid size");
|
assert(curve.F1.n64*8 == n8, fd.fileName +": Invalid size");
|
||||||
|
|
||||||
const power = await fd.readULE32();
|
const power = await fd.readULE32();
|
||||||
@ -88,7 +85,7 @@ function fromPtauPubKeyRpr(buff, pos, curve, montgomery) {
|
|||||||
if (montgomery) {
|
if (montgomery) {
|
||||||
p = curve.G1.fromRprLEM( buff, pos );
|
p = curve.G1.fromRprLEM( buff, pos );
|
||||||
} else {
|
} else {
|
||||||
p = curve.G1.fromRprBE( buff, pos );
|
p = curve.G1.fromRprUncompressed( buff, pos );
|
||||||
}
|
}
|
||||||
pos += curve.G1.F.n8*2;
|
pos += curve.G1.F.n8*2;
|
||||||
return p;
|
return p;
|
||||||
@ -99,7 +96,7 @@ function fromPtauPubKeyRpr(buff, pos, curve, montgomery) {
|
|||||||
if (montgomery) {
|
if (montgomery) {
|
||||||
p = curve.G2.fromRprLEM( buff, pos );
|
p = curve.G2.fromRprLEM( buff, pos );
|
||||||
} else {
|
} else {
|
||||||
p = curve.G2.fromRprBE( buff, pos );
|
p = curve.G2.fromRprUncompressed( buff, pos );
|
||||||
}
|
}
|
||||||
pos += curve.G2.F.n8*2;
|
pos += curve.G2.F.n8*2;
|
||||||
return p;
|
return p;
|
||||||
@ -122,7 +119,7 @@ function toPtauPubKeyRpr(buff, pos, curve, key, montgomery) {
|
|||||||
if (montgomery) {
|
if (montgomery) {
|
||||||
curve.G1.toRprLEM(buff, pos, p);
|
curve.G1.toRprLEM(buff, pos, p);
|
||||||
} else {
|
} else {
|
||||||
curve.G1.toRprBE(buff, pos, p);
|
curve.G1.toRprUncompressed(buff, pos, p);
|
||||||
}
|
}
|
||||||
pos += curve.F1.n8*2;
|
pos += curve.F1.n8*2;
|
||||||
}
|
}
|
||||||
@ -131,7 +128,7 @@ function toPtauPubKeyRpr(buff, pos, curve, key, montgomery) {
|
|||||||
if (montgomery) {
|
if (montgomery) {
|
||||||
curve.G2.toRprLEM(buff, pos, p);
|
curve.G2.toRprLEM(buff, pos, p);
|
||||||
} else {
|
} else {
|
||||||
curve.G2.toRprBE(buff, pos, p);
|
curve.G2.toRprUncompressed(buff, pos, p);
|
||||||
}
|
}
|
||||||
pos += curve.F2.n8*2;
|
pos += curve.F2.n8*2;
|
||||||
}
|
}
|
||||||
@ -194,12 +191,12 @@ async function readContribution(fd, curve) {
|
|||||||
return c;
|
return c;
|
||||||
|
|
||||||
async function readG1() {
|
async function readG1() {
|
||||||
const pBuff = await fd.read(curve.F1.n8*2);
|
const pBuff = await fd.read(curve.G1.F.n8*2);
|
||||||
return curve.G1.fromRprLEM( pBuff );
|
return curve.G1.fromRprLEM( pBuff );
|
||||||
}
|
}
|
||||||
|
|
||||||
async function readG2() {
|
async function readG2() {
|
||||||
const pBuff = await fd.read(curve.F2.n8*2);
|
const pBuff = await fd.read(curve.G2.F.n8*2);
|
||||||
return curve.G2.fromRprLEM( pBuff );
|
return curve.G2.fromRprLEM( pBuff );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,8 +299,8 @@ function calculateFirstChallangeHash(curve, power, verbose) {
|
|||||||
|
|
||||||
const vG1 = new Uint8Array(curve.G1.F.n8*2);
|
const vG1 = new Uint8Array(curve.G1.F.n8*2);
|
||||||
const vG2 = new Uint8Array(curve.G2.F.n8*2);
|
const vG2 = new Uint8Array(curve.G2.F.n8*2);
|
||||||
curve.G1.toRprBE(vG1, 0, curve.G1.g);
|
curve.G1.toRprUncompressed(vG1, 0, curve.G1.g);
|
||||||
curve.G2.toRprBE(vG2, 0, curve.G2.g);
|
curve.G2.toRprUncompressed(vG2, 0, curve.G2.g);
|
||||||
|
|
||||||
hasher.update(Blake2b(64).digest());
|
hasher.update(Blake2b(64).digest());
|
||||||
|
|
||||||
|
@ -53,9 +53,9 @@ async function verifyContribution(curve, cur, prev) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cur.key.tau.g2_sp = keyPair.getG2sp(0, prev.nextChallange, cur.key.tau.g1_s, cur.key.tau.g1_sx);
|
cur.key.tau.g2_sp = curve.G2.toAffine(keyPair.getG2sp(curve, 0, prev.nextChallange, cur.key.tau.g1_s, cur.key.tau.g1_sx));
|
||||||
cur.key.alpha.g2_sp = keyPair.getG2sp(1, prev.nextChallange, cur.key.alpha.g1_s, cur.key.alpha.g1_sx);
|
cur.key.alpha.g2_sp = curve.G2.toAffine(keyPair.getG2sp(curve, 1, prev.nextChallange, cur.key.alpha.g1_s, cur.key.alpha.g1_sx));
|
||||||
cur.key.beta.g2_sp = keyPair.getG2sp(2, prev.nextChallange, cur.key.beta.g1_s, cur.key.beta.g1_sx);
|
cur.key.beta.g2_sp = curve.G2.toAffine(keyPair.getG2sp(curve, 2, prev.nextChallange, cur.key.beta.g1_s, cur.key.beta.g1_sx));
|
||||||
|
|
||||||
sr = await sameRatio(curve, cur.key.tau.g1_s, cur.key.tau.g1_sx, cur.key.tau.g2_sp, cur.key.tau.g2_spx);
|
sr = await sameRatio(curve, cur.key.tau.g1_s, cur.key.tau.g1_sx, cur.key.tau.g2_sp, cur.key.tau.g2_spx);
|
||||||
if (sr !== true) {
|
if (sr !== true) {
|
||||||
@ -308,7 +308,7 @@ async function verify(tauFilename, verbose) {
|
|||||||
const buff = await fd.read(sG);
|
const buff = await fd.read(sG);
|
||||||
const P = G.fromRprLEM(buff);
|
const P = G.fromRprLEM(buff);
|
||||||
|
|
||||||
G.toRprBE(buffUv, 0, P);
|
G.toRprUncompressed(buffUv, 0, P);
|
||||||
nextContributionHasher.update(buffUv);
|
nextContributionHasher.update(buffUv);
|
||||||
|
|
||||||
return P;
|
return P;
|
||||||
@ -343,8 +343,8 @@ async function verify(tauFilename, verbose) {
|
|||||||
const firstBase = G.fromRprLEM(bases, 0);
|
const firstBase = G.fromRprLEM(bases, 0);
|
||||||
const r = crypto.randomBytes(4).readUInt32BE(0, true);
|
const r = crypto.randomBytes(4).readUInt32BE(0, true);
|
||||||
|
|
||||||
R1 = G.add(R1, G.mulScalar(lastBase, r));
|
R1 = G.add(R1, G.timesScalar(lastBase, r));
|
||||||
R2 = G.add(R2, G.mulScalar(firstBase, r));
|
R2 = G.add(R2, G.timesScalar(firstBase, r));
|
||||||
}
|
}
|
||||||
|
|
||||||
const r1 = await G.multiExpAffine(bases.slice(0, (n-1)*sG), scalars);
|
const r1 = await G.multiExpAffine(bases.slice(0, (n-1)*sG), scalars);
|
||||||
|
@ -23,9 +23,11 @@ const bn128 = require("ffjavascript").bn128;
|
|||||||
const PolField = require("ffjavascript").PolField;
|
const PolField = require("ffjavascript").PolField;
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
|
||||||
|
/*
|
||||||
const PolF = new PolField(new ZqField(bn128.r));
|
const PolF = new PolField(new ZqField(bn128.r));
|
||||||
const G1 = bn128.G1;
|
const G1 = bn128.G1;
|
||||||
const G2 = bn128.G2;
|
const G2 = bn128.G2;
|
||||||
|
*/
|
||||||
|
|
||||||
module.exports = function genProof(vk_proof, witness, verbose) {
|
module.exports = function genProof(vk_proof, witness, verbose) {
|
||||||
|
|
||||||
@ -51,12 +53,12 @@ module.exports = function genProof(vk_proof, witness, verbose) {
|
|||||||
|
|
||||||
for (let s= 0; s< vk_proof.nVars; s++) {
|
for (let s= 0; s< vk_proof.nVars; s++) {
|
||||||
// pi_a = pi_a + A[s] * witness[s];
|
// pi_a = pi_a + A[s] * witness[s];
|
||||||
proof.pi_a = G1.add( proof.pi_a, G1.mulScalar( vk_proof.A[s], witness[s]));
|
proof.pi_a = G1.add( proof.pi_a, G1.timesScalar( vk_proof.A[s], witness[s]));
|
||||||
|
|
||||||
// pi_b = pi_b + B[s] * witness[s];
|
// pi_b = pi_b + B[s] * witness[s];
|
||||||
proof.pi_b = G2.add( proof.pi_b, G2.mulScalar( vk_proof.B2[s], witness[s]));
|
proof.pi_b = G2.add( proof.pi_b, G2.timesScalar( vk_proof.B2[s], witness[s]));
|
||||||
|
|
||||||
pib1 = G1.add( pib1, G1.mulScalar( vk_proof.B1[s], witness[s]));
|
pib1 = G1.add( pib1, G1.timesScalar( vk_proof.B1[s], witness[s]));
|
||||||
|
|
||||||
if ((verbose)&&(s%1000 == 1)) console.log("A, B1, B2: ", s);
|
if ((verbose)&&(s%1000 == 1)) console.log("A, B1, B2: ", s);
|
||||||
|
|
||||||
@ -65,45 +67,45 @@ module.exports = function genProof(vk_proof, witness, verbose) {
|
|||||||
for (let s= vk_proof.nPublic+1; s< vk_proof.nVars; s++) {
|
for (let s= vk_proof.nPublic+1; s< vk_proof.nVars; s++) {
|
||||||
|
|
||||||
// pi_a = pi_a + A[s] * witness[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]));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesScalar( vk_proof.C[s], witness[s]));
|
||||||
|
|
||||||
if ((verbose)&&(s%1000 == 1)) console.log("C: ", s);
|
if ((verbose)&&(s%1000 == 1)) console.log("C: ", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
proof.pi_a = G1.add( proof.pi_a, vk_proof.vk_alpha_1 );
|
proof.pi_a = G1.add( proof.pi_a, vk_proof.vk_alpha_1 );
|
||||||
proof.pi_a = G1.add( proof.pi_a, G1.mulScalar( vk_proof.vk_delta_1, r ));
|
proof.pi_a = G1.add( proof.pi_a, G1.timesScalar( vk_proof.vk_delta_1, r ));
|
||||||
|
|
||||||
proof.pi_b = G2.add( proof.pi_b, vk_proof.vk_beta_2 );
|
proof.pi_b = G2.add( proof.pi_b, vk_proof.vk_beta_2 );
|
||||||
proof.pi_b = G2.add( proof.pi_b, G2.mulScalar( vk_proof.vk_delta_2, s ));
|
proof.pi_b = G2.add( proof.pi_b, G2.timesScalar( vk_proof.vk_delta_2, s ));
|
||||||
|
|
||||||
pib1 = G1.add( pib1, vk_proof.vk_beta_1 );
|
pib1 = G1.add( pib1, vk_proof.vk_beta_1 );
|
||||||
pib1 = G1.add( pib1, G1.mulScalar( vk_proof.vk_delta_1, s ));
|
pib1 = G1.add( pib1, G1.timesScalar( vk_proof.vk_delta_1, s ));
|
||||||
|
|
||||||
const h = calculateH(vk_proof, witness);
|
const h = calculateH(vk_proof, witness);
|
||||||
|
|
||||||
// proof.pi_c = G1.affine(proof.pi_c);
|
// proof.pi_c = G1.toAffine(proof.pi_c);
|
||||||
// console.log("pi_onlyc", proof.pi_c);
|
// console.log("pi_onlyc", proof.pi_c);
|
||||||
|
|
||||||
for (let i = 0; i < h.length; i++) {
|
for (let i = 0; i < h.length; i++) {
|
||||||
// console.log(i + "->" + h[i].toString());
|
// console.log(i + "->" + h[i].toString());
|
||||||
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( vk_proof.hExps[i], h[i]));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesScalar( vk_proof.hExps[i], h[i]));
|
||||||
|
|
||||||
if ((verbose)&&(i%1000 == 1)) console.log("H: ", i);
|
if ((verbose)&&(i%1000 == 1)) console.log("H: ", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// proof.pi_c = G1.affine(proof.pi_c);
|
// proof.pi_c = G1.toAffine(proof.pi_c);
|
||||||
// console.log("pi_candh", proof.pi_c);
|
// console.log("pi_candh", proof.pi_c);
|
||||||
|
|
||||||
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( proof.pi_a, s ));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesScalar( 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.timesScalar( pib1, r ));
|
||||||
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( vk_proof.vk_delta_1, PolF.F.neg(PolF.F.mul(r,s) )));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesScalar( 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);
|
||||||
|
|
||||||
proof.pi_a = G1.affine(proof.pi_a);
|
proof.pi_a = G1.toAffine(proof.pi_a);
|
||||||
proof.pi_b = G2.affine(proof.pi_b);
|
proof.pi_b = G2.toAffine(proof.pi_b);
|
||||||
proof.pi_c = G1.affine(proof.pi_c);
|
proof.pi_c = G1.toAffine(proof.pi_c);
|
||||||
|
|
||||||
proof.protocol = "groth";
|
proof.protocol = "groth";
|
||||||
|
|
||||||
|
@ -25,11 +25,11 @@ const ZqField = require("ffjavascript").ZqField;
|
|||||||
const createKeccakHash = require("keccak");
|
const createKeccakHash = require("keccak");
|
||||||
const utils = require("ffjavascript").utils;
|
const utils = require("ffjavascript").utils;
|
||||||
|
|
||||||
|
/*
|
||||||
const PolF = new PolField(new ZqField(bn128.r));
|
const PolF = new PolField(new ZqField(bn128.r));
|
||||||
const G1 = bn128.G1;
|
const G1 = bn128.G1;
|
||||||
const G2 = bn128.G2;
|
const G2 = bn128.G2;
|
||||||
|
*/
|
||||||
module.exports = function genProof(vk_proof, witness) {
|
module.exports = function genProof(vk_proof, witness) {
|
||||||
|
|
||||||
const proof = {};
|
const proof = {};
|
||||||
@ -58,35 +58,35 @@ module.exports = function genProof(vk_proof, witness) {
|
|||||||
|
|
||||||
for (let s= 0; s< vk_proof.nVars; s++) {
|
for (let s= 0; s< vk_proof.nVars; s++) {
|
||||||
// pi_a = pi_a + A[s] * witness[s];
|
// pi_a = pi_a + A[s] * witness[s];
|
||||||
proof.pi_a = G1.add( proof.pi_a, G1.mulScalar( vk_proof.A[s], witness[s]));
|
proof.pi_a = G1.add( proof.pi_a, G1.timesScalar( vk_proof.A[s], witness[s]));
|
||||||
|
|
||||||
// pi_b = pi_b + B[s] * witness[s];
|
// pi_b = pi_b + B[s] * witness[s];
|
||||||
proof.pi_b = G2.add( proof.pi_b, G2.mulScalar( vk_proof.B2[s], witness[s]));
|
proof.pi_b = G2.add( proof.pi_b, G2.timesScalar( vk_proof.B2[s], witness[s]));
|
||||||
|
|
||||||
piadelta = G1.add( piadelta, G1.mulScalar( vk_proof.Adelta[s], witness[s]));
|
piadelta = G1.add( piadelta, G1.timesScalar( vk_proof.Adelta[s], witness[s]));
|
||||||
pib1 = G1.add( pib1, G1.mulScalar( vk_proof.B1[s], witness[s]));
|
pib1 = G1.add( pib1, G1.timesScalar( vk_proof.B1[s], witness[s]));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let s= vk_proof.nPublic+1; s< vk_proof.nVars; s++) {
|
for (let s= vk_proof.nPublic+1; s< vk_proof.nVars; s++) {
|
||||||
|
|
||||||
// pi_a = pi_a + A[s] * witness[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]));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesScalar( vk_proof.C[s], witness[s]));
|
||||||
}
|
}
|
||||||
|
|
||||||
proof.pi_a = G1.add( proof.pi_a, vk_proof.vk_alpha_1 );
|
proof.pi_a = G1.add( proof.pi_a, vk_proof.vk_alpha_1 );
|
||||||
proof.pi_a = G1.add( proof.pi_a, G1.mulScalar( G1.g, r ));
|
proof.pi_a = G1.add( proof.pi_a, G1.timesScalar( G1.g, r ));
|
||||||
|
|
||||||
piadelta = G1.add( piadelta, vk_proof.vk_alphadelta_1);
|
piadelta = G1.add( piadelta, vk_proof.vk_alphadelta_1);
|
||||||
piadelta = G1.add( piadelta, G1.mulScalar( vk_proof.vk_delta_1, r ));
|
piadelta = G1.add( piadelta, G1.timesScalar( vk_proof.vk_delta_1, r ));
|
||||||
|
|
||||||
proof.pi_b = G2.add( proof.pi_b, vk_proof.vk_beta_2 );
|
proof.pi_b = G2.add( proof.pi_b, vk_proof.vk_beta_2 );
|
||||||
proof.pi_b = G2.add( proof.pi_b, G2.mulScalar( G2.g, s ));
|
proof.pi_b = G2.add( proof.pi_b, G2.timesScalar( G2.g, s ));
|
||||||
|
|
||||||
pib1 = G1.add( pib1, vk_proof.vk_beta_1 );
|
pib1 = G1.add( pib1, vk_proof.vk_beta_1 );
|
||||||
pib1 = G1.add( pib1, G1.mulScalar( G1.g, s ));
|
pib1 = G1.add( pib1, G1.timesScalar( G1.g, s ));
|
||||||
|
|
||||||
proof.pi_a = G1.affine(proof.pi_a);
|
proof.pi_a = G1.toAffine(proof.pi_a);
|
||||||
proof.pi_b = G2.affine(proof.pi_b);
|
proof.pi_b = G2.toAffine(proof.pi_b);
|
||||||
|
|
||||||
const buff = Buffer.concat([
|
const buff = Buffer.concat([
|
||||||
utils.beInt2Buff(proof.pi_a[0],32),
|
utils.beInt2Buff(proof.pi_a[0],32),
|
||||||
@ -111,28 +111,28 @@ module.exports = function genProof(vk_proof, witness) {
|
|||||||
|
|
||||||
const h = calculateH(vk_proof, witness);
|
const h = calculateH(vk_proof, witness);
|
||||||
|
|
||||||
// proof.pi_c = G1.affine(proof.pi_c);
|
// proof.pi_c = G1.toAffine(proof.pi_c);
|
||||||
// console.log("pi_onlyc", proof.pi_c);
|
// console.log("pi_onlyc", proof.pi_c);
|
||||||
|
|
||||||
for (let i = 0; i < h.length; i++) {
|
for (let i = 0; i < h.length; i++) {
|
||||||
// console.log(i + "->" + h[i].toString());
|
// console.log(i + "->" + h[i].toString());
|
||||||
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( vk_proof.hExps[i], h[i]));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesScalar( vk_proof.hExps[i], h[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// proof.pi_c = G1.affine(proof.pi_c);
|
// proof.pi_c = G1.toAffine(proof.pi_c);
|
||||||
// console.log("pi_candh", proof.pi_c);
|
// console.log("pi_candh", proof.pi_c);
|
||||||
|
|
||||||
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( proof.pi_a, s ));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesScalar( 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.timesScalar( pib1, r ));
|
||||||
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.timesScalar( 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.timesScalar( piadelta, h2 ));
|
||||||
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( pib1, h1 ));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesScalar( pib1, h1 ));
|
||||||
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( vk_proof.vk_delta_1, PolF.F.mul(h1,h2)));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesScalar( vk_proof.vk_delta_1, PolF.F.mul(h1,h2)));
|
||||||
|
|
||||||
const publicSignals = witness.slice(1, vk_proof.nPublic+1);
|
const publicSignals = witness.slice(1, vk_proof.nPublic+1);
|
||||||
|
|
||||||
proof.pi_c = G1.affine(proof.pi_c);
|
proof.pi_c = G1.toAffine(proof.pi_c);
|
||||||
|
|
||||||
proof.protocol = "kimleeoh";
|
proof.protocol = "kimleeoh";
|
||||||
|
|
||||||
|
@ -20,11 +20,11 @@
|
|||||||
const bn128 = require("ffjavascript").bn128;
|
const bn128 = require("ffjavascript").bn128;
|
||||||
const PolField = require("ffjavascript").PolField;
|
const PolField = require("ffjavascript").PolField;
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
/*
|
||||||
const PolF = new PolField(new ZqField(bn128.r));
|
const PolF = new PolField(new ZqField(bn128.r));
|
||||||
const G1 = bn128.G1;
|
const G1 = bn128.G1;
|
||||||
const G2 = bn128.G2;
|
const G2 = bn128.G2;
|
||||||
|
*/
|
||||||
module.exports = function genProof(vk_proof, witness) {
|
module.exports = function genProof(vk_proof, witness) {
|
||||||
|
|
||||||
const proof = {};
|
const proof = {};
|
||||||
@ -48,41 +48,41 @@ module.exports = function genProof(vk_proof, witness) {
|
|||||||
for (let s= vk_proof.nPublic+1; s< vk_proof.nVars; s++) {
|
for (let s= vk_proof.nPublic+1; s< vk_proof.nVars; s++) {
|
||||||
|
|
||||||
// pi_a = pi_a + A[s] * witness[s];
|
// pi_a = pi_a + A[s] * witness[s];
|
||||||
proof.pi_a = G1.add( proof.pi_a, G1.mulScalar( vk_proof.A[s], witness[s]));
|
proof.pi_a = G1.add( proof.pi_a, G1.timesScalar( vk_proof.A[s], witness[s]));
|
||||||
|
|
||||||
// pi_ap = pi_ap + Ap[s] * witness[s];
|
// pi_ap = pi_ap + Ap[s] * witness[s];
|
||||||
proof.pi_ap = G1.add( proof.pi_ap, G1.mulScalar( vk_proof.Ap[s], witness[s]));
|
proof.pi_ap = G1.add( proof.pi_ap, G1.timesScalar( vk_proof.Ap[s], witness[s]));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let s= 0; s< vk_proof.nVars; s++) {
|
for (let s= 0; s< vk_proof.nVars; s++) {
|
||||||
// pi_a = pi_a + A[s] * witness[s];
|
// pi_a = pi_a + A[s] * witness[s];
|
||||||
proof.pi_b = G2.add( proof.pi_b, G2.mulScalar( vk_proof.B[s], witness[s]));
|
proof.pi_b = G2.add( proof.pi_b, G2.timesScalar( vk_proof.B[s], witness[s]));
|
||||||
|
|
||||||
// pi_ap = pi_ap + Ap[s] * witness[s];
|
// pi_ap = pi_ap + Ap[s] * witness[s];
|
||||||
proof.pi_bp = G1.add( proof.pi_bp, G1.mulScalar( vk_proof.Bp[s], witness[s]));
|
proof.pi_bp = G1.add( proof.pi_bp, G1.timesScalar( vk_proof.Bp[s], witness[s]));
|
||||||
|
|
||||||
// pi_a = pi_a + A[s] * witness[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]));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesScalar( vk_proof.C[s], witness[s]));
|
||||||
|
|
||||||
// pi_ap = pi_ap + Ap[s] * witness[s];
|
// pi_ap = pi_ap + Ap[s] * witness[s];
|
||||||
proof.pi_cp = G1.add( proof.pi_cp, G1.mulScalar( vk_proof.Cp[s], witness[s]));
|
proof.pi_cp = G1.add( proof.pi_cp, G1.timesScalar( vk_proof.Cp[s], witness[s]));
|
||||||
|
|
||||||
// pi_ap = pi_ap + Ap[s] * witness[s];
|
// pi_ap = pi_ap + Ap[s] * witness[s];
|
||||||
proof.pi_kp = G1.add( proof.pi_kp, G1.mulScalar( vk_proof.Kp[s], witness[s]));
|
proof.pi_kp = G1.add( proof.pi_kp, G1.timesScalar( vk_proof.Kp[s], witness[s]));
|
||||||
}
|
}
|
||||||
|
|
||||||
proof.pi_a = G1.add( proof.pi_a, G1.mulScalar( vk_proof.A[vk_proof.nVars], d1));
|
proof.pi_a = G1.add( proof.pi_a, G1.timesScalar( vk_proof.A[vk_proof.nVars], d1));
|
||||||
proof.pi_ap = G1.add( proof.pi_ap, G1.mulScalar( vk_proof.Ap[vk_proof.nVars], d1));
|
proof.pi_ap = G1.add( proof.pi_ap, G1.timesScalar( vk_proof.Ap[vk_proof.nVars], d1));
|
||||||
|
|
||||||
proof.pi_b = G2.add( proof.pi_b, G2.mulScalar( vk_proof.B[vk_proof.nVars], d2));
|
proof.pi_b = G2.add( proof.pi_b, G2.timesScalar( vk_proof.B[vk_proof.nVars], d2));
|
||||||
proof.pi_bp = G1.add( proof.pi_bp, G1.mulScalar( vk_proof.Bp[vk_proof.nVars], d2));
|
proof.pi_bp = G1.add( proof.pi_bp, G1.timesScalar( vk_proof.Bp[vk_proof.nVars], d2));
|
||||||
|
|
||||||
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( vk_proof.C[vk_proof.nVars], d3));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesScalar( vk_proof.C[vk_proof.nVars], d3));
|
||||||
proof.pi_cp = G1.add( proof.pi_cp, G1.mulScalar( vk_proof.Cp[vk_proof.nVars], d3));
|
proof.pi_cp = G1.add( proof.pi_cp, G1.timesScalar( vk_proof.Cp[vk_proof.nVars], d3));
|
||||||
|
|
||||||
proof.pi_kp = G1.add( proof.pi_kp, G1.mulScalar( vk_proof.Kp[vk_proof.nVars ], d1));
|
proof.pi_kp = G1.add( proof.pi_kp, G1.timesScalar( vk_proof.Kp[vk_proof.nVars ], d1));
|
||||||
proof.pi_kp = G1.add( proof.pi_kp, G1.mulScalar( vk_proof.Kp[vk_proof.nVars+1], d2));
|
proof.pi_kp = G1.add( proof.pi_kp, G1.timesScalar( vk_proof.Kp[vk_proof.nVars+1], d2));
|
||||||
proof.pi_kp = G1.add( proof.pi_kp, G1.mulScalar( vk_proof.Kp[vk_proof.nVars+2], d3));
|
proof.pi_kp = G1.add( proof.pi_kp, G1.timesScalar( vk_proof.Kp[vk_proof.nVars+2], d3));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
let polA = [];
|
let polA = [];
|
||||||
@ -120,17 +120,17 @@ module.exports = function genProof(vk_proof, witness) {
|
|||||||
// console.log(h.length + "/" + vk_proof.hExps.length);
|
// console.log(h.length + "/" + vk_proof.hExps.length);
|
||||||
|
|
||||||
for (let i = 0; i < h.length; i++) {
|
for (let i = 0; i < h.length; i++) {
|
||||||
proof.pi_h = G1.add( proof.pi_h, G1.mulScalar( vk_proof.hExps[i], h[i]));
|
proof.pi_h = G1.add( proof.pi_h, G1.timesScalar( vk_proof.hExps[i], h[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
proof.pi_a = G1.affine(proof.pi_a);
|
proof.pi_a = G1.toAffine(proof.pi_a);
|
||||||
proof.pi_b = G2.affine(proof.pi_b);
|
proof.pi_b = G2.toAffine(proof.pi_b);
|
||||||
proof.pi_c = G1.affine(proof.pi_c);
|
proof.pi_c = G1.toAffine(proof.pi_c);
|
||||||
proof.pi_ap = G1.affine(proof.pi_ap);
|
proof.pi_ap = G1.toAffine(proof.pi_ap);
|
||||||
proof.pi_bp = G1.affine(proof.pi_bp);
|
proof.pi_bp = G1.toAffine(proof.pi_bp);
|
||||||
proof.pi_cp = G1.affine(proof.pi_cp);
|
proof.pi_cp = G1.toAffine(proof.pi_cp);
|
||||||
proof.pi_kp = G1.affine(proof.pi_kp);
|
proof.pi_kp = G1.toAffine(proof.pi_kp);
|
||||||
proof.pi_h = G1.affine(proof.pi_h);
|
proof.pi_h = G1.toAffine(proof.pi_h);
|
||||||
|
|
||||||
// proof.h=h;
|
// proof.h=h;
|
||||||
|
|
||||||
|
3
src/r1cs.js
Normal file
3
src/r1cs.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module.exports.print = require("./r1cs_print");
|
||||||
|
module.exports.info = require("./r1cs_info");
|
||||||
|
module.exports.exportJson = require("./r1cs_export_json");
|
14
src/r1cs_export_json.js
Normal file
14
src/r1cs_export_json.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
const {stringifyBigInts} = require("ffjavascript").utils;
|
||||||
|
const fs = require("fs");
|
||||||
|
const readZKey = require("./zkey_utils").read;
|
||||||
|
const loadR1cs = require("r1csfile").load;
|
||||||
|
|
||||||
|
module.exports = r1csExportJson;
|
||||||
|
|
||||||
|
async function r1csExportJson(r1csFileName, jsonFileName, verbose) {
|
||||||
|
|
||||||
|
const cir = await loadR1cs(r1csFileName, true, true);
|
||||||
|
|
||||||
|
const S = JSON.stringify(stringifyBigInts(cir), null, 1);
|
||||||
|
await fs.promises.writeFile(jsonFileName, S);
|
||||||
|
}
|
25
src/r1cs_info.js
Normal file
25
src/r1cs_info.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const loadR1cs = require("r1csfile").load;
|
||||||
|
module.exports = r1csInfo;
|
||||||
|
|
||||||
|
|
||||||
|
const bls12381r = Scalar.e("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", 16);
|
||||||
|
const bn128r = Scalar.e("21888242871839275222246405745257275088548364400416034343698204186575808495617", 16);
|
||||||
|
|
||||||
|
async function r1csInfo(r1csName) {
|
||||||
|
const cir = await loadR1cs(r1csName);
|
||||||
|
|
||||||
|
if (Scalar.eq(cir.prime, bn128r)) {
|
||||||
|
console.log("# Curve: bn-128");
|
||||||
|
} else if (Scalar.eq(cir.prime, bls12381r)) {
|
||||||
|
console.log("# Curve: bls12-381");
|
||||||
|
} else {
|
||||||
|
console.log(`# Unknown Curve. Prime: ${Scalar.toString(cir.r)}`);
|
||||||
|
}
|
||||||
|
console.log(`# Wires: ${cir.nVars}`);
|
||||||
|
console.log(`# Constraints: ${cir.nConstraints}`);
|
||||||
|
console.log(`# Private Inputs: ${cir.nPrvInputs}`);
|
||||||
|
console.log(`# Public Inputs: ${cir.nPubInputs}`);
|
||||||
|
console.log(`# Outputs: ${cir.nOutputs}`);
|
||||||
|
|
||||||
|
}
|
@ -1,12 +1,13 @@
|
|||||||
|
|
||||||
module.exports = function printR1cs(r1cs, syms) {
|
module.exports = function r1csPrint(r1cs, syms) {
|
||||||
for (let i=0; i<r1cs.constraints.length; i++) {
|
for (let i=0; i<r1cs.constraints.length; i++) {
|
||||||
printCostraint(r1cs.constraints[i]);
|
printCostraint(r1cs.constraints[i]);
|
||||||
}
|
}
|
||||||
function printCostraint(c) {
|
function printCostraint(c) {
|
||||||
const lc2str = (lc) => {
|
const lc2str = (lc) => {
|
||||||
let S = "";
|
let S = "";
|
||||||
for (let k in lc) {
|
const keys = Object.keys(lc);
|
||||||
|
keys.forEach( (k) => {
|
||||||
let name = syms.varIdx2Name[k];
|
let name = syms.varIdx2Name[k];
|
||||||
if (name == "one") name = "";
|
if (name == "one") name = "";
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ module.exports = function printR1cs(r1cs, syms) {
|
|||||||
if ((S!="")&&(vs[0]!="-")) vs = "+"+vs;
|
if ((S!="")&&(vs[0]!="-")) vs = "+"+vs;
|
||||||
if (S!="") vs = " "+vs;
|
if (S!="") vs = " "+vs;
|
||||||
S= S + vs + name;
|
S= S + vs + name;
|
||||||
}
|
});
|
||||||
return S;
|
return S;
|
||||||
};
|
};
|
||||||
const S = `[ ${lc2str(c[0])} ] * [ ${lc2str(c[1])} ] - [ ${lc2str(c[2])} ] = 0`;
|
const S = `[ ${lc2str(c[0])} ] * [ ${lc2str(c[1])} ] - [ ${lc2str(c[2])} ] = 0`;
|
@ -22,12 +22,12 @@
|
|||||||
const bn128 = require("ffjavascript").bn128;
|
const bn128 = require("ffjavascript").bn128;
|
||||||
const PolField = require("ffjavascript").PolField;
|
const PolField = require("ffjavascript").PolField;
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
/*
|
||||||
const G1 = bn128.G1;
|
const G1 = bn128.G1;
|
||||||
const G2 = bn128.G2;
|
const G2 = bn128.G2;
|
||||||
const PolF = new PolField(new ZqField(bn128.r));
|
const PolF = new PolField(new ZqField(bn128.r));
|
||||||
const F = new ZqField(bn128.r);
|
const F = new ZqField(bn128.r);
|
||||||
|
*/
|
||||||
module.exports = function setup(circuit, verbose) {
|
module.exports = function setup(circuit, verbose) {
|
||||||
const setup = {
|
const setup = {
|
||||||
vk_proof : {
|
vk_proof : {
|
||||||
@ -165,26 +165,26 @@ function calculateEncriptedValuesAtT(setup, circuit, verbose) {
|
|||||||
let invDelta = F.inv(setup.toxic.kdelta);
|
let invDelta = F.inv(setup.toxic.kdelta);
|
||||||
let invGamma = F.inv(setup.toxic.kgamma);
|
let invGamma = F.inv(setup.toxic.kgamma);
|
||||||
|
|
||||||
setup.vk_proof.vk_alpha_1 = G1.affine(G1.mulScalar( G1.g, setup.toxic.kalpha));
|
setup.vk_proof.vk_alpha_1 = G1.toAffine(G1.timesScalar( G1.g, setup.toxic.kalpha));
|
||||||
setup.vk_proof.vk_beta_1 = G1.affine(G1.mulScalar( G1.g, setup.toxic.kbeta));
|
setup.vk_proof.vk_beta_1 = G1.toAffine(G1.timesScalar( G1.g, setup.toxic.kbeta));
|
||||||
setup.vk_proof.vk_delta_1 = G1.affine(G1.mulScalar( G1.g, setup.toxic.kdelta));
|
setup.vk_proof.vk_delta_1 = G1.toAffine(G1.timesScalar( G1.g, setup.toxic.kdelta));
|
||||||
|
|
||||||
setup.vk_proof.vk_beta_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kbeta));
|
setup.vk_proof.vk_beta_2 = G2.toAffine(G2.timesScalar( G2.g, setup.toxic.kbeta));
|
||||||
setup.vk_proof.vk_delta_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kdelta));
|
setup.vk_proof.vk_delta_2 = G2.toAffine(G2.timesScalar( G2.g, setup.toxic.kdelta));
|
||||||
setup.vk_proof.vk_gamma_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kgamma));
|
setup.vk_proof.vk_gamma_2 = G2.toAffine(G2.timesScalar( G2.g, setup.toxic.kgamma));
|
||||||
|
|
||||||
|
|
||||||
for (let s=0; s<circuit.nVars; s++) {
|
for (let s=0; s<circuit.nVars; s++) {
|
||||||
|
|
||||||
const A = G1.mulScalar(G1.g, v.a_t[s]);
|
const A = G1.timesScalar(G1.g, v.a_t[s]);
|
||||||
|
|
||||||
setup.vk_proof.A[s] = A;
|
setup.vk_proof.A[s] = A;
|
||||||
|
|
||||||
const B1 = G1.mulScalar(G1.g, v.b_t[s]);
|
const B1 = G1.timesScalar(G1.g, v.b_t[s]);
|
||||||
|
|
||||||
setup.vk_proof.B1[s] = B1;
|
setup.vk_proof.B1[s] = B1;
|
||||||
|
|
||||||
const B2 = G2.mulScalar(G2.g, v.b_t[s]);
|
const B2 = G2.timesScalar(G2.g, v.b_t[s]);
|
||||||
|
|
||||||
setup.vk_proof.B2[s] = B2;
|
setup.vk_proof.B2[s] = B2;
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ function calculateEncriptedValuesAtT(setup, circuit, verbose) {
|
|||||||
F.mul(v.b_t[s], setup.toxic.kalpha)),
|
F.mul(v.b_t[s], setup.toxic.kalpha)),
|
||||||
v.c_t[s]));
|
v.c_t[s]));
|
||||||
|
|
||||||
const IC = G1.mulScalar(G1.g, ps);
|
const IC = G1.timesScalar(G1.g, ps);
|
||||||
setup.vk_proof.IC[s]=IC;
|
setup.vk_proof.IC[s]=IC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ function calculateEncriptedValuesAtT(setup, circuit, verbose) {
|
|||||||
F.mul(v.a_t[s], setup.toxic.kbeta),
|
F.mul(v.a_t[s], setup.toxic.kbeta),
|
||||||
F.mul(v.b_t[s], setup.toxic.kalpha)),
|
F.mul(v.b_t[s], setup.toxic.kalpha)),
|
||||||
v.c_t[s]));
|
v.c_t[s]));
|
||||||
const C = G1.mulScalar(G1.g, ps);
|
const C = G1.timesScalar(G1.g, ps);
|
||||||
setup.vk_proof.C[s]=C;
|
setup.vk_proof.C[s]=C;
|
||||||
|
|
||||||
if ((verbose)&&(s%1000 == 1)) console.log("C: ", s);
|
if ((verbose)&&(s%1000 == 1)) console.log("C: ", s);
|
||||||
@ -230,10 +230,10 @@ function calculateEncriptedValuesAtT(setup, circuit, verbose) {
|
|||||||
|
|
||||||
const zod = F.mul(invDelta, v.z_t);
|
const zod = F.mul(invDelta, v.z_t);
|
||||||
|
|
||||||
setup.vk_proof.hExps[0] = G1.affine(G1.mulScalar(G1.g, zod));
|
setup.vk_proof.hExps[0] = G1.toAffine(G1.timesScalar(G1.g, zod));
|
||||||
let eT = setup.toxic.t;
|
let eT = setup.toxic.t;
|
||||||
for (let i=1; i<maxH; i++) {
|
for (let i=1; i<maxH; i++) {
|
||||||
setup.vk_proof.hExps[i] = G1.mulScalar(G1.g, F.mul(eT, zod));
|
setup.vk_proof.hExps[i] = G1.timesScalar(G1.g, F.mul(eT, zod));
|
||||||
eT = F.mul(eT, setup.toxic.t);
|
eT = F.mul(eT, setup.toxic.t);
|
||||||
|
|
||||||
if ((verbose)&&(i%1000 == 1)) console.log("Tau: ", i);
|
if ((verbose)&&(i%1000 == 1)) console.log("Tau: ", i);
|
||||||
|
@ -24,12 +24,12 @@ const bigInt = require("big-integer");
|
|||||||
const bn128 = require("ffjavascript").bn128;
|
const bn128 = require("ffjavascript").bn128;
|
||||||
const PolField = require("ffjavascript").PolField;
|
const PolField = require("ffjavascript").PolField;
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
/*
|
||||||
const G1 = bn128.G1;
|
const G1 = bn128.G1;
|
||||||
const G2 = bn128.G2;
|
const G2 = bn128.G2;
|
||||||
const PolF = new PolField(new ZqField(bn128.r));
|
const PolF = new PolField(new ZqField(bn128.r));
|
||||||
const F = new ZqField(bn128.r);
|
const F = new ZqField(bn128.r);
|
||||||
|
*/
|
||||||
module.exports = function setup(circuit) {
|
module.exports = function setup(circuit) {
|
||||||
const setup = {
|
const setup = {
|
||||||
vk_proof : {
|
vk_proof : {
|
||||||
@ -135,34 +135,34 @@ function calculateEncriptedValuesAtT(setup, circuit) {
|
|||||||
|
|
||||||
const gammaSquare = F.mul(setup.toxic.kgamma, setup.toxic.kgamma);
|
const gammaSquare = F.mul(setup.toxic.kgamma, setup.toxic.kgamma);
|
||||||
|
|
||||||
setup.vk_proof.vk_alpha_1 = G1.affine(G1.mulScalar( G1.g, setup.toxic.kalpha));
|
setup.vk_proof.vk_alpha_1 = G1.toAffine(G1.timesScalar( G1.g, setup.toxic.kalpha));
|
||||||
setup.vk_proof.vk_beta_1 = G1.affine(G1.mulScalar( G1.g, setup.toxic.kbeta));
|
setup.vk_proof.vk_beta_1 = G1.toAffine(G1.timesScalar( G1.g, setup.toxic.kbeta));
|
||||||
setup.vk_proof.vk_delta_1 = G1.affine(G1.mulScalar( G1.g, setup.toxic.kdelta));
|
setup.vk_proof.vk_delta_1 = G1.toAffine(G1.timesScalar( G1.g, setup.toxic.kdelta));
|
||||||
setup.vk_proof.vk_alphadelta_1 = G1.affine(G1.mulScalar( G1.g, F.mul(setup.toxic.kalpha, setup.toxic.kdelta)));
|
setup.vk_proof.vk_alphadelta_1 = G1.toAffine(G1.timesScalar( G1.g, F.mul(setup.toxic.kalpha, setup.toxic.kdelta)));
|
||||||
|
|
||||||
setup.vk_proof.vk_beta_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kbeta));
|
setup.vk_proof.vk_beta_2 = G2.toAffine(G2.timesScalar( G2.g, setup.toxic.kbeta));
|
||||||
|
|
||||||
|
|
||||||
setup.vk_verifier.vk_alpha_1 = G1.affine(G1.mulScalar( G1.g, setup.toxic.kalpha));
|
setup.vk_verifier.vk_alpha_1 = G1.toAffine(G1.timesScalar( G1.g, setup.toxic.kalpha));
|
||||||
|
|
||||||
setup.vk_verifier.vk_beta_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kbeta));
|
setup.vk_verifier.vk_beta_2 = G2.toAffine(G2.timesScalar( G2.g, setup.toxic.kbeta));
|
||||||
setup.vk_verifier.vk_gamma_2 = G2.affine(G2.mulScalar( G2.g, setup.toxic.kgamma));
|
setup.vk_verifier.vk_gamma_2 = G2.toAffine(G2.timesScalar( 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.toAffine(G2.timesScalar( G2.g, setup.toxic.kdelta));
|
||||||
|
|
||||||
setup.vk_verifier.vk_alphabeta_12 = bn128.pairing( setup.vk_verifier.vk_alpha_1 , setup.vk_verifier.vk_beta_2 );
|
setup.vk_verifier.vk_alphabeta_12 = bn128.pairing( setup.vk_verifier.vk_alpha_1 , setup.vk_verifier.vk_beta_2 );
|
||||||
|
|
||||||
for (let s=0; s<circuit.nVars; s++) {
|
for (let s=0; s<circuit.nVars; s++) {
|
||||||
|
|
||||||
const A = G1.affine(G1.mulScalar(G1.g, F.mul(setup.toxic.kgamma, v.a_t[s])));
|
const A = G1.toAffine(G1.timesScalar(G1.g, F.mul(setup.toxic.kgamma, v.a_t[s])));
|
||||||
|
|
||||||
setup.vk_proof.A[s] = A;
|
setup.vk_proof.A[s] = A;
|
||||||
setup.vk_proof.Adelta[s] = G1.affine(G1.mulScalar(A, setup.toxic.kdelta));
|
setup.vk_proof.Adelta[s] = G1.toAffine(G1.timesScalar(A, setup.toxic.kdelta));
|
||||||
|
|
||||||
const B1 = G1.affine(G1.mulScalar(G1.g, F.mul(setup.toxic.kgamma, v.b_t[s])));
|
const B1 = G1.toAffine(G1.timesScalar(G1.g, F.mul(setup.toxic.kgamma, v.b_t[s])));
|
||||||
|
|
||||||
setup.vk_proof.B1[s] = B1;
|
setup.vk_proof.B1[s] = B1;
|
||||||
|
|
||||||
const B2 = G2.affine(G2.mulScalar(G2.g, F.mul(setup.toxic.kgamma, v.b_t[s])));
|
const B2 = G2.toAffine(G2.timesScalar(G2.g, F.mul(setup.toxic.kgamma, v.b_t[s])));
|
||||||
|
|
||||||
setup.vk_proof.B2[s] = B2;
|
setup.vk_proof.B2[s] = B2;
|
||||||
}
|
}
|
||||||
@ -187,7 +187,7 @@ function calculateEncriptedValuesAtT(setup, circuit) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const IC = G1.affine(G1.mulScalar(G1.g, ps));
|
const IC = G1.toAffine(G1.timesScalar(G1.g, ps));
|
||||||
setup.vk_verifier.IC[s]=IC;
|
setup.vk_verifier.IC[s]=IC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ function calculateEncriptedValuesAtT(setup, circuit) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const C = G1.affine(G1.mulScalar(G1.g, ps));
|
const C = G1.toAffine(G1.timesScalar(G1.g, ps));
|
||||||
setup.vk_proof.C[s]=C;
|
setup.vk_proof.C[s]=C;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,10 +222,10 @@ function calculateEncriptedValuesAtT(setup, circuit) {
|
|||||||
|
|
||||||
const zod = F.mul(gammaSquare, v.z_t);
|
const zod = F.mul(gammaSquare, v.z_t);
|
||||||
|
|
||||||
setup.vk_proof.hExps[0] = G1.affine(G1.mulScalar(G1.g, zod));
|
setup.vk_proof.hExps[0] = G1.toAffine(G1.timesScalar(G1.g, zod));
|
||||||
let eT = setup.toxic.t;
|
let eT = setup.toxic.t;
|
||||||
for (let i=1; i<maxH; i++) {
|
for (let i=1; i<maxH; i++) {
|
||||||
setup.vk_proof.hExps[i] = G1.affine(G1.mulScalar(G1.g, F.mul(eT, zod)));
|
setup.vk_proof.hExps[i] = G1.toAffine(G1.timesScalar(G1.g, F.mul(eT, zod)));
|
||||||
eT = F.mul(eT, setup.toxic.t);
|
eT = F.mul(eT, setup.toxic.t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,12 @@
|
|||||||
const bn128 = require("ffjavascript").bn128;
|
const bn128 = require("ffjavascript").bn128;
|
||||||
const PolField = require("ffjavascript").PolField;
|
const PolField = require("ffjavascript").PolField;
|
||||||
const ZqField = require("ffjavascript").F1Field;
|
const ZqField = require("ffjavascript").F1Field;
|
||||||
|
/*
|
||||||
const G1 = bn128.G1;
|
const G1 = bn128.G1;
|
||||||
const G2 = bn128.G2;
|
const G2 = bn128.G2;
|
||||||
const PolF = new PolField(new ZqField(bn128.r));
|
const PolF = new PolField(new ZqField(bn128.r));
|
||||||
const F = new ZqField(bn128.r);
|
const F = new ZqField(bn128.r);
|
||||||
|
*/
|
||||||
module.exports = function setup(circuit) {
|
module.exports = function setup(circuit) {
|
||||||
const setup = {
|
const setup = {
|
||||||
vk_proof : {
|
vk_proof : {
|
||||||
@ -139,18 +139,18 @@ function calculateEncriptedValuesAtT(setup, circuit) {
|
|||||||
|
|
||||||
const gb = F.mul(setup.toxic.kbeta, setup.toxic.kgamma);
|
const gb = F.mul(setup.toxic.kbeta, setup.toxic.kgamma);
|
||||||
|
|
||||||
setup.vk_verifier.vk_a = G2.affine(G2.mulScalar( G2.g, setup.toxic.ka));
|
setup.vk_verifier.vk_a = G2.toAffine(G2.timesScalar( G2.g, setup.toxic.ka));
|
||||||
setup.vk_verifier.vk_b = G1.affine(G1.mulScalar( G1.g, setup.toxic.kb));
|
setup.vk_verifier.vk_b = G1.toAffine(G1.timesScalar( G1.g, setup.toxic.kb));
|
||||||
setup.vk_verifier.vk_c = G2.affine(G2.mulScalar( G2.g, setup.toxic.kc));
|
setup.vk_verifier.vk_c = G2.toAffine(G2.timesScalar( G2.g, setup.toxic.kc));
|
||||||
setup.vk_verifier.vk_gb_1 = G1.affine(G1.mulScalar( G1.g, gb));
|
setup.vk_verifier.vk_gb_1 = G1.toAffine(G1.timesScalar( G1.g, gb));
|
||||||
setup.vk_verifier.vk_gb_2 = G2.affine(G2.mulScalar( G2.g, gb));
|
setup.vk_verifier.vk_gb_2 = G2.toAffine(G2.timesScalar( G2.g, gb));
|
||||||
setup.vk_verifier.vk_g = G2.affine(G2.mulScalar( G2.g, setup.toxic.kgamma));
|
setup.vk_verifier.vk_g = G2.toAffine(G2.timesScalar( G2.g, setup.toxic.kgamma));
|
||||||
|
|
||||||
for (let s=0; s<circuit.nVars; s++) {
|
for (let s=0; s<circuit.nVars; s++) {
|
||||||
|
|
||||||
// A[i] = G1 * polA(t)
|
// A[i] = G1 * polA(t)
|
||||||
const raat = F.mul(setup.toxic.ra, v.a_t[s]);
|
const raat = F.mul(setup.toxic.ra, v.a_t[s]);
|
||||||
const A = G1.affine(G1.mulScalar(G1.g, raat));
|
const A = G1.toAffine(G1.timesScalar(G1.g, raat));
|
||||||
|
|
||||||
setup.vk_proof.A[s] = A;
|
setup.vk_proof.A[s] = A;
|
||||||
|
|
||||||
@ -161,26 +161,26 @@ function calculateEncriptedValuesAtT(setup, circuit) {
|
|||||||
|
|
||||||
// B1[i] = G1 * polB(t)
|
// B1[i] = G1 * polB(t)
|
||||||
const rbbt = F.mul(setup.toxic.rb, v.b_t[s]);
|
const rbbt = F.mul(setup.toxic.rb, v.b_t[s]);
|
||||||
const B1 = G1.affine(G1.mulScalar(G1.g, rbbt));
|
const B1 = G1.toAffine(G1.timesScalar(G1.g, rbbt));
|
||||||
|
|
||||||
// B2[i] = G2 * polB(t)
|
// B2[i] = G2 * polB(t)
|
||||||
const B2 = G2.affine(G2.mulScalar(G2.g, rbbt));
|
const B2 = G2.toAffine(G2.timesScalar(G2.g, rbbt));
|
||||||
|
|
||||||
setup.vk_proof.B[s]=B2;
|
setup.vk_proof.B[s]=B2;
|
||||||
|
|
||||||
// C[i] = G1 * polC(t)
|
// C[i] = G1 * polC(t)
|
||||||
const rcct = F.mul(setup.toxic.rc, v.c_t[s]);
|
const rcct = F.mul(setup.toxic.rc, v.c_t[s]);
|
||||||
const C = G1.affine(G1.mulScalar( G1.g, rcct));
|
const C = G1.toAffine(G1.timesScalar( G1.g, rcct));
|
||||||
setup.vk_proof.C[s] =C;
|
setup.vk_proof.C[s] =C;
|
||||||
|
|
||||||
// K = G1 * (A+B+C)
|
// K = G1 * (A+B+C)
|
||||||
|
|
||||||
const kt = 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.toAffine(G1.timesScalar( G1.g, kt));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Comment this lines to improve the process
|
// Comment this lines to improve the process
|
||||||
const Ktest = G1.affine(G1.add(G1.add(A, B1), C));
|
const Ktest = G1.toAffine(G1.add(G1.add(A, B1), C));
|
||||||
|
|
||||||
if (!G1.equals(K, Ktest)) {
|
if (!G1.equals(K, Ktest)) {
|
||||||
console.log ("=====FAIL======");
|
console.log ("=====FAIL======");
|
||||||
@ -188,35 +188,35 @@ function calculateEncriptedValuesAtT(setup, circuit) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (s > setup.vk_proof.nPublic) {
|
if (s > setup.vk_proof.nPublic) {
|
||||||
setup.vk_proof.Ap[s] = G1.affine(G1.mulScalar(A, setup.toxic.ka));
|
setup.vk_proof.Ap[s] = G1.toAffine(G1.timesScalar(A, setup.toxic.ka));
|
||||||
}
|
}
|
||||||
setup.vk_proof.Bp[s] = G1.affine(G1.mulScalar(B1, setup.toxic.kb));
|
setup.vk_proof.Bp[s] = G1.toAffine(G1.timesScalar(B1, setup.toxic.kb));
|
||||||
setup.vk_proof.Cp[s] = G1.affine(G1.mulScalar(C, setup.toxic.kc));
|
setup.vk_proof.Cp[s] = G1.toAffine(G1.timesScalar(C, setup.toxic.kc));
|
||||||
setup.vk_proof.Kp[s] = G1.affine(G1.mulScalar(K, setup.toxic.kbeta));
|
setup.vk_proof.Kp[s] = G1.toAffine(G1.timesScalar(K, setup.toxic.kbeta));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extra coeficients
|
// Extra coeficients
|
||||||
const A = G1.mulScalar( G1.g, F.mul(setup.toxic.ra, v.z_t));
|
const A = G1.timesScalar( G1.g, F.mul(setup.toxic.ra, v.z_t));
|
||||||
setup.vk_proof.A[circuit.nVars] = G1.affine(A);
|
setup.vk_proof.A[circuit.nVars] = G1.toAffine(A);
|
||||||
setup.vk_proof.Ap[circuit.nVars] = G1.affine(G1.mulScalar(A, setup.toxic.ka));
|
setup.vk_proof.Ap[circuit.nVars] = G1.toAffine(G1.timesScalar(A, setup.toxic.ka));
|
||||||
|
|
||||||
const B1 = G1.mulScalar( G1.g, F.mul(setup.toxic.rb, v.z_t));
|
const B1 = G1.timesScalar( G1.g, F.mul(setup.toxic.rb, v.z_t));
|
||||||
const B2 = G2.mulScalar( G2.g, F.mul(setup.toxic.rb, v.z_t));
|
const B2 = G2.timesScalar( G2.g, F.mul(setup.toxic.rb, v.z_t));
|
||||||
setup.vk_proof.B[circuit.nVars] = G2.affine(B2);
|
setup.vk_proof.B[circuit.nVars] = G2.toAffine(B2);
|
||||||
setup.vk_proof.Bp[circuit.nVars] = G1.affine(G1.mulScalar(B1, setup.toxic.kb));
|
setup.vk_proof.Bp[circuit.nVars] = G1.toAffine(G1.timesScalar(B1, setup.toxic.kb));
|
||||||
|
|
||||||
const C = G1.mulScalar( G1.g, F.mul(setup.toxic.rc, v.z_t));
|
const C = G1.timesScalar( G1.g, F.mul(setup.toxic.rc, v.z_t));
|
||||||
setup.vk_proof.C[circuit.nVars] = G1.affine(C);
|
setup.vk_proof.C[circuit.nVars] = G1.toAffine(C);
|
||||||
setup.vk_proof.Cp[circuit.nVars] = G1.affine(G1.mulScalar(C, setup.toxic.kc));
|
setup.vk_proof.Cp[circuit.nVars] = G1.toAffine(G1.timesScalar(C, setup.toxic.kc));
|
||||||
|
|
||||||
setup.vk_proof.Kp[circuit.nVars ] = G1.affine(G1.mulScalar(A, setup.toxic.kbeta));
|
setup.vk_proof.Kp[circuit.nVars ] = G1.toAffine(G1.timesScalar(A, setup.toxic.kbeta));
|
||||||
setup.vk_proof.Kp[circuit.nVars+1] = G1.affine(G1.mulScalar(B1, setup.toxic.kbeta));
|
setup.vk_proof.Kp[circuit.nVars+1] = G1.toAffine(G1.timesScalar(B1, setup.toxic.kbeta));
|
||||||
setup.vk_proof.Kp[circuit.nVars+2] = G1.affine(G1.mulScalar(C, setup.toxic.kbeta));
|
setup.vk_proof.Kp[circuit.nVars+2] = G1.toAffine(G1.timesScalar(C, setup.toxic.kbeta));
|
||||||
|
|
||||||
// setup.vk_verifier.A[0] = G1.affine(G1.add(setup.vk_verifier.A[0], setup.vk_proof.A[circuit.nVars]));
|
// setup.vk_verifier.A[0] = G1.toAffine(G1.add(setup.vk_verifier.A[0], setup.vk_proof.A[circuit.nVars]));
|
||||||
|
|
||||||
// vk_z
|
// vk_z
|
||||||
setup.vk_verifier.vk_z = G2.affine(G2.mulScalar(
|
setup.vk_verifier.vk_z = G2.toAffine(G2.timesScalar(
|
||||||
G2.g,
|
G2.g,
|
||||||
F.mul(setup.toxic.rc, v.z_t)));
|
F.mul(setup.toxic.rc, v.z_t)));
|
||||||
}
|
}
|
||||||
@ -229,7 +229,7 @@ function calculateHexps(setup) {
|
|||||||
setup.vk_proof.hExps[0] = G1.g;
|
setup.vk_proof.hExps[0] = G1.g;
|
||||||
let eT = setup.toxic.t;
|
let eT = setup.toxic.t;
|
||||||
for (let i=1; i<maxH; i++) {
|
for (let i=1; i<maxH; i++) {
|
||||||
setup.vk_proof.hExps[i] = G1.affine(G1.mulScalar(G1.g, eT));
|
setup.vk_proof.hExps[i] = G1.toAffine(G1.timesScalar(G1.g, eT));
|
||||||
eT = F.mul(eT, setup.toxic.t);
|
eT = F.mul(eT, setup.toxic.t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,14 @@
|
|||||||
|
|
||||||
|
|
||||||
const bn128 = require("ffjavascript").bn128;
|
const bn128 = require("ffjavascript").bn128;
|
||||||
|
/*
|
||||||
const G1 = bn128.G1;
|
const G1 = bn128.G1;
|
||||||
|
*/
|
||||||
module.exports = function isValid(vk_verifier, proof, publicSignals) {
|
module.exports = function isValid(vk_verifier, proof, publicSignals) {
|
||||||
|
|
||||||
let cpub = vk_verifier.IC[0];
|
let cpub = vk_verifier.IC[0];
|
||||||
for (let s= 0; s< vk_verifier.nPublic; s++) {
|
for (let s= 0; s< vk_verifier.nPublic; s++) {
|
||||||
cpub = G1.add( cpub, G1.mulScalar( vk_verifier.IC[s+1], publicSignals[s]));
|
cpub = G1.add( cpub, G1.timesScalar( vk_verifier.IC[s+1], publicSignals[s]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! bn128.F12.eq(
|
if (! bn128.F12.eq(
|
||||||
|
@ -24,14 +24,15 @@ const bn128 = require("ffjavascript").bn128;
|
|||||||
const createKeccakHash = require("keccak");
|
const createKeccakHash = require("keccak");
|
||||||
const utils = require("ffjavascript").utils;
|
const utils = require("ffjavascript").utils;
|
||||||
|
|
||||||
|
/*
|
||||||
const G1 = bn128.G1;
|
const G1 = bn128.G1;
|
||||||
const G2 = bn128.G2;
|
const G2 = bn128.G2;
|
||||||
|
*/
|
||||||
module.exports = function isValid(vk_verifier, proof, publicSignals) {
|
module.exports = function isValid(vk_verifier, proof, publicSignals) {
|
||||||
|
|
||||||
let cpub = vk_verifier.IC[0];
|
let cpub = vk_verifier.IC[0];
|
||||||
for (let s= 0; s< vk_verifier.nPublic; s++) {
|
for (let s= 0; s< vk_verifier.nPublic; s++) {
|
||||||
cpub = G1.add( cpub, G1.mulScalar( vk_verifier.IC[s+1], publicSignals[s]));
|
cpub = G1.add( cpub, G1.timesScalar( vk_verifier.IC[s+1], publicSignals[s]));
|
||||||
}
|
}
|
||||||
|
|
||||||
const buff = Buffer.concat([
|
const buff = Buffer.concat([
|
||||||
@ -59,8 +60,8 @@ module.exports = function isValid(vk_verifier, proof, publicSignals) {
|
|||||||
|
|
||||||
if (! bn128.F12.eq(
|
if (! bn128.F12.eq(
|
||||||
bn128.pairing(
|
bn128.pairing(
|
||||||
G1.add(proof.pi_a, G1.mulScalar(G1.g, h1)),
|
G1.add(proof.pi_a, G1.timesScalar(G1.g, h1)),
|
||||||
G2.add(proof.pi_b, G2.mulScalar(vk_verifier.vk_delta_2, h2))
|
G2.add(proof.pi_b, G2.timesScalar(vk_verifier.vk_delta_2, h2))
|
||||||
),
|
),
|
||||||
bn128.F12.mul(
|
bn128.F12.mul(
|
||||||
vk_verifier.vk_alphabeta_12,
|
vk_verifier.vk_alphabeta_12,
|
||||||
|
@ -18,15 +18,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const bn128 = require("ffjavascript").bn128;
|
const bn128 = require("ffjavascript").bn128;
|
||||||
|
/*
|
||||||
const G1 = bn128.G1;
|
const G1 = bn128.G1;
|
||||||
const G2 = bn128.G2;
|
const G2 = bn128.G2;
|
||||||
|
*/
|
||||||
module.exports = function isValid(vk_verifier, proof, publicSignals) {
|
module.exports = function isValid(vk_verifier, proof, publicSignals) {
|
||||||
|
|
||||||
let full_pi_a = vk_verifier.IC[0];
|
let full_pi_a = vk_verifier.IC[0];
|
||||||
for (let s= 0; s< vk_verifier.nPublic; s++) {
|
for (let s= 0; s< vk_verifier.nPublic; s++) {
|
||||||
full_pi_a = G1.add( full_pi_a, G1.mulScalar( vk_verifier.IC[s+1], publicSignals[s]));
|
full_pi_a = G1.add( full_pi_a, G1.timesScalar( vk_verifier.IC[s+1], publicSignals[s]));
|
||||||
}
|
}
|
||||||
|
|
||||||
full_pi_a = G1.add( full_pi_a, proof.pi_a);
|
full_pi_a = G1.add( full_pi_a, proof.pi_a);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
module.exports.new = require("./zkey_new.js");
|
module.exports.new = require("./zkey_new.js");
|
||||||
module.exports.exportBellman = require("./zkey_export_bellman.js");
|
module.exports.exportBellman = require("./zkey_export_bellman.js");
|
||||||
module.exports.importBellman = require("./zkey_import_bellman.js");
|
module.exports.importBellman = require("./zkey_import_bellman.js");
|
||||||
@ -9,3 +8,4 @@ module.exports.beacon = require("./zkey_beacon.js");
|
|||||||
module.exports.exportJson = require("./zkey_export_json.js");
|
module.exports.exportJson = require("./zkey_export_json.js");
|
||||||
module.exports.utils = require("./zkey_utils.js");
|
module.exports.utils = require("./zkey_utils.js");
|
||||||
module.exports.challangeContribute = require("./zkey_challangecontribute.js");
|
module.exports.challangeContribute = require("./zkey_challangecontribute.js");
|
||||||
|
module.exports.exportVerificationKey = require("./zkey_export_verificationkey.js");
|
||||||
|
@ -51,16 +51,16 @@ module.exports = async function beacon(zkeyNameOld, zkeyNameNew, name, numIterat
|
|||||||
const curContribution = {};
|
const curContribution = {};
|
||||||
curContribution.delta = {};
|
curContribution.delta = {};
|
||||||
curContribution.delta.prvKey = curve.Fr.fromRng(rng);
|
curContribution.delta.prvKey = curve.Fr.fromRng(rng);
|
||||||
curContribution.delta.g1_s = curve.G1.affine(curve.G1.fromRng(rng));
|
curContribution.delta.g1_s = curve.G1.toAffine(curve.G1.fromRng(rng));
|
||||||
curContribution.delta.g1_sx = curve.G1.affine(curve.G1.mulScalar(curContribution.delta.g1_s, curContribution.delta.prvKey));
|
curContribution.delta.g1_sx = curve.G1.toAffine(curve.G1.timesScalar(curContribution.delta.g1_s, curContribution.delta.prvKey));
|
||||||
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_s);
|
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_s);
|
||||||
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_sx);
|
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_sx);
|
||||||
curContribution.transcript = transcriptHasher.digest();
|
curContribution.transcript = transcriptHasher.digest();
|
||||||
curContribution.delta.g2_sp = hashToG2(curContribution.transcript);
|
curContribution.delta.g2_sp = hashToG2(curve, curContribution.transcript);
|
||||||
curContribution.delta.g2_spx = curve.G2.affine(curve.G2.mulScalar(curContribution.delta.g2_sp, curContribution.delta.prvKey));
|
curContribution.delta.g2_spx = curve.G2.toAffine(curve.G2.timesScalar(curContribution.delta.g2_sp, curContribution.delta.prvKey));
|
||||||
|
|
||||||
zkey.vk_delta_1 = curve.G1.mulScalar(zkey.vk_delta_1, curContribution.delta.prvKey);
|
zkey.vk_delta_1 = curve.G1.timesScalar(zkey.vk_delta_1, curContribution.delta.prvKey);
|
||||||
zkey.vk_delta_2 = curve.G2.mulScalar(zkey.vk_delta_2, curContribution.delta.prvKey);
|
zkey.vk_delta_2 = curve.G2.timesScalar(zkey.vk_delta_2, curContribution.delta.prvKey);
|
||||||
|
|
||||||
curContribution.deltaAfter = zkey.vk_delta_1;
|
curContribution.deltaAfter = zkey.vk_delta_1;
|
||||||
|
|
||||||
|
@ -44,10 +44,10 @@ async function challangeContribute(curve, challangeFilename, responesFileName, e
|
|||||||
await copy(sG2); // beta2
|
await copy(sG2); // beta2
|
||||||
await copy(sG2); // gamma2
|
await copy(sG2); // gamma2
|
||||||
const oldDelta1 = await readG1();
|
const oldDelta1 = await readG1();
|
||||||
const delta1 = curve.G1.mulScalar(oldDelta1, delta);
|
const delta1 = curve.G1.timesScalar(oldDelta1, delta);
|
||||||
await writeG1(delta1);
|
await writeG1(delta1);
|
||||||
const oldDelta2 = await readG2();
|
const oldDelta2 = await readG2();
|
||||||
const delta2 = curve.G2.mulScalar(oldDelta2, delta);
|
const delta2 = curve.G2.timesScalar(oldDelta2, delta);
|
||||||
await writeG2(delta2);
|
await writeG2(delta2);
|
||||||
|
|
||||||
// IC
|
// IC
|
||||||
@ -107,13 +107,13 @@ async function challangeContribute(curve, challangeFilename, responesFileName, e
|
|||||||
const curContribution = {};
|
const curContribution = {};
|
||||||
curContribution.delta = {};
|
curContribution.delta = {};
|
||||||
curContribution.delta.prvKey = delta;
|
curContribution.delta.prvKey = delta;
|
||||||
curContribution.delta.g1_s = curve.G1.affine(curve.G1.fromRng(rng));
|
curContribution.delta.g1_s = curve.G1.toAffine(curve.G1.fromRng(rng));
|
||||||
curContribution.delta.g1_sx = curve.G1.affine(curve.G1.mulScalar(curContribution.delta.g1_s, delta));
|
curContribution.delta.g1_sx = curve.G1.toAffine(curve.G1.timesScalar(curContribution.delta.g1_s, delta));
|
||||||
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_s);
|
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_s);
|
||||||
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_sx);
|
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_sx);
|
||||||
curContribution.transcript = transcriptHasher.digest();
|
curContribution.transcript = transcriptHasher.digest();
|
||||||
curContribution.delta.g2_sp = hashToG2(curContribution.transcript);
|
curContribution.delta.g2_sp = hashToG2(curve, curContribution.transcript);
|
||||||
curContribution.delta.g2_spx = curve.G2.affine(curve.G2.mulScalar(curContribution.delta.g2_sp, delta));
|
curContribution.delta.g2_spx = curve.G2.toAffine(curve.G2.timesScalar(curContribution.delta.g2_sp, delta));
|
||||||
curContribution.deltaAfter = delta1;
|
curContribution.deltaAfter = delta1;
|
||||||
curContribution.type = 0;
|
curContribution.type = 0;
|
||||||
mpcParams.contributions.push(curContribution);
|
mpcParams.contributions.push(curContribution);
|
||||||
|
@ -25,6 +25,7 @@ module.exports = async function phase2contribute(zkeyNameOld, zkeyNameNew, name
|
|||||||
const rng = await misc.getRandomRng(entropy);
|
const rng = await misc.getRandomRng(entropy);
|
||||||
|
|
||||||
const transcriptHasher = Blake2b(64);
|
const transcriptHasher = Blake2b(64);
|
||||||
|
transcriptHasher.update(mpcParams.csHash);
|
||||||
for (let i=0; i<mpcParams.contributions.length; i++) {
|
for (let i=0; i<mpcParams.contributions.length; i++) {
|
||||||
utils.hashPubKey(transcriptHasher, curve, mpcParams.contributions[i]);
|
utils.hashPubKey(transcriptHasher, curve, mpcParams.contributions[i]);
|
||||||
}
|
}
|
||||||
@ -32,16 +33,16 @@ module.exports = async function phase2contribute(zkeyNameOld, zkeyNameNew, name
|
|||||||
const curContribution = {};
|
const curContribution = {};
|
||||||
curContribution.delta = {};
|
curContribution.delta = {};
|
||||||
curContribution.delta.prvKey = curve.Fr.fromRng(rng);
|
curContribution.delta.prvKey = curve.Fr.fromRng(rng);
|
||||||
curContribution.delta.g1_s = curve.G1.affine(curve.G1.fromRng(rng));
|
curContribution.delta.g1_s = curve.G1.toAffine(curve.G1.fromRng(rng));
|
||||||
curContribution.delta.g1_sx = curve.G1.affine(curve.G1.mulScalar(curContribution.delta.g1_s, curContribution.delta.prvKey));
|
curContribution.delta.g1_sx = curve.G1.toAffine(curve.G1.timesScalar(curContribution.delta.g1_s, curContribution.delta.prvKey));
|
||||||
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_s);
|
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_s);
|
||||||
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_sx);
|
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_sx);
|
||||||
curContribution.transcript = transcriptHasher.digest();
|
curContribution.transcript = transcriptHasher.digest();
|
||||||
curContribution.delta.g2_sp = hashToG2(curContribution.transcript);
|
curContribution.delta.g2_sp = hashToG2(curve, curContribution.transcript);
|
||||||
curContribution.delta.g2_spx = curve.G2.affine(curve.G2.mulScalar(curContribution.delta.g2_sp, curContribution.delta.prvKey));
|
curContribution.delta.g2_spx = curve.G2.toAffine(curve.G2.timesScalar(curContribution.delta.g2_sp, curContribution.delta.prvKey));
|
||||||
|
|
||||||
zkey.vk_delta_1 = curve.G1.mulScalar(zkey.vk_delta_1, curContribution.delta.prvKey);
|
zkey.vk_delta_1 = curve.G1.timesScalar(zkey.vk_delta_1, curContribution.delta.prvKey);
|
||||||
zkey.vk_delta_2 = curve.G2.mulScalar(zkey.vk_delta_2, curContribution.delta.prvKey);
|
zkey.vk_delta_2 = curve.G2.timesScalar(zkey.vk_delta_2, curContribution.delta.prvKey);
|
||||||
|
|
||||||
curContribution.deltaAfter = zkey.vk_delta_1;
|
curContribution.deltaAfter = zkey.vk_delta_1;
|
||||||
|
|
||||||
|
43
src/zkey_export_verificationkey.js
Normal file
43
src/zkey_export_verificationkey.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
const binFileUtils = require("./binfileutils");
|
||||||
|
const zkeyUtils = require("./zkey_utils");
|
||||||
|
const getCurve = require("./curves").getCurveFromQ;
|
||||||
|
const {stringifyBigInts} = require("ffjavascript").utils;
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
module.exports = async function zkeyExportVerificationKey(zkeyName, verificationKeyName) {
|
||||||
|
|
||||||
|
const {fd, sections} = await binFileUtils.readBinFile(zkeyName, "zkey", 2);
|
||||||
|
const zkey = await zkeyUtils.readHeader(fd, sections, "groth16");
|
||||||
|
|
||||||
|
const curve = await getCurve(zkey.q);
|
||||||
|
const sG1 = curve.G1.F.n8*2;
|
||||||
|
|
||||||
|
const alphaBeta = await curve.pairing( zkey.vk_alpha_1 , zkey.vk_beta_2 );
|
||||||
|
|
||||||
|
const vKey = {
|
||||||
|
protocol: zkey.protocol,
|
||||||
|
curve: curve.name,
|
||||||
|
nPublic: zkey.nPublic,
|
||||||
|
|
||||||
|
vk_alpha_1: curve.G1.toObject(zkey.vk_alpha_1),
|
||||||
|
|
||||||
|
vk_beta_2: curve.G2.toObject(zkey.vk_beta_2),
|
||||||
|
vk_gamma_2: curve.G2.toObject(zkey.vk_gamma_2),
|
||||||
|
vk_delta_2: curve.G2.toObject(zkey.vk_delta_2),
|
||||||
|
|
||||||
|
vk_alphabeta_12: curve.Gt.toObject(alphaBeta)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Read IC Section
|
||||||
|
///////////
|
||||||
|
await binFileUtils.startReadUniqueSection(fd, sections, 3);
|
||||||
|
vKey.IC = [];
|
||||||
|
for (let i=0; i<= zkey.nPublic; i++) {
|
||||||
|
const buff = await fd.read(sG1);
|
||||||
|
const P = curve.G1.toObject(buff);
|
||||||
|
vKey.IC.push(P);
|
||||||
|
}
|
||||||
|
await binFileUtils.endReadSection(fd);
|
||||||
|
|
||||||
|
await fs.promises.writeFile(verificationKeyName, JSON.stringify(stringifyBigInts(vKey), null, 1), "utf-8");
|
||||||
|
};
|
@ -19,8 +19,6 @@ module.exports = async function phase2new(r1csName, ptauName, zkeyName, verbose
|
|||||||
const {fd: fdPTau, sections: sectionsPTau} = await binFileUtils.readBinFile(ptauName, "ptau", 1);
|
const {fd: fdPTau, sections: sectionsPTau} = await binFileUtils.readBinFile(ptauName, "ptau", 1);
|
||||||
const {curve, power} = await utils.readPTauHeader(fdPTau, sectionsPTau);
|
const {curve, power} = await utils.readPTauHeader(fdPTau, sectionsPTau);
|
||||||
|
|
||||||
await curve.loadEngine();
|
|
||||||
|
|
||||||
const fdZKey = await binFileUtils.createBinFile(zkeyName, "zkey", 1, 10);
|
const fdZKey = await binFileUtils.createBinFile(zkeyName, "zkey", 1, 10);
|
||||||
|
|
||||||
const sG1 = curve.G1.F.n8*2;
|
const sG1 = curve.G1.F.n8*2;
|
||||||
@ -62,7 +60,7 @@ module.exports = async function phase2new(r1csName, ptauName, zkeyName, verbose
|
|||||||
const primeR = curve.r;
|
const primeR = curve.r;
|
||||||
const n8r = (Math.floor( (Scalar.bitLength(primeR) - 1) / 64) +1)*8;
|
const n8r = (Math.floor( (Scalar.bitLength(primeR) - 1) / 64) +1)*8;
|
||||||
const Rr = Scalar.mod(Scalar.shl(1, n8r*8), primeR);
|
const Rr = Scalar.mod(Scalar.shl(1, n8r*8), primeR);
|
||||||
const R2r = Scalar.mod(Scalar.mul(Rr,Rr), primeR);
|
const R2r = curve.Fr.e(Scalar.mod(Scalar.mul(Rr,Rr), primeR));
|
||||||
|
|
||||||
await fdZKey.writeULE32(n8q);
|
await fdZKey.writeULE32(n8q);
|
||||||
await binFileUtils.writeBigInt(fdZKey, primeQ, n8q);
|
await binFileUtils.writeBigInt(fdZKey, primeQ, n8q);
|
||||||
@ -95,9 +93,9 @@ module.exports = async function phase2new(r1csName, ptauName, zkeyName, verbose
|
|||||||
const bg2 = new Uint8Array(sG2);
|
const bg2 = new Uint8Array(sG2);
|
||||||
curve.G2.toRprLEM(bg2, 0, curve.G2.g);
|
curve.G2.toRprLEM(bg2, 0, curve.G2.g);
|
||||||
const bg1U = new Uint8Array(sG1);
|
const bg1U = new Uint8Array(sG1);
|
||||||
curve.G1.toRprBE(bg1U, 0, curve.G1.g);
|
curve.G1.toRprUncompressed(bg1U, 0, curve.G1.g);
|
||||||
const bg2U = new Uint8Array(sG2);
|
const bg2U = new Uint8Array(sG2);
|
||||||
curve.G2.toRprBE(bg2U, 0, curve.G2.g);
|
curve.G2.toRprUncompressed(bg2U, 0, curve.G2.g);
|
||||||
|
|
||||||
await fdZKey.write(bg2); // gamma2
|
await fdZKey.write(bg2); // gamma2
|
||||||
await fdZKey.write(bg1); // delta1
|
await fdZKey.write(bg1); // delta1
|
||||||
@ -285,7 +283,7 @@ module.exports = async function phase2new(r1csName, ptauName, zkeyName, verbose
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function composeAndWritePointsChunk(groupName, arr) {
|
async function composeAndWritePointsChunk(groupName, arr) {
|
||||||
const concurrency= curve.engine.concurrency;
|
const concurrency= curve.tm.concurrency;
|
||||||
const nElementsPerThread = Math.floor(arr.length / concurrency);
|
const nElementsPerThread = Math.floor(arr.length / concurrency);
|
||||||
const opPromises = [];
|
const opPromises = [];
|
||||||
const G = curve[groupName];
|
const G = curve[groupName];
|
||||||
@ -388,7 +386,7 @@ module.exports = async function phase2new(r1csName, ptauName, zkeyName, verbose
|
|||||||
]});
|
]});
|
||||||
task.push({cmd: "GET", out: 0, var: 2, len: arr.length*sGout});
|
task.push({cmd: "GET", out: 0, var: 2, len: arr.length*sGout});
|
||||||
|
|
||||||
const res = await curve.engine.queueAction(task);
|
const res = await curve.tm.queueAction(task);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -409,7 +407,7 @@ module.exports = async function phase2new(r1csName, ptauName, zkeyName, verbose
|
|||||||
async function hashHPointsChunk(offset, nPoints) {
|
async function hashHPointsChunk(offset, nPoints) {
|
||||||
const buff1 = await fdPTau.read(nPoints *sG1, sectionsPTau[2][0].p + (offset + domainSize)*sG1);
|
const buff1 = await fdPTau.read(nPoints *sG1, sectionsPTau[2][0].p + (offset + domainSize)*sG1);
|
||||||
const buff2 = await fdPTau.read(nPoints *sG1, sectionsPTau[2][0].p + offset*sG1);
|
const buff2 = await fdPTau.read(nPoints *sG1, sectionsPTau[2][0].p + offset*sG1);
|
||||||
const concurrency= curve.engine.concurrency;
|
const concurrency= curve.tm.concurrency;
|
||||||
const nPointsPerThread = Math.floor(nPoints / concurrency);
|
const nPointsPerThread = Math.floor(nPoints / concurrency);
|
||||||
const opPromises = [];
|
const opPromises = [];
|
||||||
for (let i=0; i<concurrency; i++) {
|
for (let i=0; i<concurrency; i++) {
|
||||||
@ -464,7 +462,7 @@ module.exports = async function phase2new(r1csName, ptauName, zkeyName, verbose
|
|||||||
]});
|
]});
|
||||||
task.push({cmd: "GET", out: 0, var: 2, len: nPoints*sG1});
|
task.push({cmd: "GET", out: 0, var: 2, len: nPoints*sG1});
|
||||||
|
|
||||||
const res = await curve.engine.queueAction(task);
|
const res = await curve.tm.queueAction(task);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ async function readHeader(fd, sections, protocol) {
|
|||||||
zkey.n8r = n8r;
|
zkey.n8r = n8r;
|
||||||
zkey.r = await binFileUtils.readBigInt(fd, n8r);
|
zkey.r = await binFileUtils.readBigInt(fd, n8r);
|
||||||
|
|
||||||
let curve = getCurve(zkey.q);
|
let curve = await getCurve(zkey.q);
|
||||||
|
|
||||||
zkey.nVars = await fd.readULE32();
|
zkey.nVars = await fd.readULE32();
|
||||||
zkey.nPublic = await fd.readULE32();
|
zkey.nPublic = await fd.readULE32();
|
||||||
|
@ -42,7 +42,7 @@ module.exports = async function phase2verify(r1csFileName, pTauFileName, zkeyFi
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const delta_g2_sp = hashToG2(c.transcript);
|
const delta_g2_sp = hashToG2(curve, c.transcript);
|
||||||
|
|
||||||
sr = await sameRatio(curve, c.delta.g1_s, c.delta.g1_sx, delta_g2_sp, c.delta.g2_spx);
|
sr = await sameRatio(curve, c.delta.g1_s, c.delta.g1_sx, delta_g2_sp, c.delta.g2_spx);
|
||||||
if (sr !== true) {
|
if (sr !== true) {
|
||||||
@ -59,8 +59,8 @@ module.exports = async function phase2verify(r1csFileName, pTauFileName, zkeyFi
|
|||||||
if (c.type == 1) {
|
if (c.type == 1) {
|
||||||
const rng = misc.rngFromBeaconParams(c.beaconHash, c.numIterationsExp);
|
const rng = misc.rngFromBeaconParams(c.beaconHash, c.numIterationsExp);
|
||||||
const expected_prvKey = curve.Fr.fromRng(rng);
|
const expected_prvKey = curve.Fr.fromRng(rng);
|
||||||
const expected_g1_s = curve.G1.affine(curve.G1.fromRng(rng));
|
const expected_g1_s = curve.G1.toAffine(curve.G1.fromRng(rng));
|
||||||
const expected_g1_sx = curve.G1.affine(curve.G1.mulScalar(expected_g1_s, expected_prvKey));
|
const expected_g1_sx = curve.G1.toAffine(curve.G1.timesScalar(expected_g1_s, expected_prvKey));
|
||||||
if (curve.G1.eq(expected_g1_s, c.delta.g1_s) !== true) {
|
if (curve.G1.eq(expected_g1_s, c.delta.g1_s) !== true) {
|
||||||
console.log(`INVALID(${i}): Key of the beacon does not match. g1_s `);
|
console.log(`INVALID(${i}): Key of the beacon does not match. g1_s `);
|
||||||
return false;
|
return false;
|
||||||
|
@ -22,8 +22,7 @@ async function groth16Prover(zkeyFileName, witnessFileName, verbose) {
|
|||||||
throw new Error(`Invalid witness length. Circuit: ${zkey.nVars}, witness: ${wtns.nWitness}`);
|
throw new Error(`Invalid witness length. Circuit: ${zkey.nVars}, witness: ${wtns.nWitness}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const curve = getCurve(zkey.q);
|
const curve = await getCurve(zkey.q);
|
||||||
await curve.loadEngine();
|
|
||||||
const Fr = curve.Fr;
|
const Fr = curve.Fr;
|
||||||
const G1 = curve.G1;
|
const G1 = curve.G1;
|
||||||
const G2 = curve.G2;
|
const G2 = curve.G2;
|
||||||
@ -41,15 +40,15 @@ async function groth16Prover(zkeyFileName, witnessFileName, verbose) {
|
|||||||
const [buffA_T, buffB_T, buffC_T] = await buldABC(curve, zkey, buffWitness, buffCoeffs);
|
const [buffA_T, buffB_T, buffC_T] = await buldABC(curve, zkey, buffWitness, buffCoeffs);
|
||||||
|
|
||||||
const buffA = await Fr.ifft(buffA_T);
|
const buffA = await Fr.ifft(buffA_T);
|
||||||
const buffAodd = await Fr.batchApplyKey(buffA, Fr.e(1), curve.PFr.w[power+1]);
|
const buffAodd = await Fr.batchApplyKey(buffA, Fr.e(1), curve.Fr.w[power+1]);
|
||||||
const buffAodd_T = await Fr.fft(buffAodd);
|
const buffAodd_T = await Fr.fft(buffAodd);
|
||||||
|
|
||||||
const buffB = await Fr.ifft(buffB_T);
|
const buffB = await Fr.ifft(buffB_T);
|
||||||
const buffBodd = await Fr.batchApplyKey(buffB, Fr.e(1), curve.PFr.w[power+1]);
|
const buffBodd = await Fr.batchApplyKey(buffB, Fr.e(1), curve.Fr.w[power+1]);
|
||||||
const buffBodd_T = await Fr.fft(buffBodd);
|
const buffBodd_T = await Fr.fft(buffBodd);
|
||||||
|
|
||||||
const buffC = await Fr.ifft(buffC_T);
|
const buffC = await Fr.ifft(buffC_T);
|
||||||
const buffCodd = await Fr.batchApplyKey(buffC, Fr.e(1), curve.PFr.w[power+1]);
|
const buffCodd = await Fr.batchApplyKey(buffC, Fr.e(1), curve.Fr.w[power+1]);
|
||||||
const buffCodd_T = await Fr.fft(buffCodd);
|
const buffCodd_T = await Fr.fft(buffCodd);
|
||||||
|
|
||||||
const buffPodd_T = await joinABC(curve, zkey, buffAodd_T, buffBodd_T, buffCodd_T);
|
const buffPodd_T = await joinABC(curve, zkey, buffAodd_T, buffBodd_T, buffCodd_T);
|
||||||
@ -65,35 +64,35 @@ async function groth16Prover(zkeyFileName, witnessFileName, verbose) {
|
|||||||
const r = curve.Fr.random();
|
const r = curve.Fr.random();
|
||||||
const s = curve.Fr.random();
|
const s = curve.Fr.random();
|
||||||
|
|
||||||
|
|
||||||
proof.pi_a = G1.add( proof.pi_a, zkey.vk_alpha_1 );
|
proof.pi_a = G1.add( proof.pi_a, zkey.vk_alpha_1 );
|
||||||
proof.pi_a = G1.add( proof.pi_a, G1.mulScalar( zkey.vk_delta_1, r ));
|
proof.pi_a = G1.add( proof.pi_a, G1.timesFr( zkey.vk_delta_1, r ));
|
||||||
|
|
||||||
proof.pi_b = G2.add( proof.pi_b, zkey.vk_beta_2 );
|
proof.pi_b = G2.add( proof.pi_b, zkey.vk_beta_2 );
|
||||||
proof.pi_b = G2.add( proof.pi_b, G2.mulScalar( zkey.vk_delta_2, s ));
|
proof.pi_b = G2.add( proof.pi_b, G2.timesFr( zkey.vk_delta_2, s ));
|
||||||
|
|
||||||
pib1 = G1.add( pib1, zkey.vk_beta_1 );
|
pib1 = G1.add( pib1, zkey.vk_beta_1 );
|
||||||
pib1 = G1.add( pib1, G1.mulScalar( zkey.vk_delta_1, s ));
|
pib1 = G1.add( pib1, G1.timesFr( zkey.vk_delta_1, s ));
|
||||||
|
|
||||||
proof.pi_c = G1.add(proof.pi_c, resH);
|
proof.pi_c = G1.add(proof.pi_c, resH);
|
||||||
|
|
||||||
|
|
||||||
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( proof.pi_a, s ));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesFr( 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.timesFr( pib1, r ));
|
||||||
proof.pi_c = G1.add( proof.pi_c, G1.mulScalar( zkey.vk_delta_1, Fr.neg(Fr.mul(r,s) )));
|
proof.pi_c = G1.add( proof.pi_c, G1.timesFr( zkey.vk_delta_1, Fr.neg(Fr.mul(r,s) )));
|
||||||
|
|
||||||
|
|
||||||
const publicSignals = [];
|
const publicSignals = [];
|
||||||
|
|
||||||
for (let i=1; i<= zkey.nPublic; i++) {
|
for (let i=1; i<= zkey.nPublic; i++) {
|
||||||
publicSignals.push(Fr.fromRprLE(buffWitness, i*Fr.n8));
|
const b = buffWitness.slice(i*Fr.n8, i*Fr.n8+Fr.n8);
|
||||||
|
publicSignals.push(Scalar.fromRprLE(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
proof.pi_a = G1.affine(proof.pi_a);
|
proof.pi_a = G1.toObject(G1.toAffine(proof.pi_a));
|
||||||
proof.pi_b = G2.affine(proof.pi_b);
|
proof.pi_b = G2.toObject(G2.toAffine(proof.pi_b));
|
||||||
proof.pi_c = G1.affine(proof.pi_c);
|
proof.pi_c = G1.toObject(G1.toAffine(proof.pi_c));
|
||||||
|
|
||||||
proof.protocol = "groth";
|
proof.protocol = "groth16";
|
||||||
|
|
||||||
await fdZKey.close();
|
await fdZKey.close();
|
||||||
await fdWtns.close();
|
await fdWtns.close();
|
||||||
@ -103,7 +102,7 @@ async function groth16Prover(zkeyFileName, witnessFileName, verbose) {
|
|||||||
|
|
||||||
|
|
||||||
async function buldABC(curve, zkey, witness, coeffs) {
|
async function buldABC(curve, zkey, witness, coeffs) {
|
||||||
const concurrency = curve.engine.concurrency;
|
const concurrency = curve.tm.concurrency;
|
||||||
const sCoef = 4*3 + zkey.n8r;
|
const sCoef = 4*3 + zkey.n8r;
|
||||||
|
|
||||||
const elementsPerChunk = Math.floor(zkey.domainSize/concurrency);
|
const elementsPerChunk = Math.floor(zkey.domainSize/concurrency);
|
||||||
@ -145,7 +144,7 @@ async function buldABC(curve, zkey, witness, coeffs) {
|
|||||||
task.push({cmd: "GET", out: 0, var: 2, len: n*curve.Fr.n8});
|
task.push({cmd: "GET", out: 0, var: 2, len: n*curve.Fr.n8});
|
||||||
task.push({cmd: "GET", out: 1, var: 3, len: n*curve.Fr.n8});
|
task.push({cmd: "GET", out: 1, var: 3, len: n*curve.Fr.n8});
|
||||||
task.push({cmd: "GET", out: 2, var: 4, len: n*curve.Fr.n8});
|
task.push({cmd: "GET", out: 2, var: 4, len: n*curve.Fr.n8});
|
||||||
promises.push(curve.engine.queueAction(task));
|
promises.push(curve.tm.queueAction(task));
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await Promise.all(promises);
|
const result = await Promise.all(promises);
|
||||||
@ -183,7 +182,7 @@ async function buldABC(curve, zkey, witness, coeffs) {
|
|||||||
|
|
||||||
|
|
||||||
async function joinABC(curve, zkey, a, b, c) {
|
async function joinABC(curve, zkey, a, b, c) {
|
||||||
const concurrency = curve.engine.concurrency;
|
const concurrency = curve.tm.concurrency;
|
||||||
|
|
||||||
const n8 = curve.Fr.n8;
|
const n8 = curve.Fr.n8;
|
||||||
const nElements = Math.floor(a.byteLength / curve.Fr.n8);
|
const nElements = Math.floor(a.byteLength / curve.Fr.n8);
|
||||||
@ -223,7 +222,7 @@ async function joinABC(curve, zkey, a, b, c) {
|
|||||||
{var: 3}
|
{var: 3}
|
||||||
]});
|
]});
|
||||||
task.push({cmd: "GET", out: 0, var: 3, len: n*n8});
|
task.push({cmd: "GET", out: 0, var: 3, len: n*n8});
|
||||||
promises.push(curve.engine.queueAction(task));
|
promises.push(curve.tm.queueAction(task));
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await Promise.all(promises);
|
const result = await Promise.all(promises);
|
||||||
|
@ -19,28 +19,47 @@
|
|||||||
|
|
||||||
/* Implementation of this paper: https://eprint.iacr.org/2016/260.pdf */
|
/* Implementation of this paper: https://eprint.iacr.org/2016/260.pdf */
|
||||||
|
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
const bn128 = require("ffjavascript").bn128;
|
const curves = require("./curves");
|
||||||
|
|
||||||
const G1 = bn128.G1;
|
|
||||||
|
|
||||||
module.exports = async function isValid(vk_verifier, proof, publicSignals) {
|
module.exports = async function isValid(vk_verifier, proof, publicSignals) {
|
||||||
/*
|
/*
|
||||||
let cpub = vk_verifier.IC[0];
|
let cpub = vk_verifier.IC[0];
|
||||||
for (let s= 0; s< vk_verifier.nPublic; s++) {
|
for (let s= 0; s< vk_verifier.nPublic; s++) {
|
||||||
cpub = G1.add( cpub, G1.mulScalar( vk_verifier.IC[s+1], publicSignals[s]));
|
cpub = G1.add( cpub, G1.timesScalar( vk_verifier.IC[s+1], publicSignals[s]));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let cpub = await G1.multiExp(vk_verifier.IC.slice(1), publicSignals);
|
const curve = await curves.getCurveFromName(vk_verifier.curve);
|
||||||
cpub = G1.add(cpub, vk_verifier.IC[0]);
|
|
||||||
|
|
||||||
const res = await bn128.pairingEq(
|
const IC0 = curve.G1.fromObject(vk_verifier.IC[0]);
|
||||||
bn128.G1.neg(proof.pi_a) , proof.pi_b,
|
const IC = new Uint8Array(curve.G1.F.n8*2 * publicSignals.length);
|
||||||
cpub , vk_verifier.vk_gamma_2,
|
const w = new Uint8Array(curve.Fr.n8 * publicSignals.length);
|
||||||
proof.pi_c , vk_verifier.vk_delta_2,
|
|
||||||
|
|
||||||
vk_verifier.vk_alpha_1, vk_verifier.vk_beta_2
|
for (let i=0; i<publicSignals.length; i++) {
|
||||||
|
const buffP = curve.G1.fromObject(vk_verifier.IC[i+1]);
|
||||||
|
IC.set(buffP, i*curve.G1.F.n8*2);
|
||||||
|
Scalar.toRprLE(w, curve.Fr.n8*i, publicSignals[i], curve.Fr.n8);
|
||||||
|
}
|
||||||
|
|
||||||
|
let cpub = await curve.G1.multiExpAffine(IC, w);
|
||||||
|
cpub = curve.G1.add(cpub, IC0);
|
||||||
|
|
||||||
|
const pi_a = curve.G1.fromObject(proof.pi_a);
|
||||||
|
const pi_b = curve.G2.fromObject(proof.pi_b);
|
||||||
|
const pi_c = curve.G1.fromObject(proof.pi_c);
|
||||||
|
|
||||||
|
const vk_gamma_2 = curve.G2.fromObject(vk_verifier.vk_gamma_2);
|
||||||
|
const vk_delta_2 = curve.G2.fromObject(vk_verifier.vk_delta_2);
|
||||||
|
const vk_alpha_1 = curve.G1.fromObject(vk_verifier.vk_alpha_1);
|
||||||
|
const vk_beta_2 = curve.G2.fromObject(vk_verifier.vk_beta_2);
|
||||||
|
|
||||||
|
const res = await curve.pairingEq(
|
||||||
|
curve.G1.neg(pi_a) , pi_b,
|
||||||
|
cpub , vk_gamma_2,
|
||||||
|
pi_c , vk_delta_2,
|
||||||
|
|
||||||
|
vk_alpha_1, vk_beta_2
|
||||||
);
|
);
|
||||||
|
|
||||||
if (! res) return false;
|
if (! res) return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user