Contribution phase2
This commit is contained in:
parent
2e9ce5efe6
commit
3ba1341404
13
cli.js
13
cli.js
@ -133,7 +133,7 @@ const commands = [
|
|||||||
cmd: "powersoftau import <powersoftau_old.ptau> <response> <<powersoftau_new.ptau>",
|
cmd: "powersoftau import <powersoftau_old.ptau> <response> <<powersoftau_new.ptau>",
|
||||||
description: "import a response to a ptau file",
|
description: "import a response to a ptau file",
|
||||||
alias: ["pti"],
|
alias: ["pti"],
|
||||||
options: "-verbose|v -nopoints -nocheck -description|d -name|n",
|
options: "-verbose|v -nopoints -nocheck -name|n",
|
||||||
action: powersOfTawImport
|
action: powersOfTawImport
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -204,7 +204,7 @@ const commands = [
|
|||||||
cmd: "zkey contribute <circuit_old.zkey> <circuit_new.zkey>",
|
cmd: "zkey contribute <circuit_old.zkey> <circuit_new.zkey>",
|
||||||
description: "creates a zkey file with a new contribution",
|
description: "creates a zkey file with a new contribution",
|
||||||
alias: ["zkc"],
|
alias: ["zkc"],
|
||||||
options: "-verbose|v",
|
options: "-verbose|v -entropy|e -name|n",
|
||||||
action: zkeyContribute
|
action: zkeyContribute
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -772,7 +772,7 @@ async function zkeyNew(params, options) {
|
|||||||
zkeyName = params[2];
|
zkeyName = params[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
return phase2.new(r1csName, ptauName, zkeyName, options.verbose);
|
return zkey.new(r1csName, ptauName, zkeyName, options.verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
// zkey export bellman [circuit.zkey] [circuit.mpcparams]
|
// zkey export bellman [circuit.zkey] [circuit.mpcparams]
|
||||||
@ -792,7 +792,7 @@ async function zkeyExportBellman(params, options) {
|
|||||||
mpcparamsName = params[1];
|
mpcparamsName = params[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return phase2.exportMPCParams(zkeyName, mpcparamsName, options.verbose);
|
return zkey.exportMPCParams(zkeyName, mpcparamsName, options.verbose);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -846,8 +846,7 @@ async function zkeyVerify(params, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// phase2 contribute <circuit_old.zkey> <circuit_new.zkey>
|
// zkey contribute <circuit_old.zkey> <circuit_new.zkey>
|
||||||
|
|
||||||
async function zkeyContribute(params, options) {
|
async function zkeyContribute(params, options) {
|
||||||
let zkeyOldName;
|
let zkeyOldName;
|
||||||
let zkeyNewName;
|
let zkeyNewName;
|
||||||
@ -856,5 +855,5 @@ async function zkeyContribute(params, options) {
|
|||||||
zkeyNewName = params[1];
|
zkeyNewName = params[1];
|
||||||
|
|
||||||
|
|
||||||
return phase2.contribute(zkeyOldName, zkeyNewName, options.verbose);
|
return zkey.contribute(zkeyOldName, zkeyNewName, options.name, options.entropy, options.verbose);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ const blake2b = require("blake2b");
|
|||||||
const ChaCha = require("ffjavascript").ChaCha;
|
const ChaCha = require("ffjavascript").ChaCha;
|
||||||
|
|
||||||
function hashToG2(hash) {
|
function hashToG2(hash) {
|
||||||
const hashV = new DataView(hash.buffer);
|
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++) {
|
||||||
seed[i] = hashV.getUint32(i*4);
|
seed[i] = hashV.getUint32(i*4);
|
||||||
@ -57,6 +57,17 @@ function createPTauKey(curve, challangeHash, rng) {
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createDeltaKey(curve, transcript, rng) {
|
||||||
|
const delta = {};
|
||||||
|
delta.prvKey = curve.Fr.fromRng(rng);
|
||||||
|
delta.g1_s = curve.G1.affine(curve.G1.fromRng(rng));
|
||||||
|
delta.g1_sx = curve.G1.affine(curve.G1.mulScalar(delta.g1_s, delta.prvKey));
|
||||||
|
delta.g2_sp = hashToG2(transcript);
|
||||||
|
delta.g2_spx = curve.G2.affine(curve.G2.mulScalar(delta.g2_sp, delta.prvKey));
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.createPTauKey = createPTauKey;
|
module.exports.createPTauKey = createPTauKey;
|
||||||
module.exports.getG2sp = getG2sp;
|
module.exports.getG2sp = getG2sp;
|
||||||
module.exports.hashToG2 = hashToG2;
|
module.exports.hashToG2 = hashToG2;
|
||||||
|
module.exports.createDeltaKey =createDeltaKey;
|
||||||
|
36
src/misc.js
36
src/misc.js
@ -1,4 +1,7 @@
|
|||||||
const Blake2b = require("blake2b-wasm");
|
const Blake2b = require("blake2b-wasm");
|
||||||
|
const readline = require("readline");
|
||||||
|
const ChaCha = require("ffjavascript").ChaCha;
|
||||||
|
const crypto = require("crypto");
|
||||||
|
|
||||||
const _revTable = [];
|
const _revTable = [];
|
||||||
for (let i=0; i<256; i++) {
|
for (let i=0; i<256; i++) {
|
||||||
@ -74,9 +77,42 @@ async function sameRatio(curve, g1s, g1sx, g2s, g2sx) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout
|
||||||
|
});
|
||||||
|
|
||||||
|
function askEntropy() {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
rl.question("Enter a random text. (Entropy): ", (input) => resolve(input) );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getRandomRng(entropy) {
|
||||||
|
// Generate a random key
|
||||||
|
while (!entropy) {
|
||||||
|
entropy = await askEntropy();
|
||||||
|
}
|
||||||
|
const hasher = Blake2b(64);
|
||||||
|
hasher.update(crypto.randomBytes(64));
|
||||||
|
const enc = new TextEncoder(); // always utf-8
|
||||||
|
hasher.update(enc.encode(entropy));
|
||||||
|
const hash = Buffer.from(hasher.digest());
|
||||||
|
|
||||||
|
const seed = [];
|
||||||
|
for (let i=0;i<8;i++) {
|
||||||
|
seed[i] = hash.readUInt32BE(i*4);
|
||||||
|
}
|
||||||
|
const rng = new ChaCha(seed);
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.bitReverse = bitReverse;
|
module.exports.bitReverse = bitReverse;
|
||||||
module.exports.log2 = log2;
|
module.exports.log2 = log2;
|
||||||
module.exports.formatHash = formatHash;
|
module.exports.formatHash = formatHash;
|
||||||
module.exports.hashIsEqual = hashIsEqual;
|
module.exports.hashIsEqual = hashIsEqual;
|
||||||
module.exports.cloneHasher = cloneHasher;
|
module.exports.cloneHasher = cloneHasher;
|
||||||
module.exports.sameRatio = sameRatio;
|
module.exports.sameRatio = sameRatio;
|
||||||
|
module.exports.getRandomRng = getRandomRng;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
const buildTaskManager = require("./taskmanager");
|
const buildTaskManager = require("./taskmanager");
|
||||||
|
const binFileUtils = require("./binfileutils");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This function creates a new section in the fdTo file with id idSection.
|
This function creates a new section in the fdTo file with id idSection.
|
||||||
@ -8,116 +9,36 @@ const buildTaskManager = require("./taskmanager");
|
|||||||
It also updates the newChallangeHasher with the new points
|
It also updates the newChallangeHasher with the new points
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async function applyKey(params) {
|
async function applyKeyToSection(fdOld, sections, fdNew, idSection, curve, groupName, first, inc, sectionName, verbose) {
|
||||||
const {
|
const MAX_CHUNK_SIZE = 1 << 16;
|
||||||
fdFrom,
|
const G = curve[groupName];
|
||||||
sections,
|
|
||||||
curve,
|
|
||||||
fdTo,
|
|
||||||
sectionId,
|
|
||||||
NPoints,
|
|
||||||
G:Gs,
|
|
||||||
first,
|
|
||||||
inc,
|
|
||||||
newChallangeHasher,
|
|
||||||
responseHasher,
|
|
||||||
returnPoints,
|
|
||||||
sectionName,
|
|
||||||
verbose
|
|
||||||
} = params;
|
|
||||||
const G = curve[Gs];
|
|
||||||
const MAX_CHUNK_SIZE = 1024;
|
|
||||||
|
|
||||||
let res = [];
|
|
||||||
const sG = G.F.n8*2;
|
const sG = G.F.n8*2;
|
||||||
const buffUv = new Uint8Array(sG);
|
const nPoints = sections[idSection][0].size / sG;
|
||||||
const scG = G.F.n8;
|
|
||||||
const buffCv = new Uint8Array(scG);
|
|
||||||
|
|
||||||
const taskManager = await buildTaskManager(contributeThread, {
|
await binFileUtils.startReadUniqueSection(fdOld, sections,idSection );
|
||||||
ffjavascript: "ffjavascript"
|
await binFileUtils.startWriteSection(fdNew, idSection);
|
||||||
},{
|
|
||||||
curve: curve.name
|
|
||||||
});
|
|
||||||
|
|
||||||
fdFrom.pos = sections[sectionId][0].p;
|
|
||||||
await fdTo.writeULE32(sectionId); // tauG1
|
|
||||||
const pSection = fdTo.pos;
|
|
||||||
await fdTo.writeULE64(0); // Temporally set to 0 length
|
|
||||||
let t = first;
|
let t = first;
|
||||||
let writePointer = fdTo.pos;
|
for (let i=0; i<nPoints; i += MAX_CHUNK_SIZE) {
|
||||||
let beginWritePointer = fdTo.pos;
|
if (verbose) console.log(`Applying key: ${sectionName}: ${i}/${nPoints}`);
|
||||||
for (let i=0; i< NPoints; i+=MAX_CHUNK_SIZE) {
|
const n= Math.min(nPoints - i, MAX_CHUNK_SIZE);
|
||||||
if ((verbose)&&i) console.log(`${sectionName}: ` + i);
|
let buff;
|
||||||
const n = Math.min(NPoints - i, MAX_CHUNK_SIZE);
|
buff = await fdOld.read(n*sG);
|
||||||
const buff = await fdFrom.read(n*sG);
|
buff = await G.batchApplyKey(buff, t, inc);
|
||||||
await taskManager.addTask({
|
await fdNew.write(buff);
|
||||||
cmd: "MUL",
|
|
||||||
G: Gs,
|
|
||||||
first: t,
|
|
||||||
inc: inc.toString(),
|
|
||||||
buff: buff.slice(),
|
|
||||||
n: n,
|
|
||||||
writePos: writePointer
|
|
||||||
}, async function(r) {
|
|
||||||
return await fdTo.write(r.buff, r.writePos);
|
|
||||||
});
|
|
||||||
t = curve.Fr.mul(t, curve.Fr.pow(inc, n));
|
t = curve.Fr.mul(t, curve.Fr.pow(inc, n));
|
||||||
writePointer += n*sG;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await taskManager.finish();
|
await binFileUtils.endWriteSection(fdNew);
|
||||||
|
await binFileUtils.endReadSection(fdOld);
|
||||||
|
|
||||||
const sSize = fdTo.pos - pSection -8;
|
|
||||||
const lastPos = fdTo.pos;
|
|
||||||
await fdTo.writeULE64(sSize, pSection);
|
|
||||||
fdTo.pos = lastPos;
|
|
||||||
|
|
||||||
fdTo.pos = beginWritePointer;
|
}
|
||||||
for (let i=0; i<NPoints; i++) {
|
|
||||||
const buff = await fdTo.read(sG);
|
async function applyKeyToBinFile(fdOld, fdNew, curve, groupName, nPoints, first, inc, sectionName, verbose) {
|
||||||
const P = G.fromRprLEM(buff, 0);
|
|
||||||
G.toRprBE(buffUv, 0, P);
|
|
||||||
newChallangeHasher.update(buffUv);
|
|
||||||
G.toRprCompressed(buffCv, 0, P);
|
|
||||||
responseHasher.update(buffCv);
|
|
||||||
const idx = returnPoints.indexOf(i);
|
|
||||||
if (idx>=0) res[idx] = P;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function contributeThread(ctx, task) {
|
module.exports.applyKeyToBinFile = applyKeyToBinFile;
|
||||||
if (task.cmd == "INIT") {
|
module.exports.applyKeyToSection = applyKeyToSection;
|
||||||
ctx.assert = ctx.modules.assert;
|
|
||||||
if (task.curve == "bn128") {
|
|
||||||
ctx.curve = ctx.modules.ffjavascript.bn128;
|
|
||||||
} else {
|
|
||||||
ctx.assert(false, "curve not defined");
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
} else if (task.cmd == "MUL") {
|
|
||||||
const G = ctx.curve[task.G];
|
|
||||||
const sG = G.F.n64*8*2;
|
|
||||||
const buffDest = new Uint8Array(sG*task.n);
|
|
||||||
let t = ctx.curve.Fr.e(task.first);
|
|
||||||
let inc = ctx.curve.Fr.e(task.inc);
|
|
||||||
for (let i=0; i<task.n; i++) {
|
|
||||||
const P = G.fromRprLEM(task.buff, i*sG);
|
|
||||||
const R = G.mulScalar(P, t);
|
|
||||||
G.toRprLEM(buffDest, i*sG, R); // Main thread will convert it to Montgomery
|
|
||||||
t = ctx.curve.Fr.mul(t, inc);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
buff: buffDest,
|
|
||||||
writePos: task.writePos
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
ctx.assert(false, "Op not implemented");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = applyKey;
|
|
||||||
|
@ -1,4 +1,87 @@
|
|||||||
|
|
||||||
module.exports = async function phase2contribute(zkeyNameOld, zkeyNameNew, verbose) {
|
const binFileUtils = require("./binfileutils");
|
||||||
|
const zkeyUtils = require("./zkey_utils");
|
||||||
|
const getCurve = require("./curves").getCurveFromQ;
|
||||||
|
const misc = require("./misc");
|
||||||
|
const Blake2b = require("blake2b-wasm");
|
||||||
|
const utils = require("./zkey_utils");
|
||||||
|
const hashToG2 = require("./keypair").hashToG2;
|
||||||
|
const {applyKeyToSection} = require("./mpc_applykey");
|
||||||
|
|
||||||
|
module.exports = async function phase2contribute(zkeyNameOld, zkeyNameNew, name, entropy, verbose) {
|
||||||
|
await Blake2b.ready();
|
||||||
|
|
||||||
|
const {fd: fdOld, sections: sections} = await binFileUtils.readBinFile(zkeyNameOld, "zkey", 2);
|
||||||
|
const zkey = await zkeyUtils.readHeader(fdOld, sections, "groth16");
|
||||||
|
|
||||||
|
const curve = getCurve(zkey.q);
|
||||||
|
await curve.loadEngine();
|
||||||
|
|
||||||
|
const mpcParams = await zkeyUtils.readMPCParams(fdOld, curve, sections);
|
||||||
|
|
||||||
|
const fdNew = await binFileUtils.createBinFile(zkeyNameNew, "zkey", 1, 10);
|
||||||
|
|
||||||
|
const curContribution = {};
|
||||||
|
|
||||||
|
const rng = await misc.getRandomRng(entropy);
|
||||||
|
|
||||||
|
const transcriptHasher = Blake2b(64);
|
||||||
|
for (let i=0; i<mpcParams.contributions.length; i++) {
|
||||||
|
utils.hashPubKey(transcriptHasher, curve, mpcParams.contributions[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
curContribution.delta = {};
|
||||||
|
curContribution.delta.prvKey = curve.Fr.fromRng(rng);
|
||||||
|
curContribution.delta.g1_s = curve.G1.affine(curve.G1.fromRng(rng));
|
||||||
|
curContribution.delta.g1_sx = curve.G1.affine(curve.G1.mulScalar(curContribution.delta.g1_s, curContribution.delta.prvKey));
|
||||||
|
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_s);
|
||||||
|
utils.hashG1(transcriptHasher, curve, curContribution.delta.g1_sx);
|
||||||
|
curContribution.transcript = transcriptHasher.digest();
|
||||||
|
curContribution.delta.g2_sp = hashToG2(curContribution.transcript);
|
||||||
|
curContribution.delta.g2_spx = curve.G2.affine(curve.G2.mulScalar(curContribution.delta.g2_sp, curContribution.delta.prvKey));
|
||||||
|
|
||||||
|
zkey.vk_delta_1 = curve.G1.mulScalar(zkey.vk_delta_1, curContribution.delta.prvKey);
|
||||||
|
zkey.vk_delta_2 = curve.G2.mulScalar(zkey.vk_delta_2, curContribution.delta.prvKey);
|
||||||
|
|
||||||
|
curContribution.deltaAfter = zkey.vk_delta_1;
|
||||||
|
mpcParams.contributions.push(curContribution);
|
||||||
|
|
||||||
|
curContribution.type = 0;
|
||||||
|
if (name) curContribution.name = name;
|
||||||
|
|
||||||
|
await zkeyUtils.writeHeader(fdNew, zkey);
|
||||||
|
|
||||||
|
// IC
|
||||||
|
await binFileUtils.copySection(fdOld, sections, fdNew, 3);
|
||||||
|
|
||||||
|
// Coeffs (Keep original)
|
||||||
|
await binFileUtils.copySection(fdOld, sections, fdNew, 4);
|
||||||
|
|
||||||
|
// A Section
|
||||||
|
await binFileUtils.copySection(fdOld, sections, fdNew, 5);
|
||||||
|
|
||||||
|
// B1 Section
|
||||||
|
await binFileUtils.copySection(fdOld, sections, fdNew, 6);
|
||||||
|
|
||||||
|
// B2 Section
|
||||||
|
await binFileUtils.copySection(fdOld, sections, fdNew, 7);
|
||||||
|
|
||||||
|
const invDelta = curve.Fr.inv(curContribution.delta.prvKey);
|
||||||
|
await applyKeyToSection(fdOld, sections, fdNew, 8, curve, "G1", invDelta, curve.Fr.e(1), "L Section", verbose);
|
||||||
|
await applyKeyToSection(fdOld, sections, fdNew, 9, curve, "G1", invDelta, curve.Fr.e(1), "H Section", verbose);
|
||||||
|
|
||||||
|
await zkeyUtils.writeMPCParams(fdNew, curve, mpcParams);
|
||||||
|
|
||||||
|
await fdOld.close();
|
||||||
|
await fdNew.close();
|
||||||
|
|
||||||
|
const contributionHasher = Blake2b(64);
|
||||||
|
utils.hashPubKey(contributionHasher, curve, curContribution);
|
||||||
|
|
||||||
|
const contribuionHash = contributionHasher.digest();
|
||||||
|
|
||||||
|
console.log("Contribution Hash: ");
|
||||||
|
console.log(misc.formatHash(contribuionHash));
|
||||||
|
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
@ -395,7 +395,7 @@ module.exports = async function phase2new(r1csName, ptauName, zkeyName, verbose
|
|||||||
|
|
||||||
|
|
||||||
async function hashHPoints() {
|
async function hashHPoints() {
|
||||||
const CHUNK_SIZE = 1<<20;
|
const CHUNK_SIZE = 1<<16;
|
||||||
|
|
||||||
hashU32(domainSize-1);
|
hashU32(domainSize-1);
|
||||||
|
|
||||||
|
@ -346,6 +346,33 @@ async function readContribution(fd, curve) {
|
|||||||
c.delta.g1_sx = await readG1(fd, curve);
|
c.delta.g1_sx = await readG1(fd, curve);
|
||||||
c.delta.g2_spx = await readG2(fd, curve);
|
c.delta.g2_spx = await readG2(fd, curve);
|
||||||
c.transcript = await fd.read(64);
|
c.transcript = await fd.read(64);
|
||||||
|
c.type = await fd.readULE32();
|
||||||
|
|
||||||
|
const paramLength = await fd.readULE32();
|
||||||
|
const curPos = fd.pos;
|
||||||
|
let lastType =0;
|
||||||
|
while (fd.pos-curPos < paramLength) {
|
||||||
|
const buffType = await fd.read(1);
|
||||||
|
if (buffType[0]<= lastType) throw new Error("Parameters in the contribution must be sorted");
|
||||||
|
lastType = buffType[0];
|
||||||
|
if (buffType[0]==1) { // Name
|
||||||
|
const buffLen = await fd.read(1);
|
||||||
|
const buffStr = await fd.read(buffLen[0]);
|
||||||
|
c.name = new TextDecoder().decode(buffStr);
|
||||||
|
} else if (buffType[0]==2) {
|
||||||
|
const buffExp = await fd.read(1);
|
||||||
|
c.numIterationsExp = buffExp[0];
|
||||||
|
} else if (buffType[0]==3) {
|
||||||
|
const buffLen = await fd.read(1);
|
||||||
|
c.beaconHash = await fd.read(buffLen[0]);
|
||||||
|
} else {
|
||||||
|
throw new Error("Parameter not recognized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fd.pos != curPos + paramLength) {
|
||||||
|
throw new Error("Parametes do not match");
|
||||||
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,6 +397,31 @@ async function writeContribution(fd, curve, c) {
|
|||||||
await writeG1(fd, curve, c.delta.g1_sx);
|
await writeG1(fd, curve, c.delta.g1_sx);
|
||||||
await writeG2(fd, curve, c.delta.g2_spx);
|
await writeG2(fd, curve, c.delta.g2_spx);
|
||||||
await fd.write(c.transcript);
|
await fd.write(c.transcript);
|
||||||
|
await fd.writeULE32(c.type || 0);
|
||||||
|
|
||||||
|
const params = [];
|
||||||
|
if (c.name) {
|
||||||
|
params.push(1); // Param Name
|
||||||
|
const nameData = new TextEncoder("utf-8").encode(c.name.substring(0,64));
|
||||||
|
params.push(nameData.byteLength);
|
||||||
|
for (let i=0; i<nameData.byteLength; i++) params.push(nameData[i]);
|
||||||
|
}
|
||||||
|
if (c.type == 1) {
|
||||||
|
params.push(2); // Param numIterationsExp
|
||||||
|
params.push(c.numIterationsExp);
|
||||||
|
|
||||||
|
params.push(3); // Beacon Hash
|
||||||
|
params.push(c.beaconHash.byteLength);
|
||||||
|
for (let i=0; i<c.beaconHash.byteLength; i++) params.push(c.beaconHash[i]);
|
||||||
|
}
|
||||||
|
if (params.length>0) {
|
||||||
|
const paramsBuff = new Uint8Array(params);
|
||||||
|
await fd.writeULE32(paramsBuff.byteLength);
|
||||||
|
await fd.write(paramsBuff);
|
||||||
|
} else {
|
||||||
|
await fd.writeULE32(0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function writeMPCParams(fd, curve, mpcParams) {
|
async function writeMPCParams(fd, curve, mpcParams) {
|
||||||
@ -382,9 +434,33 @@ async function writeMPCParams(fd, curve, mpcParams) {
|
|||||||
await binFileUtils.endWriteSection(fd);
|
await binFileUtils.endWriteSection(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hashG1(hasher, curve, p) {
|
||||||
|
const buff = new Uint8Array(curve.G1.F.n8*2);
|
||||||
|
curve.G1.toRprUncompressed(buff, 0, p);
|
||||||
|
hasher.update(buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hashG2(hasher,curve, p) {
|
||||||
|
const buff = new Uint8Array(curve.G2.F.n8*2);
|
||||||
|
curve.G2.toRprUncompressed(buff, 0, p);
|
||||||
|
hasher.update(buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hashPubKey(hasher, curve, c) {
|
||||||
|
hashG1(hasher, curve, c.deltaAfter);
|
||||||
|
hashG1(hasher, curve, c.delta.g1_s);
|
||||||
|
hashG1(hasher, curve, c.delta.g1_sx);
|
||||||
|
hashG2(hasher, curve, c.delta.g2_spx);
|
||||||
|
hasher.update(c.transcript);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports.readHeader = readHeader;
|
module.exports.readHeader = readHeader;
|
||||||
module.exports.writeHeader = writeHeader;
|
module.exports.writeHeader = writeHeader;
|
||||||
module.exports.read = readZKey;
|
module.exports.read = readZKey;
|
||||||
module.exports.write = writeZKey;
|
module.exports.write = writeZKey;
|
||||||
module.exports.readMPCParams = readMPCParams;
|
module.exports.readMPCParams = readMPCParams;
|
||||||
module.exports.writeMPCParams = writeMPCParams;
|
module.exports.writeMPCParams = writeMPCParams;
|
||||||
|
module.exports.hashG1 = hashG1;
|
||||||
|
module.exports.hashG2 = hashG2;
|
||||||
|
module.exports.hashPubKey = hashPubKey;
|
||||||
|
@ -9,6 +9,7 @@ const sameRatio = misc.sameRatio;
|
|||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
const ChaCha = require("ffjavascript").ChaCha;
|
const ChaCha = require("ffjavascript").ChaCha;
|
||||||
const newZKey = require("./zkey_new");
|
const newZKey = require("./zkey_new");
|
||||||
|
const {hashG1, hashPubKey} = require("./zkey_utils");
|
||||||
|
|
||||||
|
|
||||||
module.exports = async function phase2verify(r1csFileName, pTauFileName, zkeyFileName, verbose) {
|
module.exports = async function phase2verify(r1csFileName, pTauFileName, zkeyFileName, verbose) {
|
||||||
@ -34,8 +35,8 @@ module.exports = async function phase2verify(r1csFileName, pTauFileName, zkeyFi
|
|||||||
const c = mpcParams.contributions[i];
|
const c = mpcParams.contributions[i];
|
||||||
const ourHasher = misc.cloneHasher(accumulatedHasher);
|
const ourHasher = misc.cloneHasher(accumulatedHasher);
|
||||||
|
|
||||||
hashG1(ourHasher, c.delta.g1_s);
|
hashG1(ourHasher, curve, c.delta.g1_s);
|
||||||
hashG1(ourHasher, c.delta.g1_sx);
|
hashG1(ourHasher, curve, c.delta.g1_sx);
|
||||||
|
|
||||||
if (!misc.hashIsEqual(ourHasher.digest(), c.transcript)) {
|
if (!misc.hashIsEqual(ourHasher.digest(), c.transcript)) {
|
||||||
console.log(`INVALID(${i}): Inconsistent transcript `);
|
console.log(`INVALID(${i}): Inconsistent transcript `);
|
||||||
@ -56,10 +57,10 @@ module.exports = async function phase2verify(r1csFileName, pTauFileName, zkeyFi
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
hashPubKey(accumulatedHasher, c);
|
hashPubKey(accumulatedHasher, curve, c);
|
||||||
|
|
||||||
const contributionHasher = Blake2b(64);
|
const contributionHasher = Blake2b(64);
|
||||||
hashPubKey(contributionHasher, c);
|
hashPubKey(contributionHasher, curve, c);
|
||||||
responses.push(contributionHasher.digest());
|
responses.push(contributionHasher.digest());
|
||||||
|
|
||||||
curDelta = c.deltaAfter;
|
curDelta = c.deltaAfter;
|
||||||
@ -181,27 +182,6 @@ module.exports = async function phase2verify(r1csFileName, pTauFileName, zkeyFi
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
function hashG1(hasher, p) {
|
|
||||||
const buff = new Uint8Array(sG1);
|
|
||||||
curve.G1.toRprUncompressed(buff, 0, p);
|
|
||||||
hasher.update(buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
function hashG2(hasher, p) {
|
|
||||||
const buff = new Uint8Array(sG2);
|
|
||||||
curve.G2.toRprUncompressed(buff, 0, p);
|
|
||||||
hasher.update(buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
function hashPubKey(hasher, c) {
|
|
||||||
hashG1(hasher, c.deltaAfter);
|
|
||||||
hashG1(hasher, c.delta.g1_s);
|
|
||||||
hashG1(hasher, c.delta.g1_sx);
|
|
||||||
hashG2(hasher, c.delta.g2_spx);
|
|
||||||
hasher.update(c.transcript);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function sectionHasSameRatio(groupName, fd1, sections1, fd2, sections2, idSection, g2sp, g2spx, sectionName) {
|
async function sectionHasSameRatio(groupName, fd1, sections1, fd2, sections2, idSection, g2sp, g2spx, sectionName) {
|
||||||
const MAX_CHUNK_SIZE = 1<<20;
|
const MAX_CHUNK_SIZE = 1<<20;
|
||||||
|
Loading…
Reference in New Issue
Block a user