First try phase2
This commit is contained in:
parent
2d07b2c806
commit
b948a0d0d1
72
cli.js
72
cli.js
@ -38,11 +38,13 @@ const printR1cs = require("./src/printr1cs");
|
||||
|
||||
const clProcessor = require("./src/clprocessor");
|
||||
|
||||
const powersOfTaw = require("./src/powersoftaw");
|
||||
const powersOfTaw = require("./src/powersoftau");
|
||||
|
||||
const bn128 = require("ffjavascript").bn128;
|
||||
const solidityGenerator = require("./src/soliditygenerator.js");
|
||||
|
||||
const phase2 = require("./src/phase2");
|
||||
|
||||
const commands = [
|
||||
{
|
||||
cmd: "r1cs info [circuit.r1cs]",
|
||||
@ -103,62 +105,69 @@ const commands = [
|
||||
action: solidityGenCall
|
||||
},
|
||||
{
|
||||
cmd: "powersoftaw new <power> [powersoftaw_0000.ptaw]",
|
||||
description: "Starts a powers of taw ceremony",
|
||||
cmd: "powersoftau new <power> [powersoftau_0000.ptau]",
|
||||
description: "Starts a powers of tau ceremony",
|
||||
alias: ["ptn"],
|
||||
options: "-verbose|v",
|
||||
action: powersOfTawNew
|
||||
},
|
||||
{
|
||||
cmd: "powersoftaw export challange <powersoftaw_0000.ptaw> [challange]",
|
||||
cmd: "powersoftau export challange <powersoftau_0000.ptau> [challange]",
|
||||
description: "Creates a challange",
|
||||
alias: ["pte"],
|
||||
options: "-verbose|v",
|
||||
action: powersOfTawExportChallange
|
||||
},
|
||||
{
|
||||
cmd: "powersoftaw challange contribute <challange> [response]",
|
||||
cmd: "powersoftau challange contribute <challange> [response]",
|
||||
description: "Contribute to a challange",
|
||||
alias: ["ptcc"],
|
||||
options: "-verbose|v -entropy|e",
|
||||
action: powersOfTawChallangeContribute
|
||||
},
|
||||
{
|
||||
cmd: "powersoftaw import <powersoftaw_old.ptaw> <response> <<powersoftaw_new.ptaw>",
|
||||
description: "import a response to a ptaw file",
|
||||
cmd: "powersoftau import <powersoftau_old.ptau> <response> <<powersoftau_new.ptau>",
|
||||
description: "import a response to a ptau file",
|
||||
alias: ["pti"],
|
||||
options: "-verbose|v -nopoints -nocheck -description|d -name|n",
|
||||
action: powersOfTawImport
|
||||
},
|
||||
{
|
||||
cmd: "powersoftaw verify <powersoftaw.ptaw>",
|
||||
cmd: "powersoftau verify <powersoftau.ptau>",
|
||||
description: "verifies a powers of tau file",
|
||||
alias: ["ptv"],
|
||||
options: "-verbose|v",
|
||||
action: powersOfTawVerify
|
||||
},
|
||||
{
|
||||
cmd: "powersoftaw beacon <old_powersoftaw.ptaw> <new_powersoftaw.ptaw> <beaconHash(Hex)> <numIterationsExp>",
|
||||
cmd: "powersoftau beacon <old_powersoftau.ptau> <new_powersoftau.ptau> <beaconHash(Hex)> <numIterationsExp>",
|
||||
description: "adds a beacon",
|
||||
alias: ["ptb"],
|
||||
options: "-verbose|v -name|n",
|
||||
action: powersOfTawBeacon
|
||||
},
|
||||
{
|
||||
cmd: "powersoftaw contribute <powersoftaw.ptaw> <new_powersoftaw.ptaw>",
|
||||
cmd: "powersoftau contribute <powersoftau.ptau> <new_powersoftau.ptau>",
|
||||
description: "verifies a powers of tau file",
|
||||
alias: ["ptc"],
|
||||
options: "-verbose|v -name|n -entropy|e",
|
||||
action: powersOfTawContribute
|
||||
},
|
||||
{
|
||||
cmd: "powersoftaw prepare phase2 <powersoftaw.ptaw> <new_powersoftaw.ptaw>",
|
||||
cmd: "powersoftau prepare phase2 <powersoftau.ptau> <new_powersoftau.ptau>",
|
||||
description: "Prepares phase 2. ",
|
||||
longDescription: " This process calculates the evaluation of the Lagrange polinomials at tau for alpha*tau and beta tau",
|
||||
alias: ["pt2"],
|
||||
options: "-verbose|v",
|
||||
action: powersOfTawPreparePhase2
|
||||
},
|
||||
{
|
||||
cmd: "phase2 new [circuit.r1cs] [powersoftau.ptau] [circuit.zkey]",
|
||||
description: "Creates an initial pkey file with zero contributions ",
|
||||
alias: ["p2n"],
|
||||
options: "-verbose|v",
|
||||
action: phase2new
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
@ -504,7 +513,7 @@ async function solidityGenCall(params, options) {
|
||||
|
||||
async function powersOfTawNew(params, options) {
|
||||
let power;
|
||||
let ptawName;
|
||||
let ptauName;
|
||||
|
||||
power = parseInt(params[0]);
|
||||
if ((power<1) || (power>28)) {
|
||||
@ -512,19 +521,19 @@ async function powersOfTawNew(params, options) {
|
||||
}
|
||||
|
||||
if (params.length < 2) {
|
||||
ptawName = "powersOfTaw" + power + "_0000.ptaw";
|
||||
ptauName = "powersOfTaw" + power + "_0000.ptau";
|
||||
} else {
|
||||
ptawName = params[1];
|
||||
ptauName = params[1];
|
||||
}
|
||||
|
||||
return await powersOfTaw.newAccumulator(bn128, power, ptawName, options.verbose);
|
||||
return await powersOfTaw.newAccumulator(bn128, power, ptauName, options.verbose);
|
||||
}
|
||||
|
||||
async function powersOfTawExportChallange(params, options) {
|
||||
let ptawName;
|
||||
let ptauName;
|
||||
let challangeName;
|
||||
|
||||
ptawName = params[0];
|
||||
ptauName = params[0];
|
||||
|
||||
if (params.length < 2) {
|
||||
challangeName = "challange";
|
||||
@ -532,7 +541,7 @@ async function powersOfTawExportChallange(params, options) {
|
||||
challangeName = params[1];
|
||||
}
|
||||
|
||||
return await powersOfTaw.exportChallange(ptawName, challangeName, options.verbose);
|
||||
return await powersOfTaw.exportChallange(ptauName, challangeName, options.verbose);
|
||||
}
|
||||
|
||||
|
||||
@ -623,3 +632,30 @@ async function powersOfTawPreparePhase2(params, options) {
|
||||
return await powersOfTaw.preparePhase2(oldPtauName, newPtauName, options.verbose);
|
||||
}
|
||||
|
||||
|
||||
// phase2 new <circuit.r1cs> <powersoftau.ptau> <circuit.zkey>
|
||||
async function phase2new(params, options) {
|
||||
let r1csName;
|
||||
let ptauName;
|
||||
let zkeyName;
|
||||
|
||||
if (params.length < 1) {
|
||||
r1csName = "circuit.r1cs";
|
||||
} else {
|
||||
r1csName = params[0];
|
||||
}
|
||||
|
||||
if (params.length < 2) {
|
||||
ptauName = "powersoftau.ptau";
|
||||
} else {
|
||||
ptauName = params[1];
|
||||
}
|
||||
|
||||
if (params.length < 2) {
|
||||
zkeyName = "circuit.zkey";
|
||||
} else {
|
||||
zkeyName = params[2];
|
||||
}
|
||||
|
||||
return phase2.new(r1csName, ptauName, zkeyName, options.verbose);
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ async function endReadSection(fd, noCheck) {
|
||||
|
||||
async function writeBigInt(fd, n, n8) {
|
||||
const buff = new Uint8Array(n8);
|
||||
Scalar.toRprLE(buff, 0, n);
|
||||
Scalar.toRprLE(buff, 0, n, n8);
|
||||
await fd.write(buff);
|
||||
}
|
||||
|
||||
|
3
src/phase2.js
Normal file
3
src/phase2.js
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
module.exports.new = require("./phase2_new.js");
|
191
src/phase2_new.js
Normal file
191
src/phase2_new.js
Normal file
@ -0,0 +1,191 @@
|
||||
|
||||
const loadR1cs = require("r1csfile").load;
|
||||
const utils = require("./powersoftau_utils");
|
||||
const binFileUtils = require("./binfileutils");
|
||||
const writeZKey = require("./zkeyfile").write;
|
||||
const assert = require("assert");
|
||||
|
||||
|
||||
function log2( V )
|
||||
{
|
||||
return( ( ( V & 0xFFFF0000 ) !== 0 ? ( V &= 0xFFFF0000, 16 ) : 0 ) | ( ( V & 0xFF00FF00 ) !== 0 ? ( V &= 0xFF00FF00, 8 ) : 0 ) | ( ( V & 0xF0F0F0F0 ) !== 0 ? ( V &= 0xF0F0F0F0, 4 ) : 0 ) | ( ( V & 0xCCCCCCCC ) !== 0 ? ( V &= 0xCCCCCCCC, 2 ) : 0 ) | ( ( V & 0xAAAAAAAA ) !== 0 ) );
|
||||
}
|
||||
|
||||
|
||||
module.exports = async function phase2new(r1csName, ptauName, zkeyName) {
|
||||
|
||||
const r1cs = await loadR1cs(r1csName, true);
|
||||
|
||||
const {fd: ptauFd, sections} = await binFileUtils.readBinFile(ptauName, "ptau", 1);
|
||||
const {curve, power} = await utils.readPTauHeader(ptauFd, sections);
|
||||
|
||||
if (r1cs.prime != curve.r) {
|
||||
console.log("r1cs curve does not match powers of tau ceremony curve");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const cirPower = log2(r1cs.nConstraints + r1cs.nPubInputs + r1cs.nOutputs +1 -1) +1;
|
||||
|
||||
if (cirPower > power) {
|
||||
console.log(`circuit too big for this power of tau ceremony. ${r1cs.nConstraints} > 2**${power}`);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!sections[12]) {
|
||||
console.log("Powers of tau is not prepared.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const zKey = {
|
||||
|
||||
nPublic: r1cs.nOutputs + r1cs.nPubInputs,
|
||||
nVars: r1cs.nVars,
|
||||
q: curve.q,
|
||||
r: curve.r,
|
||||
domainBits: cirPower,
|
||||
domainSize: 1 << cirPower
|
||||
|
||||
};
|
||||
|
||||
const linc = 1 << (power - cirPower);
|
||||
|
||||
calculatePolinomials(curve, zKey,r1cs);
|
||||
|
||||
zKey.A = new Array(r1cs.nVars);
|
||||
zKey.B1 = new Array(r1cs.nVars);
|
||||
zKey.B2 = new Array(r1cs.nVars);
|
||||
zKey.C = new Array(r1cs.nVars);
|
||||
zKey.IC = new Array(zKey.nPublic+1);
|
||||
for (let i=0; i<r1cs.nVars; i++) {
|
||||
zKey.A[i] = curve.G1.zero;
|
||||
zKey.B1[i] = curve.G1.zero;
|
||||
zKey.B2[i] = curve.G2.zero;
|
||||
if (i>zKey.nPublic) {
|
||||
zKey.C[i] = curve.G1.zero;
|
||||
} else {
|
||||
zKey.IC[i] = curve.G1.zero;
|
||||
}
|
||||
}
|
||||
for (let i=0; i<zKey.ccoefs.length; i++) {
|
||||
const c = zKey.ccoefs[i];
|
||||
let CIC;
|
||||
if (c.matrix == 0) {
|
||||
const l1 = await readEvaluation("lTauG1", c.constraint);
|
||||
const l2 = await readEvaluation("lBetaTauG1", c.constraint);
|
||||
zKey.A[c.signal] =
|
||||
curve.G1.add(
|
||||
zKey.A[c.signal],
|
||||
curve.G1.mulScalar(l1, c.value)
|
||||
);
|
||||
CIC = curve.G1.mulScalar(l2, c.value);
|
||||
} else if (c.matrix == 1) {
|
||||
const l1 = await readEvaluation("lTauG1", c.constraint);
|
||||
const l2 = await readEvaluation("lTauG2", c.constraint);
|
||||
const l3 = await readEvaluation("lAlphaTauG1", c.constraint);
|
||||
zKey.B1[c.signal] =
|
||||
curve.G1.add(
|
||||
zKey.B1[c.signal],
|
||||
curve.G1.mulScalar(l1, c.value)
|
||||
);
|
||||
zKey.B2[c.signal] =
|
||||
curve.G2.add(
|
||||
zKey.B2[c.signal],
|
||||
curve.G2.mulScalar(l2, c.value)
|
||||
);
|
||||
CIC = curve.G1.mulScalar(l3, c.value);
|
||||
} else if (c.matrix == 2) {
|
||||
const l1 = await readEvaluation("lTauG1", c.constraint);
|
||||
CIC = curve.G1.mulScalar(l1, c.value);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (c.signal <= zKey.nPublic) {
|
||||
zKey.IC[c.signal] =
|
||||
curve.G1.add(
|
||||
zKey.IC[c.signal],
|
||||
CIC
|
||||
);
|
||||
} else {
|
||||
zKey.C[c.signal] =
|
||||
curve.G1.add(
|
||||
zKey.C[c.signal],
|
||||
CIC
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
zKey.hExps = new Array(zKey.domainSize-1);
|
||||
for (let i=0; i< zKey.domainSize; i++) {
|
||||
const t1 = await readEvaluation("tauG1", i);
|
||||
const t2 = await readEvaluation("tauG1", i+zKey.domainSize);
|
||||
zKey.hExps[i] = curve.G1.add(t1, t2);
|
||||
}
|
||||
|
||||
zKey.vk_alfa_1 = await readEvaluation("alphaTauG1", 0);
|
||||
zKey.vk_beta_1 = await readEvaluation("betaTauG1", 0);
|
||||
zKey.vk_delta_1 = curve.G1.g;
|
||||
zKey.vk_beta_2 = await readEvaluation("betaG2", 0);
|
||||
zKey.vk_gamma_2 = curve.G2.g;
|
||||
zKey.vk_delta_2 = curve.G2.g;
|
||||
|
||||
await writeZKey(zkeyName, zKey);
|
||||
|
||||
return 0;
|
||||
|
||||
async function readEvaluation(sectionName, idx) {
|
||||
let o;
|
||||
let G;
|
||||
switch (sectionName) {
|
||||
case "tauG1": o = sections[2][0].p; G = curve.G1; break;
|
||||
case "tauG2": o = sections[3][0].p; G = curve.G2; break;
|
||||
case "alphaTauG1": o = sections[4][0].p; G = curve.G1; break;
|
||||
case "betaTauG1": o = sections[5][0].p; G = curve.G1; break;
|
||||
case "betaG2": o = sections[6][0].p; G = curve.G2; break;
|
||||
case "lTauG1": o = sections[12][0].p; G = curve.G1; break;
|
||||
case "lTauG2": o = sections[13][0].p; G = curve.G2; break;
|
||||
case "lAlphaTauG1": o = sections[14][0].p; G = curve.G1; break;
|
||||
case "lBetaTauG1": o = sections[15][0].p; G = curve.G1; break;
|
||||
}
|
||||
const sG = G.F.n8*2;
|
||||
ptauFd.pos = o + sG*idx*linc;
|
||||
const buff = await ptauFd.read(sG);
|
||||
return G.fromRprLEM(buff, 0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
function calculatePolinomials(curve, zKey, r1cs) {
|
||||
|
||||
zKey.ccoefs = [];
|
||||
for (let m=0; m<2; m++) {
|
||||
for (let c=0; c<r1cs.nConstraints; c++) {
|
||||
const signals = Object.keys(r1cs.constraints[c][m]);
|
||||
signals.forEach( (s) => {
|
||||
zKey.ccoefs.push({
|
||||
matrix: m,
|
||||
constraint: c,
|
||||
signal: s,
|
||||
value: r1cs.constraints[c][m][s]
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add and process the constraints
|
||||
* input_i * 0 = 0
|
||||
* to ensure soundness of input consistency
|
||||
*/
|
||||
for (let i = 0; i < r1cs.nPubInputs + r1cs.nOutputs + 1; ++i)
|
||||
{
|
||||
zKey.ccoefs.push({
|
||||
matrix: 0,
|
||||
constraint: r1cs.nConstraints + i,
|
||||
signal: i,
|
||||
value: curve.Fr.one
|
||||
});
|
||||
}
|
||||
}
|
@ -3,20 +3,21 @@ const utils = require("./powersoftau_utils");
|
||||
const keyPair = require("./keypair");
|
||||
const assert = require("assert");
|
||||
const crypto = require("crypto");
|
||||
const buildTaskManager = require("./taskmanager");
|
||||
const binFileUtils = require("./binfileutils");
|
||||
const ChaCha = require("ffjavascript").ChaCha;
|
||||
|
||||
function sameRatio(curve, g1s, g1sx, g2s, g2sx) {
|
||||
async function sameRatio(curve, g1s, g1sx, g2s, g2sx) {
|
||||
if (curve.G1.isZero(g1s)) return false;
|
||||
if (curve.G1.isZero(g1sx)) return false;
|
||||
if (curve.G2.isZero(g2s)) return false;
|
||||
if (curve.G2.isZero(g2sx)) return false;
|
||||
return curve.F12.eq(curve.pairing(g1s, g2sx), curve.pairing(g1sx, g2s));
|
||||
// return curve.F12.eq(curve.pairing(g1s, g2sx), curve.pairing(g1sx, g2s));
|
||||
const res = await curve.pairingEq(g1s, g2sx, curve.G1.neg(g1sx), g2s);
|
||||
return res;
|
||||
}
|
||||
|
||||
function verifyContribution(curve, cur, prev) {
|
||||
|
||||
async function verifyContribution(curve, cur, prev) {
|
||||
let sr;
|
||||
if (cur.type == 1) { // Verify the beacon.
|
||||
const beaconKey = utils.keyFromBeacon(curve, prev.nextChallange, cur.beaconHash, cur.numIterationsExp);
|
||||
|
||||
@ -64,42 +65,50 @@ function verifyContribution(curve, cur, prev) {
|
||||
cur.key.alpha.g2_sp = keyPair.getG2sp(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);
|
||||
|
||||
if (!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) {
|
||||
console.log("INVALID key (tau) in challange #"+cur.id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sameRatio(curve, cur.key.alpha.g1_s, cur.key.alpha.g1_sx, cur.key.alpha.g2_sp, cur.key.alpha.g2_spx)) {
|
||||
sr = await sameRatio(curve, cur.key.alpha.g1_s, cur.key.alpha.g1_sx, cur.key.alpha.g2_sp, cur.key.alpha.g2_spx);
|
||||
if (sr !== true) {
|
||||
console.log("INVALID key (alpha) in challange #"+cur.id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sameRatio(curve, cur.key.beta.g1_s, cur.key.beta.g1_sx, cur.key.beta.g2_sp, cur.key.beta.g2_spx)) {
|
||||
sr = await sameRatio(curve, cur.key.beta.g1_s, cur.key.beta.g1_sx, cur.key.beta.g2_sp, cur.key.beta.g2_spx);
|
||||
if (sr !== true) {
|
||||
console.log("INVALID key (beta) in challange #"+cur.id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sameRatio(curve, prev.tauG1, cur.tauG1, cur.key.tau.g2_sp, cur.key.tau.g2_spx)) {
|
||||
sr = await sameRatio(curve, prev.tauG1, cur.tauG1, cur.key.tau.g2_sp, cur.key.tau.g2_spx);
|
||||
if (sr !== true) {
|
||||
console.log("INVALID tau*G1. challange #"+cur.id+" It does not follow the previous contribution");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sameRatio(curve, cur.key.tau.g1_s, cur.key.tau.g1_sx, prev.tauG2, cur.tauG2,)) {
|
||||
sr = await sameRatio(curve, cur.key.tau.g1_s, cur.key.tau.g1_sx, prev.tauG2, cur.tauG2);
|
||||
if (sr !== true) {
|
||||
console.log("INVALID tau*G2. challange #"+cur.id+" It does not follow the previous contribution");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sameRatio(curve, prev.alphaG1, cur.alphaG1, cur.key.alpha.g2_sp, cur.key.alpha.g2_spx)) {
|
||||
sr = await sameRatio(curve, prev.alphaG1, cur.alphaG1, cur.key.alpha.g2_sp, cur.key.alpha.g2_spx);
|
||||
if (sr !== true) {
|
||||
console.log("INVALID alpha*G1. challange #"+cur.id+" It does not follow the previous contribution");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sameRatio(curve, prev.betaG1, cur.betaG1, cur.key.beta.g2_sp, cur.key.beta.g2_spx)) {
|
||||
sr = await sameRatio(curve, prev.betaG1, cur.betaG1, cur.key.beta.g2_sp, cur.key.beta.g2_spx);
|
||||
if (sr !== true) {
|
||||
console.log("INVALID beta*G1. challange #"+cur.id+" It does not follow the previous contribution");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sameRatio(curve, cur.key.beta.g1_s, cur.key.beta.g1_sx, prev.betaG2, cur.betaG2,)) {
|
||||
sr = await sameRatio(curve, cur.key.beta.g1_s, cur.key.beta.g1_sx, prev.betaG2, cur.betaG2);
|
||||
if (sr !== true) {
|
||||
console.log("INVALID beta*G2. challange #"+cur.id+"It does not follow the previous contribution");
|
||||
return false;
|
||||
}
|
||||
@ -108,6 +117,7 @@ function verifyContribution(curve, cur, prev) {
|
||||
}
|
||||
|
||||
async function verify(tauFilename, verbose) {
|
||||
let sr;
|
||||
await Blake2b.ready();
|
||||
|
||||
const {fd, sections} = await binFileUtils.readBinFile(tauFilename, "ptau", 1);
|
||||
@ -141,7 +151,7 @@ async function verify(tauFilename, verbose) {
|
||||
}
|
||||
const curContr = contrs[contrs.length-1];
|
||||
if (verbose) console.log("Validating contribution #"+contrs[contrs.length-1].id);
|
||||
const res = verifyContribution(curve, curContr,prevContr, verbose);
|
||||
const res = await verifyContribution(curve, curContr,prevContr, verbose);
|
||||
if (!res) return false;
|
||||
|
||||
|
||||
@ -156,7 +166,8 @@ async function verify(tauFilename, verbose) {
|
||||
// Verify Section tau*G1
|
||||
if (verbose) console.log("Verifying powers in tau*G1 section");
|
||||
const rTau1 = await processSection(2, "G1", "tauG1", (1 << power)*2-1, [0, 1]);
|
||||
if (!sameRatio(curve, rTau1.R1, rTau1.R2, curve.G2.g, curContr.tauG2)) {
|
||||
sr = await sameRatio(curve, rTau1.R1, rTau1.R2, curve.G2.g, curContr.tauG2);
|
||||
if (sr !== true) {
|
||||
console.log("tauG1 section. Powers do not match");
|
||||
return false;
|
||||
}
|
||||
@ -174,7 +185,8 @@ async function verify(tauFilename, verbose) {
|
||||
// Verify Section tau*G2
|
||||
if (verbose) console.log("Verifying powers in tau*G2 section");
|
||||
const rTau2 = await processSection(3, "G2", "tauG2", 1 << power, [0, 1]);
|
||||
if (!sameRatio(curve, curve.G1.g, curContr.tauG1, rTau2.R1, rTau2.R2)) {
|
||||
sr = await sameRatio(curve, curve.G1.g, curContr.tauG1, rTau2.R1, rTau2.R2);
|
||||
if (sr !== true) {
|
||||
console.log("tauG2 section. Powers do not match");
|
||||
return false;
|
||||
}
|
||||
@ -190,7 +202,8 @@ async function verify(tauFilename, verbose) {
|
||||
// Verify Section alpha*tau*G1
|
||||
if (verbose) console.log("Verifying powers in alpha*tau*G1 section");
|
||||
const rAlphaTauG1 = await processSection(4, "G1", "alphatauG1", 1 << power, [0]);
|
||||
if (!sameRatio(curve, rAlphaTauG1.R1, rAlphaTauG1.R2, curve.G2.g, curContr.tauG2)) {
|
||||
sr = await sameRatio(curve, rAlphaTauG1.R1, rAlphaTauG1.R2, curve.G2.g, curContr.tauG2);
|
||||
if (sr !== true) {
|
||||
console.log("alphaTauG1 section. Powers do not match");
|
||||
return false;
|
||||
}
|
||||
@ -202,7 +215,8 @@ async function verify(tauFilename, verbose) {
|
||||
// Verify Section beta*tau*G1
|
||||
if (verbose) console.log("Verifying powers in beta*tau*G1 section");
|
||||
const rBetaTauG1 = await processSection(5, "G1", "betatauG1", 1 << power, [0]);
|
||||
if (!sameRatio(curve, rBetaTauG1.R1, rBetaTauG1.R2, curve.G2.g, curContr.tauG2)) {
|
||||
sr = await sameRatio(curve, rBetaTauG1.R1, rBetaTauG1.R2, curve.G2.g, curContr.tauG2);
|
||||
if (sr !== true) {
|
||||
console.log("betaTauG1 section. Powers do not match");
|
||||
return false;
|
||||
}
|
||||
@ -238,7 +252,7 @@ async function verify(tauFilename, verbose) {
|
||||
for (let i = contrs.length-2; i>=0; i--) {
|
||||
const curContr = contrs[i];
|
||||
const prevContr = (curContr>0) ? contrs[i-1] : initialContribution;
|
||||
verifyContribution(curve, curContr, prevContr);
|
||||
await verifyContribution(curve, curContr, prevContr);
|
||||
printContribution(curContr, prevContr);
|
||||
}
|
||||
console.log("-----------------------------------------------------");
|
||||
|
177
src/zkeyfile.js
177
src/zkeyfile.js
@ -32,10 +32,18 @@ const Scalar = require("ffjavascript").Scalar;
|
||||
const F1Field = require("ffjavascript").F1Field;
|
||||
const assert = require("assert");
|
||||
const binFileUtils = require("./binfileutils");
|
||||
const bn128 = require("ffjavascript").bn128;
|
||||
|
||||
module.exports.write = async function writeZKey(fileName, zkey) {
|
||||
|
||||
const fd = await binFileUtils.createOverride(fileName,"zkey", 6, 1);
|
||||
let curve;
|
||||
if (Scalar.eq(zkey.q, bn128.q)) {
|
||||
curve = bn128;
|
||||
} else {
|
||||
assert(false, fd.fileName +": Curve not supported");
|
||||
}
|
||||
|
||||
const fd = await binFileUtils.createBinFile(fileName,"zkey", 1, 9);
|
||||
|
||||
// Write the header
|
||||
///////////
|
||||
@ -48,20 +56,17 @@ module.exports.write = async function writeZKey(fileName, zkey) {
|
||||
|
||||
await binFileUtils.startWriteSection(fd, 2);
|
||||
const primeQ = zkey.q;
|
||||
const Fq = new F1Field(zkey.q);
|
||||
const n8q = (Math.floor( (Scalar.bitLength(primeQ) - 1) / 64) +1)*8;
|
||||
const Rq = Scalar.mod(Scalar.shl(1, n8q*8), primeQ);
|
||||
|
||||
const primeR = zkey.r;
|
||||
const Fr = new F1Field(zkey.r);
|
||||
const n8r = (Math.floor( (Scalar.bitLength(primeR) - 1) / 64) +1)*8;
|
||||
const Rr = Scalar.mod(Scalar.shl(1, n8r*8), primeR);
|
||||
const R2r = Scalar.mod(Scalar.mul(Rr,Rr), primeR);
|
||||
|
||||
await fd.writeULE32(n8q);
|
||||
await binFileUtils.writeBigInt(primeQ, n8q);
|
||||
await binFileUtils.writeBigInt(fd, primeQ, n8q);
|
||||
await fd.writeULE32(n8r);
|
||||
await binFileUtils.writeBigInt(primeR, n8r);
|
||||
await binFileUtils.writeBigInt(fd, primeR, n8r);
|
||||
await fd.writeULE32(zkey.nVars); // Total number of bars
|
||||
await fd.writeULE32(zkey.nPublic); // Total number of public vars (not including ONE)
|
||||
await fd.writeULE32(zkey.domainSize); // domainSize
|
||||
@ -98,24 +103,43 @@ module.exports.write = async function writeZKey(fileName, zkey) {
|
||||
await binFileUtils.endWriteSection(fd);
|
||||
|
||||
|
||||
// Write A B1 B2 C points
|
||||
|
||||
// Write A
|
||||
///////////
|
||||
await binFileUtils.startWriteSection(fd, 5);
|
||||
for (let i=0; i<zkey.nVars; i++) {
|
||||
await writePointG1(zkey.A[i]);
|
||||
await writePointG1(zkey.B1[i]);
|
||||
await writePointG2(zkey.B2[i]);
|
||||
if (i<=zkey.nPublic) {
|
||||
await writePointG1_zero();
|
||||
} else {
|
||||
await writePointG1(zkey.C[i]);
|
||||
}
|
||||
}
|
||||
await binFileUtils.endWriteSection(fd);
|
||||
|
||||
// Write H points
|
||||
// Write B1
|
||||
///////////
|
||||
await binFileUtils.startWriteSection(fd, 6);
|
||||
for (let i=0; i<zkey.nVars; i++) {
|
||||
await writePointG1(zkey.B1[i]);
|
||||
}
|
||||
await binFileUtils.endWriteSection(fd);
|
||||
|
||||
// Write B2
|
||||
///////////
|
||||
await binFileUtils.startWriteSection(fd, 7);
|
||||
for (let i=0; i<zkey.nVars; i++) {
|
||||
await writePointG2(zkey.B2[i]);
|
||||
}
|
||||
await binFileUtils.endWriteSection(fd);
|
||||
|
||||
// Write C
|
||||
///////////
|
||||
await binFileUtils.startWriteSection(fd, 8);
|
||||
for (let i=zkey.nPublic+1; i<zkey.nVars; i++) {
|
||||
await writePointG1(zkey.C[i]);
|
||||
}
|
||||
await binFileUtils.endWriteSection(fd);
|
||||
|
||||
|
||||
// Write H points
|
||||
///////////
|
||||
await binFileUtils.startWriteSection(fd, 9);
|
||||
for (let i=0; i<zkey.domainSize; i++) {
|
||||
await writePointG1(zkey.hExps[i]);
|
||||
}
|
||||
@ -130,41 +154,16 @@ module.exports.write = async function writeZKey(fileName, zkey) {
|
||||
await binFileUtils.writeBigInt(fd, n, n8r);
|
||||
}
|
||||
|
||||
async function writeFq(n) {
|
||||
// Convert to montgomery
|
||||
n = Scalar.mod( Scalar.mul(n, Rq), primeQ);
|
||||
|
||||
await binFileUtils.writeBigInt(fd, n, n8q);
|
||||
}
|
||||
|
||||
async function writePointG1(p) {
|
||||
if (Fq.isZero(p[2])) {
|
||||
await writeFq(0);
|
||||
await writeFq(0);
|
||||
} else {
|
||||
await writeFq(p[0]);
|
||||
await writeFq(p[1]);
|
||||
}
|
||||
}
|
||||
|
||||
async function writePointG1_zero() {
|
||||
await writeFq(0);
|
||||
await writeFq(0);
|
||||
const buff = new Uint8Array(curve.G1.F.n8*2);
|
||||
curve.G1.toRprLEM(buff, 0, p);
|
||||
await fd.write(buff);
|
||||
}
|
||||
|
||||
async function writePointG2(p) {
|
||||
if (Fq.isZero(p[2][0]) && Fq.isZero(p[2][1])) {
|
||||
await writeFq(Fq.e(0));
|
||||
await writeFq(Fq.e(0));
|
||||
await writeFq(Fq.e(0));
|
||||
await writeFq(Fq.e(0));
|
||||
|
||||
} else {
|
||||
await writeFq(p[0][0]);
|
||||
await writeFq(p[0][1]);
|
||||
await writeFq(p[1][0]);
|
||||
await writeFq(p[1][1]);
|
||||
}
|
||||
const buff = new Uint8Array(curve.G2.F.n8*2);
|
||||
curve.G2.toRprLEM(buff, 0, p);
|
||||
await fd.write(buff);
|
||||
}
|
||||
};
|
||||
|
||||
@ -197,6 +196,12 @@ module.exports.read = async function readZKey(fileName) {
|
||||
const Rri = Fr.inv(Rr);
|
||||
const Rri2 = Fr.mul(Rri, Rri);
|
||||
|
||||
let curve;
|
||||
if (Scalar.eq(zkey.q, bn128.q)) {
|
||||
curve = bn128;
|
||||
} else {
|
||||
assert(false, fd.fileName +": Curve not supported");
|
||||
}
|
||||
|
||||
zkey.nVars = await fd.readULE32();
|
||||
zkey.nPublic = await fd.readULE32();
|
||||
@ -240,32 +245,55 @@ module.exports.read = async function readZKey(fileName) {
|
||||
}
|
||||
await binFileUtils.endReadSection(fd);
|
||||
|
||||
// Read A B1 B2 C points
|
||||
// Read A points
|
||||
///////////
|
||||
await binFileUtils.startReadUniqueSection(fd, sections, 5);
|
||||
zkey.A = [];
|
||||
zkey.B1 = [];
|
||||
zkey.B2 = [];
|
||||
zkey.C = [];
|
||||
for (let i=0; i<zkey.nVars; i++) {
|
||||
const A = await readG1();
|
||||
const B1 = await readG1();
|
||||
const B2 = await readG2();
|
||||
const C = await readG1();
|
||||
|
||||
zkey.A.push(A);
|
||||
zkey.B1.push(B1);
|
||||
zkey.B2.push(B2);
|
||||
zkey.C.push(C);
|
||||
if (i<= zkey.nPublic) {
|
||||
assert(Fr.isZero(C[2]), "C value for public is not zero");
|
||||
}
|
||||
zkey.A[i] = A;
|
||||
}
|
||||
await binFileUtils.endReadSection(fd);
|
||||
|
||||
// Read H points
|
||||
|
||||
// Read B1
|
||||
///////////
|
||||
await binFileUtils.startReadUniqueSection(fd, sections, 6);
|
||||
zkey.B1 = [];
|
||||
for (let i=0; i<zkey.nVars; i++) {
|
||||
const B1 = await readG1();
|
||||
|
||||
zkey.B1[i] = B1;
|
||||
}
|
||||
await binFileUtils.endReadSection(fd);
|
||||
|
||||
|
||||
// Read B2 points
|
||||
///////////
|
||||
await binFileUtils.startReadUniqueSection(fd, sections, 7);
|
||||
zkey.B2 = [];
|
||||
for (let i=0; i<zkey.nVars; i++) {
|
||||
const B2 = await readG2();
|
||||
zkey.B2[i] = B2;
|
||||
}
|
||||
await binFileUtils.endReadSection(fd);
|
||||
|
||||
|
||||
// Read C points
|
||||
///////////
|
||||
await binFileUtils.startReadUniqueSection(fd, sections, 8);
|
||||
zkey.C = [];
|
||||
for (let i=zkey.nPublic+1; i<zkey.nVars; i++) {
|
||||
const C = await readG1();
|
||||
|
||||
zkey.C[i] = C;
|
||||
}
|
||||
await binFileUtils.endReadSection(fd);
|
||||
|
||||
|
||||
// Read H points
|
||||
///////////
|
||||
await binFileUtils.startReadUniqueSection(fd, sections, 9);
|
||||
zkey.hExps = [];
|
||||
for (let i=0; i<zkey.domainSize; i++) {
|
||||
const H = await readG1();
|
||||
@ -277,36 +305,19 @@ module.exports.read = async function readZKey(fileName) {
|
||||
|
||||
return zkey;
|
||||
|
||||
async function readFq() {
|
||||
const n = await binFileUtils.readBigInt(fd, n8q);
|
||||
return Fq.mul(n, Rqi);
|
||||
}
|
||||
|
||||
async function readFr2() {
|
||||
const n = await binFileUtils.readBigInt(fd, n8r);
|
||||
return Fr.mul(n, Rri2);
|
||||
}
|
||||
|
||||
async function readG1() {
|
||||
const x = await readFq();
|
||||
const y = await readFq();
|
||||
if (Fq.isZero(x) && Fq.isZero(y)) {
|
||||
return [Fq.e(0), Fq.e(1), Fq.e(0)];
|
||||
} else {
|
||||
return [x , y, Fq.e(1)];
|
||||
}
|
||||
const buff = await fd.read(curve.G1.F.n8*2);
|
||||
return curve.G1.fromRprLEM(buff, 0);
|
||||
}
|
||||
|
||||
async function readG2() {
|
||||
const xa = await readFq();
|
||||
const xb = await readFq();
|
||||
const ya = await readFq();
|
||||
const yb = await readFq();
|
||||
if (Fq.isZero(xa) && Fq.isZero(xb) && Fq.isZero(ya) && Fq.isZero(yb)) {
|
||||
return [[Fq.e(0),Fq.e(0)],[Fq.e(1),Fq.e(0)], [Fq.e(0),Fq.e(0)]];
|
||||
} else {
|
||||
return [[xa, xb],[ya, yb], [Fq.e(1),Fq.e(0)]];
|
||||
}
|
||||
const buff = await fd.read(curve.G2.F.n8*2);
|
||||
return curve.G2.fromRprLEM(buff, 0);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user