plonk prover random numbers works

This commit is contained in:
Jordi Baylina 2021-05-24 07:17:07 +02:00
parent 7ed350002d
commit 1e89672bec
No known key found for this signature in database
GPG Key ID: 7480C80C1BE43112
6 changed files with 353 additions and 252 deletions

View File

@ -63,10 +63,9 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
await calculateAdditions(); await calculateAdditions();
let A,B,C,Z; let A,B,C,Z;
let A4, B4, C4, Z4;
let pol_a,pol_b,pol_c, pol_z, pol_t, pol_r; let pol_a,pol_b,pol_c, pol_z, pol_t, pol_r;
let proof = {}; let proof = {};
if (logger) logger.debug("Reading L Points");
const lagrangeBases = await binFileUtils.readSection(fdZKey, sectionsZKey, 14);
const sigmaBuff = new BigBuffer(zkey.domainSize*n8r*4*3); const sigmaBuff = new BigBuffer(zkey.domainSize*n8r*4*3);
let o = sectionsZKey[12][0].p + zkey.domainSize*n8r; let o = sectionsZKey[12][0].p + zkey.domainSize*n8r;
@ -82,12 +81,10 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
const pol_s2 = new BigBuffer(zkey.domainSize*n8r); const pol_s2 = new BigBuffer(zkey.domainSize*n8r);
await fdZKey.readToBuffer(pol_s2, 0 , zkey.domainSize*n8r, sectionsZKey[12][0].p + 5*zkey.domainSize*n8r); await fdZKey.readToBuffer(pol_s2, 0 , zkey.domainSize*n8r, sectionsZKey[12][0].p + 5*zkey.domainSize*n8r);
const PTau = await binFileUtils.readSection(fdZKey, sectionsZKey, 15); const PTau = await binFileUtils.readSection(fdZKey, sectionsZKey, 14);
let alpha, beta, gamma, xi; const ch = {};
let xim;
const b=[];
await round1(); await round1();
await round2(); await round2();
@ -112,14 +109,14 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
publicSignals.push(Scalar.fromRprLE(pub)); publicSignals.push(Scalar.fromRprLE(pub));
} }
proof.A = G1.toObject(G1.toAffine(proof.A)); proof.A = G1.toObject(proof.A);
proof.B = G1.toObject(G1.toAffine(proof.B)); proof.B = G1.toObject(proof.B);
proof.C = G1.toObject(G1.toAffine(proof.C)); proof.C = G1.toObject(proof.C);
proof.Z = G1.toObject(G1.toAffine(proof.Z)); proof.Z = G1.toObject(proof.Z);
proof.T1 = G1.toObject(G1.toAffine(proof.T1)); proof.T1 = G1.toObject(proof.T1);
proof.T2 = G1.toObject(G1.toAffine(proof.T2)); proof.T2 = G1.toObject(proof.T2);
proof.T3 = G1.toObject(G1.toAffine(proof.T3)); proof.T3 = G1.toObject(proof.T3);
proof.eval_a = Fr.toObject(proof.eval_a); proof.eval_a = Fr.toObject(proof.eval_a);
proof.eval_b = Fr.toObject(proof.eval_b); proof.eval_b = Fr.toObject(proof.eval_b);
@ -130,8 +127,8 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
proof.eval_t = Fr.toObject(proof.eval_t); proof.eval_t = Fr.toObject(proof.eval_t);
proof.eval_r = Fr.toObject(proof.eval_r); proof.eval_r = Fr.toObject(proof.eval_r);
proof.Wxi = G1.toObject(G1.toAffine(proof.Wxi)); proof.Wxi = G1.toObject(proof.Wxi);
proof.Wxiw = G1.toObject(G1.toAffine(proof.Wxiw)); proof.Wxiw = G1.toObject(proof.Wxiw);
proof = stringifyBigInts(proof); proof = stringifyBigInts(proof);
publicSignals = stringifyBigInts(publicSignals); publicSignals = stringifyBigInts(publicSignals);
@ -161,9 +158,9 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
} }
async function buildABC() { async function buildABC() {
const A = new BigBuffer(zkey.domainSize * n8r); let A = new BigBuffer(zkey.domainSize * n8r);
const B = new BigBuffer(zkey.domainSize * n8r); let B = new BigBuffer(zkey.domainSize * n8r);
const C = new BigBuffer(zkey.domainSize * n8r); let C = new BigBuffer(zkey.domainSize * n8r);
const aMap = await binFileUtils.readSection(fdZKey, sectionsZKey, 4); const aMap = await binFileUtils.readSection(fdZKey, sectionsZKey, 4);
const bMap = await binFileUtils.readSection(fdZKey, sectionsZKey, 5); const bMap = await binFileUtils.readSection(fdZKey, sectionsZKey, 5);
@ -177,7 +174,11 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
const iC = readUInt32(cMap, i*4); const iC = readUInt32(cMap, i*4);
C.set(getWitness(iC), i*n8r); C.set(getWitness(iC), i*n8r);
} }
A = await Fr.batchToMontgomery(A);
B = await Fr.batchToMontgomery(B);
C = await Fr.batchToMontgomery(C);
return [A,B,C]; return [A,B,C];
} }
@ -198,32 +199,21 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
} }
async function round1() { async function round1() {
ch.b = [];
for (let i=1; i<=9; i++) { for (let i=1; i<=9; i++) {
b[i] = curve.Fr.random(); ch.b[i] = curve.Fr.random();
b[i] = curve.Fr.e(i);
// b[i] = curve.Fr.zero;
} }
[A, B, C] = await buildABC(); [A, B, C] = await buildABC();
[pol_a, A4] = await to4T(A, [ch.b[2], ch.b[1]]);
[pol_b, B4] = await to4T(B, [ch.b[4], ch.b[3]]);
[pol_c, C4] = await to4T(C, [ch.b[6], ch.b[5]]);
proof.A = await curve.G1.multiExpAffine(lagrangeBases, A, logger, "multiexp A"); proof.A = await expTau(pol_a, "multiexp A");
proof.B = await curve.G1.multiExpAffine(lagrangeBases, B, logger, "multiexp B"); proof.B = await expTau(pol_b, "multiexp B");
proof.C = await curve.G1.multiExpAffine(lagrangeBases, C, logger, "multiexp C"); proof.C = await expTau(pol_c, "multiexp C");
proof.A = G1.add(proof.A, G1.timesFr(zkey.XtoMplus1, b[1]));
proof.A = G1.sub(proof.A, G1.timesFr(zkey.X, b[1]));
proof.A = G1.add(proof.A, G1.timesFr(zkey.XtoM, b[2]));
proof.A = G1.sub(proof.A, G1.timesFr(G1.one, b[2]));
proof.B = G1.add(proof.B, G1.timesFr(zkey.XtoMplus1, b[3]));
proof.B = G1.sub(proof.B, G1.timesFr(zkey.X, b[3]));
proof.B = G1.add(proof.B, G1.timesFr(zkey.XtoM, b[4]));
proof.B = G1.sub(proof.B, G1.timesFr(G1.one, b[4]));
proof.C = G1.add(proof.C, G1.timesFr(zkey.XtoMplus1, b[5]));
proof.C = G1.sub(proof.C, G1.timesFr(zkey.X, b[5]));
proof.C = G1.add(proof.C, G1.timesFr(zkey.XtoM, b[6]));
proof.C = G1.sub(proof.C, G1.timesFr(G1.one, b[6]));
} }
async function round2() { async function round2() {
@ -233,18 +223,14 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
G1.toRprUncompressed(transcript1, G1.F.n8*2, proof.B); G1.toRprUncompressed(transcript1, G1.F.n8*2, proof.B);
G1.toRprUncompressed(transcript1, G1.F.n8*4, proof.C); G1.toRprUncompressed(transcript1, G1.F.n8*4, proof.C);
beta = hashToFr(transcript1); ch.beta = hashToFr(transcript1);
if (logger) logger.debug("beta: " + Fr.toString(beta)); if (logger) logger.debug("beta: " + Fr.toString(ch.beta));
const transcript2 = new Uint8Array(n8r); const transcript2 = new Uint8Array(n8r);
Fr.toRprBE(transcript2, 0, beta); Fr.toRprBE(transcript2, 0, ch.beta);
gamma = hashToFr(transcript2); ch.gamma = hashToFr(transcript2);
if (logger) logger.debug("gamma: " + Fr.toString(gamma)); if (logger) logger.debug("gamma: " + Fr.toString(ch.gamma));
A = await Fr.batchToMontgomery(A);
B = await Fr.batchToMontgomery(B);
C = await Fr.batchToMontgomery(C);
let numArr = new BigBuffer(Fr.n8*zkey.domainSize); let numArr = new BigBuffer(Fr.n8*zkey.domainSize);
let denArr = new BigBuffer(Fr.n8*zkey.domainSize); let denArr = new BigBuffer(Fr.n8*zkey.domainSize);
@ -254,30 +240,30 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
let w = Fr.one; let w = Fr.one;
for (let i=0; i<zkey.domainSize; i++) { for (let i=0; i<zkey.domainSize; i++) {
let n1 = A.slice(i*n8r, (i+1)*n8r); let n1 = A.slice(i*n8r, (i+1)*n8r);
n1 = Fr.add( n1, Fr.mul(beta, w) ); n1 = Fr.add( n1, Fr.mul(ch.beta, w) );
n1 = Fr.add( n1, gamma ); n1 = Fr.add( n1, ch.gamma );
let n2 = B.slice(i*n8r, (i+1)*n8r); let n2 = B.slice(i*n8r, (i+1)*n8r);
n2 = Fr.add( n2, Fr.mul(zkey.k1, Fr.mul(beta, w) )); n2 = Fr.add( n2, Fr.mul(zkey.k1, Fr.mul(ch.beta, w) ));
n2 = Fr.add( n2, gamma ); n2 = Fr.add( n2, ch.gamma );
let n3 = C.slice(i*n8r, (i+1)*n8r); let n3 = C.slice(i*n8r, (i+1)*n8r);
n3 = Fr.add( n3, Fr.mul(zkey.k2, Fr.mul(beta, w) )); n3 = Fr.add( n3, Fr.mul(zkey.k2, Fr.mul(ch.beta, w) ));
n3 = Fr.add( n3, gamma ); n3 = Fr.add( n3, ch.gamma );
const num = Fr.mul(n1, Fr.mul(n2, n3)); const num = Fr.mul(n1, Fr.mul(n2, n3));
let d1 = A.slice(i*n8r, (i+1)*n8r); let d1 = A.slice(i*n8r, (i+1)*n8r);
d1 = Fr.add(d1, Fr.mul( sigmaBuff.slice(i*n8r*4, i*n8r*4 + n8r) , beta)); d1 = Fr.add(d1, Fr.mul( sigmaBuff.slice(i*n8r*4, i*n8r*4 + n8r) , ch.beta));
d1 = Fr.add(d1, gamma); d1 = Fr.add(d1, ch.gamma);
let d2 = B.slice(i*n8r, (i+1)*n8r); let d2 = B.slice(i*n8r, (i+1)*n8r);
d2 = Fr.add(d2, Fr.mul( sigmaBuff.slice((zkey.domainSize + i)*4*n8r, (zkey.domainSize + i)*4*n8r+n8r) , beta)); d2 = Fr.add(d2, Fr.mul( sigmaBuff.slice((zkey.domainSize + i)*4*n8r, (zkey.domainSize + i)*4*n8r+n8r) , ch.beta));
d2 = Fr.add(d2, gamma); d2 = Fr.add(d2, ch.gamma);
let d3 = C.slice(i*n8r, (i+1)*n8r); let d3 = C.slice(i*n8r, (i+1)*n8r);
d3 = Fr.add(d3, Fr.mul( sigmaBuff.slice((zkey.domainSize*2 + i)*4*n8r, (zkey.domainSize*2 + i)*4*n8r + n8r) , beta)); d3 = Fr.add(d3, Fr.mul( sigmaBuff.slice((zkey.domainSize*2 + i)*4*n8r, (zkey.domainSize*2 + i)*4*n8r + n8r) , ch.beta));
d3 = Fr.add(d3, gamma); d3 = Fr.add(d3, ch.gamma);
const den = Fr.mul(d1, Fr.mul(d2, d3)); const den = Fr.mul(d1, Fr.mul(d2, d3));
@ -311,27 +297,23 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
throw new Error("Copy constraints does not match"); throw new Error("Copy constraints does not match");
} }
Z = numArr.slice(0, zkey.domainSize*n8r); Z = numArr;
numArr = await Fr.batchFromMontgomery(numArr);
proof.Z = await curve.G1.multiExpAffine(lagrangeBases, numArr, logger, "multiexp Z"); [pol_z, Z4] = await to4T(Z, [ch.b[9], ch.b[8], ch.b[7]]);
proof.Z = G1.add(proof.Z, G1.timesFr(zkey.XtoMplus2, b[7])); proof.Z = await expTau( pol_z, "multiexp Z");
proof.Z = G1.sub(proof.Z, G1.timesFr(zkey.Xto2, b[7]));
proof.Z = G1.add(proof.Z, G1.timesFr(zkey.XtoMplus1, b[8]));
proof.Z = G1.sub(proof.Z, G1.timesFr(zkey.X, b[8]));
proof.Z = G1.add(proof.Z, G1.timesFr(zkey.XtoM, b[9]));
proof.Z = G1.sub(proof.Z, G1.timesFr(G1.one, b[9]));
} }
async function round3() { async function round3() {
/*
async function checkDegree(P) { async function checkDegree(P) {
const p = await curve.Fr.ifft(P); const p = await curve.Fr.ifft(P);
let deg = (P.byteLength/n8r)-1; let deg = (P.byteLength/n8r)-1;
while ((deg>0)&&(Fr.isZero(p.slice(deg*n8r, deg*n8r+n8r)))) deg--; while ((deg>0)&&(Fr.isZero(p.slice(deg*n8r, deg*n8r+n8r)))) deg--;
return deg; return deg;
} }
*/
function printPol(P) { function printPol(P) {
const n=(P.byteLength/n8r); const n=(P.byteLength/n8r);
@ -362,14 +344,31 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
const transcript3 = new Uint8Array(G1.F.n8*2); const transcript3 = new Uint8Array(G1.F.n8*2);
G1.toRprUncompressed(transcript3, 0, proof.Z); G1.toRprUncompressed(transcript3, 0, proof.Z);
alpha = hashToFr(transcript3); ch.alpha = hashToFr(transcript3);
if (logger) logger.debug("alpha: " + Fr.toString(alpha)); if (logger) logger.debug("alpha: " + Fr.toString(ch.alpha));
let A4; [pol_a, A4] = await to4T(A);
let B4; [pol_b, B4] = await to4T(B); const Z1 = [
let C4; [pol_c, C4] = await to4T(C); Fr.zero,
let Z4; [pol_z, Z4] = await to4T(Z); Fr.add(Fr.e(-1), Fr.w[2]),
Fr.e(-2),
Fr.sub(Fr.e(-1), Fr.w[2]),
];
const Z2 = [
Fr.zero,
Fr.add(Fr.zero, Fr.mul(Fr.e(-2), Fr.w[2])),
Fr.e(4),
Fr.sub(Fr.zero, Fr.mul(Fr.e(-2), Fr.w[2])),
];
const Z3 = [
Fr.zero,
Fr.add(Fr.e(2), Fr.mul(Fr.e(2), Fr.w[2])),
Fr.e(-8),
Fr.sub(Fr.e(2), Fr.mul(Fr.e(2), Fr.w[2])),
];
/* /*
const Zw = new BigBuffer(zkey.domainSize*4*n8r); const Zw = new BigBuffer(zkey.domainSize*4*n8r);
@ -385,6 +384,7 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
console.log("degZw: " + degZw); console.log("degZw: " + degZw);
*/ */
const T = new BigBuffer(zkey.domainSize*4*n8r); const T = new BigBuffer(zkey.domainSize*4*n8r);
const Tz = new BigBuffer(zkey.domainSize*4*n8r);
let w = Fr.one; let w = Fr.one;
for (let i=0; i<zkey.domainSize*4; i++) { for (let i=0; i<zkey.domainSize*4; i++) {
@ -401,6 +401,14 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
const s1 = sigmaBuff.slice(i*n8r, i*n8r+n8r); const s1 = sigmaBuff.slice(i*n8r, i*n8r+n8r);
const s2 = sigmaBuff.slice((i+zkey.domainSize*4)*n8r, (i+zkey.domainSize*4)*n8r+n8r); const s2 = sigmaBuff.slice((i+zkey.domainSize*4)*n8r, (i+zkey.domainSize*4)*n8r+n8r);
const s3 = sigmaBuff.slice((i+zkey.domainSize*8)*n8r, (i+zkey.domainSize*8)*n8r+n8r); const s3 = sigmaBuff.slice((i+zkey.domainSize*8)*n8r, (i+zkey.domainSize*8)*n8r+n8r);
const ap = Fr.add(ch.b[2], Fr.mul(ch.b[1], w));
const bp = Fr.add(ch.b[4], Fr.mul(ch.b[3], w));
const cp = Fr.add(ch.b[6], Fr.mul(ch.b[5], w));
const w2 = Fr.square(w);
const zp = Fr.add(Fr.add(Fr.mul(ch.b[7], w2), Fr.mul(ch.b[8], w)), ch.b[9]);
const wW = Fr.mul(w, Fr.w[zkey.power]);
const wW2 = Fr.square(wW);
const zWp = Fr.add(Fr.add(Fr.mul(ch.b[7], wW2), Fr.mul(ch.b[8], wW)), ch.b[9]);
let pl = Fr.zero; let pl = Fr.zero;
for (let j=0; j<zkey.nPublic; j++) { for (let j=0; j<zkey.nPublic; j++) {
@ -410,53 +418,71 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
)); ));
} }
let e1 = Fr.mul(Fr.mul(a, b), qm); let [e1, e1z] = mul2(a, b, ap, bp, i%4);
e1 = Fr.mul(e1, qm);
e1z = Fr.mul(e1z, qm);
e1 = Fr.add(e1, Fr.mul(a, ql)); e1 = Fr.add(e1, Fr.mul(a, ql));
e1z = Fr.add(e1z, Fr.mul(ap, ql));
e1 = Fr.add(e1, Fr.mul(b, qr)); e1 = Fr.add(e1, Fr.mul(b, qr));
e1z = Fr.add(e1z, Fr.mul(bp, qr));
e1 = Fr.add(e1, Fr.mul(c, qo)); e1 = Fr.add(e1, Fr.mul(c, qo));
e1z = Fr.add(e1z, Fr.mul(cp, qo));
e1 = Fr.add(e1, pl); e1 = Fr.add(e1, pl);
e1 = Fr.add(e1, qc); e1 = Fr.add(e1, qc);
const betaw = Fr.mul(beta, w); const betaw = Fr.mul(ch.beta, w);
let e2a =a; let e2a =a;
e2a = Fr.add(e2a, betaw); e2a = Fr.add(e2a, betaw);
e2a = Fr.add(e2a, gamma); e2a = Fr.add(e2a, ch.gamma);
let e2b =b; let e2b =b;
e2b = Fr.add(e2b, Fr.mul(betaw, zkey.k1)); e2b = Fr.add(e2b, Fr.mul(betaw, zkey.k1));
e2b = Fr.add(e2b, gamma); e2b = Fr.add(e2b, ch.gamma);
let e2c =c; let e2c =c;
e2c = Fr.add(e2c, Fr.mul(betaw, zkey.k2)); e2c = Fr.add(e2c, Fr.mul(betaw, zkey.k2));
e2c = Fr.add(e2c, gamma); e2c = Fr.add(e2c, ch.gamma);
let e2 = Fr.mul(Fr.mul(e2a, e2b), e2c); let e2d = z;
e2 = Fr.mul(e2, z);
e2 = Fr.mul(e2, alpha); let [e2, e2z] = mul4(e2a, e2b, e2c, e2d, ap, bp, cp, zp, i%4);
e2 = Fr.mul(e2, ch.alpha);
e2z = Fr.mul(e2z, ch.alpha);
let e3a = a; let e3a = a;
e3a = Fr.add(e3a, Fr.mul(beta, s1)); e3a = Fr.add(e3a, Fr.mul(ch.beta, s1));
e3a = Fr.add(e3a, gamma); e3a = Fr.add(e3a, ch.gamma);
let e3b = b; let e3b = b;
e3b = Fr.add(e3b, Fr.mul(beta,s2)); e3b = Fr.add(e3b, Fr.mul(ch.beta,s2));
e3b = Fr.add(e3b, gamma); e3b = Fr.add(e3b, ch.gamma);
let e3c = c; let e3c = c;
e3c = Fr.add(e3c, Fr.mul(beta,s3)); e3c = Fr.add(e3c, Fr.mul(ch.beta,s3));
e3c = Fr.add(e3c, gamma); e3c = Fr.add(e3c, ch.gamma);
let e3 = Fr.mul(Fr.mul(e3a, e3b), e3c); let e3d = zw;
e3 = Fr.mul(e3, zw); let [e3, e3z] = mul4(e3a, e3b, e3c, e3d, ap, bp, cp, zWp, i%4);
e3 = Fr.mul(e3, alpha);
e3 = Fr.mul(e3, ch.alpha);
e3z = Fr.mul(e3z, ch.alpha);
let e4 = Fr.sub(z, Fr.one); let e4 = Fr.sub(z, Fr.one);
e4 = Fr.mul(e4, lPols.slice( (zkey.domainSize + i)*n8r, (zkey.domainSize+i+1)*n8r)); e4 = Fr.mul(e4, lPols.slice( (zkey.domainSize + i)*n8r, (zkey.domainSize+i+1)*n8r));
e4 = Fr.mul(e4, Fr.mul(alpha, alpha)); e4 = Fr.mul(e4, Fr.mul(ch.alpha, ch.alpha));
let e4z = Fr.mul(zp, lPols.slice( (zkey.domainSize + i)*n8r, (zkey.domainSize+i+1)*n8r));
e4z = Fr.mul(e4z, Fr.mul(ch.alpha, ch.alpha));
let e = Fr.add(Fr.sub(Fr.add(e1, e2), e3), e4); let e = Fr.add(Fr.sub(Fr.add(e1, e2), e3), e4);
let ez = Fr.add(Fr.sub(Fr.add(e1z, e2z), e3z), e4z);
T.set(e, i*n8r); T.set(e, i*n8r);
Tz.set(ez, i*n8r);
w = Fr.mul(w, Fr.w[zkey.power+2]); w = Fr.mul(w, Fr.w[zkey.power+2]);
} }
@ -482,21 +508,97 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
} }
} }
pol_t = t.slice(0, (zkey.domainSize*3)*n8r); const tz = await Fr.ifft(Tz);
printPol(tz);
for (let i=0; i<zkey.domainSize*4; i++) {
const a = tz.slice(i*n8r, (i+1)*n8r);
if (i > (zkey.domainSize*3 +5) ) {
if (!Fr.isZero(a)) {
throw new Error("Tz Polynomial is not well calculated");
}
} else {
t.set(
Fr.add(
t.slice(i*n8r, (i+1)*n8r),
a
),
i*n8r
);
}
}
t = await Fr.batchFromMontgomery(t); pol_t = t.slice(0, (zkey.domainSize*3+6)*n8r);
proof.T1 = await curve.G1.multiExpAffine(PTau, t.slice(0, zkey.domainSize*n8r), logger, "multiexp T1"); proof.T1 = await expTau( t.slice(0, zkey.domainSize*n8r) , "multiexp T1");
proof.T2 = await curve.G1.multiExpAffine(PTau, t.slice(zkey.domainSize*n8r, zkey.domainSize*2*n8r), logger, "multiexp T2"); proof.T2 = await expTau( t.slice(zkey.domainSize*n8r, zkey.domainSize*2*n8r) , "multiexp T2");
proof.T3 = await curve.G1.multiExpAffine(PTau, t.slice(zkey.domainSize*2*n8r, (zkey.domainSize*3)*n8r), logger, "multiexp T3"); proof.T3 = await expTau( t.slice(zkey.domainSize*2*n8r, (zkey.domainSize*3+6)*n8r) , "multiexp T3");
function mul2(a,b, ap, bp, p) {
let r, rz;
async function to4T(A) {
const a = await Fr.ifft(A); const a_b = Fr.mul(a,b);
const a4 = new BigBuffer(n8r*zkey.domainSize*4); const a_bp = Fr.mul(a,bp);
a4.set(a, 0); const ap_b = Fr.mul(ap,b);
const A4 = await Fr.fft(a4); const ap_bp = Fr.mul(ap,bp);
return [a, A4];
r = a_b;
let a0 = Fr.add(a_bp, ap_b);
let a1 = ap_bp;
rz = a0;
if (p) {
rz = Fr.add(rz, Fr.mul(Z1[p], a1));
}
return [r, rz];
}
function mul4(a,b,c,d, ap, bp, cp, dp, p) {
let r, rz;
const a_b = Fr.mul(a,b);
const a_bp = Fr.mul(a,bp);
const ap_b = Fr.mul(ap,b);
const ap_bp = Fr.mul(ap,bp);
const c_d = Fr.mul(c,d);
const c_dp = Fr.mul(c,dp);
const cp_d = Fr.mul(cp,d);
const cp_dp = Fr.mul(cp,dp);
r = Fr.mul(a_b, c_d);
let a0 = Fr.mul(ap_b, c_d);
a0 = Fr.add(a0, Fr.mul(a_bp, c_d));
a0 = Fr.add(a0, Fr.mul(a_b, cp_d));
a0 = Fr.add(a0, Fr.mul(a_b, c_dp));
let a1 = Fr.mul(ap_bp, c_d);
a1 = Fr.add(a1, Fr.mul(ap_b, cp_d));
a1 = Fr.add(a1, Fr.mul(ap_b, c_dp));
a1 = Fr.add(a1, Fr.mul(a_bp, cp_d));
a1 = Fr.add(a1, Fr.mul(a_bp, c_dp));
a1 = Fr.add(a1, Fr.mul(a_b, cp_dp));
let a2 = Fr.mul(a_bp, cp_dp);
a2 = Fr.add(a2, Fr.mul(ap_b, cp_dp));
a2 = Fr.add(a2, Fr.mul(ap_bp, c_dp));
a2 = Fr.add(a2, Fr.mul(ap_bp, cp_d));
let a3 = Fr.mul(ap_bp, cp_dp);
rz = a0;
if (p) {
rz = Fr.add(rz, Fr.mul(Z1[p], a1));
rz = Fr.add(rz, Fr.mul(Z2[p], a2));
rz = Fr.add(rz, Fr.mul(Z3[p], a3));
}
return [r, rz];
} }
} }
@ -523,74 +625,76 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
G1.toRprUncompressed(transcript4, 0, proof.T1); G1.toRprUncompressed(transcript4, 0, proof.T1);
G1.toRprUncompressed(transcript4, G1.F.n8*2, proof.T2); G1.toRprUncompressed(transcript4, G1.F.n8*2, proof.T2);
G1.toRprUncompressed(transcript4, G1.F.n8*4, proof.T3); G1.toRprUncompressed(transcript4, G1.F.n8*4, proof.T3);
xi = hashToFr(transcript4); ch.xi = hashToFr(transcript4);
if (logger) logger.debug("xi: " + Fr.toString(xi)); if (logger) logger.debug("xi: " + Fr.toString(ch.xi));
proof.eval_a = evalPol(pol_a, xi); proof.eval_a = evalPol(pol_a, ch.xi);
proof.eval_b = evalPol(pol_b, xi); proof.eval_b = evalPol(pol_b, ch.xi);
proof.eval_c = evalPol(pol_c, xi); proof.eval_c = evalPol(pol_c, ch.xi);
proof.eval_s1 = evalPol(pol_s1, xi); proof.eval_s1 = evalPol(pol_s1, ch.xi);
proof.eval_s2 = evalPol(pol_s2, xi); proof.eval_s2 = evalPol(pol_s2, ch.xi);
proof.eval_t = evalPol(pol_t, xi); proof.eval_t = evalPol(pol_t, ch.xi);
proof.eval_zw = evalPol(pol_z, Fr.mul(xi, Fr.w[zkey.power])); proof.eval_zw = evalPol(pol_z, Fr.mul(ch.xi, Fr.w[zkey.power]));
const coef_ab = Fr.mul(proof.eval_a, proof.eval_b); const coef_ab = Fr.mul(proof.eval_a, proof.eval_b);
let e2a = proof.eval_a; let e2a = proof.eval_a;
const betaxi = Fr.mul(beta, xi); const betaxi = Fr.mul(ch.beta, ch.xi);
e2a = Fr.add( e2a, betaxi); e2a = Fr.add( e2a, betaxi);
e2a = Fr.add( e2a, gamma); e2a = Fr.add( e2a, ch.gamma);
let e2b = proof.eval_b; let e2b = proof.eval_b;
e2b = Fr.add( e2b, Fr.mul(betaxi, zkey.k1)); e2b = Fr.add( e2b, Fr.mul(betaxi, zkey.k1));
e2b = Fr.add( e2b, gamma); e2b = Fr.add( e2b, ch.gamma);
let e2c = proof.eval_c; let e2c = proof.eval_c;
e2c = Fr.add( e2c, Fr.mul(betaxi, zkey.k2)); e2c = Fr.add( e2c, Fr.mul(betaxi, zkey.k2));
e2c = Fr.add( e2c, gamma); e2c = Fr.add( e2c, ch.gamma);
const e2 = Fr.mul(Fr.mul(Fr.mul(e2a, e2b), e2c), alpha); const e2 = Fr.mul(Fr.mul(Fr.mul(e2a, e2b), e2c), ch.alpha);
let e3a = proof.eval_a; let e3a = proof.eval_a;
e3a = Fr.add( e3a, Fr.mul(beta, proof.eval_s1)); e3a = Fr.add( e3a, Fr.mul(ch.beta, proof.eval_s1));
e3a = Fr.add( e3a, gamma); e3a = Fr.add( e3a, ch.gamma);
let e3b = proof.eval_b; let e3b = proof.eval_b;
e3b = Fr.add( e3b, Fr.mul(beta, proof.eval_s2)); e3b = Fr.add( e3b, Fr.mul(ch.beta, proof.eval_s2));
e3b = Fr.add( e3b, gamma); e3b = Fr.add( e3b, ch.gamma);
let e3 = Fr.mul(e3a, e3b); let e3 = Fr.mul(e3a, e3b);
e3 = Fr.mul(e3, beta); e3 = Fr.mul(e3, ch.beta);
e3 = Fr.mul(e3, proof.eval_zw); e3 = Fr.mul(e3, proof.eval_zw);
e3 = Fr.mul(e3, alpha); e3 = Fr.mul(e3, ch.alpha);
xim= xi; ch.xim= ch.xi;
for (let i=0; i<zkey.power; i++) xim = Fr.mul(xim, xim); for (let i=0; i<zkey.power; i++) ch.xim = Fr.mul(ch.xim, ch.xim);
const eval_l1 = Fr.div( const eval_l1 = Fr.div(
Fr.sub(xim, Fr.one), Fr.sub(ch.xim, Fr.one),
Fr.mul(Fr.sub(xi, Fr.one), Fr.e(zkey.domainSize)) Fr.mul(Fr.sub(ch.xi, Fr.one), Fr.e(zkey.domainSize))
); );
const e4 = Fr.mul(eval_l1, Fr.mul(alpha, alpha)); const e4 = Fr.mul(eval_l1, Fr.mul(ch.alpha, ch.alpha));
const coefs3 = e3; const coefs3 = e3;
const coefz = Fr.add(e2, e4); const coefz = Fr.add(e2, e4);
pol_r = new BigBuffer(zkey.domainSize*n8r); pol_r = new BigBuffer((zkey.domainSize+3)*n8r);
for (let i = 0; i<zkey.domainSize; i++) { for (let i = 0; i<zkey.domainSize+3; i++) {
let v = Fr.mul(coef_ab, pol_qm.slice(i*n8r,(i+1)*n8r)); let v = Fr.mul(coefz, pol_z.slice(i*n8r,(i+1)*n8r));
v = Fr.add(v, Fr.mul(proof.eval_a, pol_ql.slice(i*n8r,(i+1)*n8r))); if (i<zkey.domainSize) {
v = Fr.add(v, Fr.mul(proof.eval_b, pol_qr.slice(i*n8r,(i+1)*n8r))); v = Fr.add(v, Fr.mul(coef_ab, pol_qm.slice(i*n8r,(i+1)*n8r)));
v = Fr.add(v, Fr.mul(proof.eval_c, pol_qo.slice(i*n8r,(i+1)*n8r))); v = Fr.add(v, Fr.mul(proof.eval_a, pol_ql.slice(i*n8r,(i+1)*n8r)));
v = Fr.add(v, pol_qc.slice(i*n8r,(i+1)*n8r)); v = Fr.add(v, Fr.mul(proof.eval_b, pol_qr.slice(i*n8r,(i+1)*n8r)));
v = Fr.add(v, Fr.mul(coefz, pol_z.slice(i*n8r,(i+1)*n8r))); v = Fr.add(v, Fr.mul(proof.eval_c, pol_qo.slice(i*n8r,(i+1)*n8r)));
v = Fr.sub(v, Fr.mul(coefs3, pol_s3.slice(i*n8r,(i+1)*n8r))); v = Fr.add(v, pol_qc.slice(i*n8r,(i+1)*n8r));
v = Fr.sub(v, Fr.mul(coefs3, pol_s3.slice(i*n8r,(i+1)*n8r)));
}
pol_r.set(v, i*n8r); pol_r.set(v, i*n8r);
} }
proof.eval_r = evalPol(pol_r, xi); proof.eval_r = evalPol(pol_r, ch.xi);
} }
async function round5() { async function round5() {
@ -603,55 +707,56 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
Fr.toRprBE(transcript5, n8r*5, proof.eval_zw); Fr.toRprBE(transcript5, n8r*5, proof.eval_zw);
Fr.toRprBE(transcript5, n8r*6, proof.eval_t); Fr.toRprBE(transcript5, n8r*6, proof.eval_t);
Fr.toRprBE(transcript5, n8r*7, proof.eval_r); Fr.toRprBE(transcript5, n8r*7, proof.eval_r);
const v = []; ch.v = [];
v[1] = hashToFr(transcript5); ch.v[1] = hashToFr(transcript5);
if (logger) logger.debug("v: " + Fr.toString(v[1])); if (logger) logger.debug("v: " + Fr.toString(ch.v[1]));
for (let i=2; i<=6; i++ ) v[i] = Fr.mul(v[i-1], v[1]); for (let i=2; i<=6; i++ ) ch.v[i] = Fr.mul(ch.v[i-1], ch.v[1]);
let pol_wxi = new BigBuffer((zkey.domainSize+6)*n8r);
// TODO DELETE const xi2m = Fr.mul(ch.xim, ch.xim);
// v[1] = Fr.zero;
// v[2] = Fr.zero;
// v[3] = Fr.zero;
// v[4] = Fr.zero;
// v[5] = Fr.zero;
// v[6] = Fr.zero;
let pol_wxi = new BigBuffer(zkey.domainSize*n8r); for (let i=0; i<zkey.domainSize+6; i++) {
const xi2m = Fr.mul(xim, xim);
for (let i=0; i<zkey.domainSize; i++) {
let w = Fr.zero; let w = Fr.zero;
w = Fr.add(w, pol_t.slice(i*n8r, (i+1)*n8r));
w = Fr.add(w, Fr.mul(xim, pol_t.slice( (zkey.domainSize+i)*n8r, (zkey.domainSize+i+1)*n8r )));
w = Fr.add(w, Fr.mul(xi2m, pol_t.slice( (zkey.domainSize*2+i)*n8r, (zkey.domainSize*2+i+1)*n8r ))); w = Fr.add(w, Fr.mul(xi2m, pol_t.slice( (zkey.domainSize*2+i)*n8r, (zkey.domainSize*2+i+1)*n8r )));
w = Fr.add(w, Fr.mul(v[1], pol_r.slice(i*n8r, (i+1)*n8r))); if (i<zkey.domainSize+3) {
w = Fr.add(w, Fr.mul(v[2], pol_a.slice(i*n8r, (i+1)*n8r))); w = Fr.add(w, Fr.mul(ch.v[1], pol_r.slice(i*n8r, (i+1)*n8r)));
w = Fr.add(w, Fr.mul(v[3], pol_b.slice(i*n8r, (i+1)*n8r))); }
w = Fr.add(w, Fr.mul(v[4], pol_c.slice(i*n8r, (i+1)*n8r)));
w = Fr.add(w, Fr.mul(v[5], pol_s1.slice(i*n8r, (i+1)*n8r))); if (i<zkey.domainSize+2) {
w = Fr.add(w, Fr.mul(v[6], pol_s2.slice(i*n8r, (i+1)*n8r))); w = Fr.add(w, Fr.mul(ch.v[2], pol_a.slice(i*n8r, (i+1)*n8r)));
w = Fr.add(w, Fr.mul(ch.v[3], pol_b.slice(i*n8r, (i+1)*n8r)));
w = Fr.add(w, Fr.mul(ch.v[4], pol_c.slice(i*n8r, (i+1)*n8r)));
}
if (i<zkey.domainSize) {
w = Fr.add(w, pol_t.slice(i*n8r, (i+1)*n8r));
w = Fr.add(w, Fr.mul(ch.xim, pol_t.slice( (zkey.domainSize+i)*n8r, (zkey.domainSize+i+1)*n8r )));
w = Fr.add(w, Fr.mul(ch.v[5], pol_s1.slice(i*n8r, (i+1)*n8r)));
w = Fr.add(w, Fr.mul(ch.v[6], pol_s2.slice(i*n8r, (i+1)*n8r)));
}
pol_wxi.set(w, i*n8r); pol_wxi.set(w, i*n8r);
} }
let w0 = pol_wxi.slice(0, n8r); let w0 = pol_wxi.slice(0, n8r);
w0 = Fr.sub(w0, proof.eval_t); w0 = Fr.sub(w0, proof.eval_t);
w0 = Fr.sub(w0, Fr.mul(v[1], proof.eval_r)); w0 = Fr.sub(w0, Fr.mul(ch.v[1], proof.eval_r));
w0 = Fr.sub(w0, Fr.mul(v[2], proof.eval_a)); w0 = Fr.sub(w0, Fr.mul(ch.v[2], proof.eval_a));
w0 = Fr.sub(w0, Fr.mul(v[3], proof.eval_b)); w0 = Fr.sub(w0, Fr.mul(ch.v[3], proof.eval_b));
w0 = Fr.sub(w0, Fr.mul(v[4], proof.eval_c)); w0 = Fr.sub(w0, Fr.mul(ch.v[4], proof.eval_c));
w0 = Fr.sub(w0, Fr.mul(v[5], proof.eval_s1)); w0 = Fr.sub(w0, Fr.mul(ch.v[5], proof.eval_s1));
w0 = Fr.sub(w0, Fr.mul(v[6], proof.eval_s2)); w0 = Fr.sub(w0, Fr.mul(ch.v[6], proof.eval_s2));
pol_wxi.set(w0, 0); pol_wxi.set(w0, 0);
pol_wxi= divPol1(pol_wxi, xi); pol_wxi= divPol1(pol_wxi, ch.xi);
pol_wxi = await Fr.batchFromMontgomery(pol_wxi);
proof.Wxi = await curve.G1.multiExpAffine(PTau, pol_wxi, logger, "multiexp Wxi");
let pol_wxiw = new BigBuffer(zkey.domainSize*n8r); proof.Wxi = await expTau(pol_wxi, "multiexp Wxi");
for (let i=0; i<zkey.domainSize; i++) {
let pol_wxiw = new BigBuffer((zkey.domainSize+3)*n8r);
for (let i=0; i<zkey.domainSize+3; i++) {
const w = pol_z.slice(i*n8r, (i+1)*n8r); const w = pol_z.slice(i*n8r, (i+1)*n8r);
pol_wxiw.set(w, i*n8r); pol_wxiw.set(w, i*n8r);
} }
@ -659,11 +764,8 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
w0 = Fr.sub(w0, proof.eval_zw); w0 = Fr.sub(w0, proof.eval_zw);
pol_wxiw.set(w0, 0); pol_wxiw.set(w0, 0);
pol_wxiw= divPol1(pol_wxiw, Fr.mul(ch.xi, Fr.w[zkey.power]));
pol_wxiw= divPol1(pol_wxiw, Fr.mul(xi, Fr.w[zkey.power])); proof.Wxiw = await expTau(pol_wxiw, "multiexp Wxiw");
pol_wxiw = await Fr.batchFromMontgomery(pol_wxiw);
proof.Wxiw = await curve.G1.multiExpAffine(PTau, pol_wxiw, logger, "multiexp Wxiw");
} }
function hashToFr(transcript) { function hashToFr(transcript) {
@ -710,6 +812,46 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
} }
return res; return res;
} }
async function expTau(b, name) {
const n = b.byteLength/n8r;
const PTauN = PTau.slice(0, n*curve.G1.F.n8*2);
const bm = await curve.Fr.batchFromMontgomery(b);
let res = await curve.G1.multiExpAffine(PTauN, bm, logger, name);
res = curve.G1.toAffine(res);
return res;
}
async function to4T(A, pz) {
pz = pz || [];
let a = await Fr.ifft(A);
const a4 = new BigBuffer(n8r*zkey.domainSize*4);
a4.set(a, 0);
const a1 = new BigBuffer(n8r*(zkey.domainSize + pz.length));
a1.set(a, 0);
for (let i= 0; i<pz.length; i++) {
a1.set(
Fr.add(
a1.slice((zkey.domainSize+i)*n8r, (zkey.domainSize+i+1)*n8r),
pz[i]
),
(zkey.domainSize+i)*n8r
);
a1.set(
Fr.sub(
a1.slice(i*n8r, (i+1)*n8r),
pz[i]
),
i*n8r
);
}
const A4 = await Fr.fft(a4);
return [a1, A4];
}
} }

View File

@ -104,18 +104,12 @@ export default async function plonkSetup(r1csName, ptauName, zkeyName, logger) {
await writeSigma(12, "sigma"); await writeSigma(12, "sigma");
await writeLs(13, "lagrange polynomials"); await writeLs(13, "lagrange polynomials");
// Write Lagrange Points Section
///////////
await startWriteSection(fdZKey, 14);
await fdZKey.write(LPoints);
await endWriteSection(fdZKey);
// Write PTau points // Write PTau points
//////////// ////////////
await startWriteSection(fdZKey, 15); await startWriteSection(fdZKey, 14);
const buffOut = new BigBuffer(domainSize*sG1); const buffOut = new BigBuffer((domainSize+6)*sG1);
await fdPTau.readToBuffer(buffOut, 0, domainSize*sG1, sectionsPTau[2][0].p); await fdPTau.readToBuffer(buffOut, 0, (domainSize+6)*sG1, sectionsPTau[2][0].p);
await fdZKey.write(buffOut); await fdZKey.write(buffOut);
await endWriteSection(fdZKey); await endWriteSection(fdZKey);
@ -385,26 +379,6 @@ export default async function plonkSetup(r1csName, ptauName, zkeyName, logger) {
await fdZKey.write(k1); await fdZKey.write(k1);
await fdZKey.write(k2); await fdZKey.write(k2);
let bX;
bX = await fdPTau.read(sG1, sectionsPTau[2][0].p + sG1);
await fdZKey.write(bX);
let bX2;
bX2 = await fdPTau.read(sG1, sectionsPTau[2][0].p + sG1*2);
await fdZKey.write(bX2);
let bXtoM;
bXtoM = await fdPTau.read(sG1, sectionsPTau[2][0].p + sG1*domainSize);
await fdZKey.write(bXtoM);
let bXtoMplus1;
bXtoMplus1 = await fdPTau.read(sG1, sectionsPTau[2][0].p + sG1*(domainSize+1));
await fdZKey.write(bXtoMplus1);
let bXtoMplus2;
bXtoMplus2 = await fdPTau.read(sG1, sectionsPTau[2][0].p + sG1*(domainSize+2));
await fdZKey.write(bXtoMplus2);
await fdZKey.write(G1.toAffine(vk.Qm)); await fdZKey.write(G1.toAffine(vk.Qm));
await fdZKey.write(G1.toAffine(vk.Ql)); await fdZKey.write(G1.toAffine(vk.Ql));
await fdZKey.write(G1.toAffine(vk.Qr)); await fdZKey.write(G1.toAffine(vk.Qr));

View File

@ -208,15 +208,6 @@ function calculateChallanges(curve, proof) {
G1.toRprUncompressed(transcript6, G1.F.n8*2, proof.Wxiw); G1.toRprUncompressed(transcript6, G1.F.n8*2, proof.Wxiw);
res.u = hashToFr(curve, transcript6); res.u = hashToFr(curve, transcript6);
// TODO: remove
// res.v[1] = Fr.zero;
// res.v[2] = Fr.zero;
// res.v[3] = Fr.zero;
// res.v[4] = Fr.zero;
// res.v[5] = Fr.zero;
// res.v[6] = Fr.zero;
// res.u = Fr.zero;
return res; return res;
} }

View File

@ -268,12 +268,6 @@ async function readHeaderPlonk(fd, sections, protocol, toObject) {
zkey.k1 = await fd.read(n8r); zkey.k1 = await fd.read(n8r);
zkey.k2 = await fd.read(n8r); zkey.k2 = await fd.read(n8r);
zkey.X = await readG1(fd, curve, toObject);
zkey.Xto2 = await readG1(fd, curve, toObject);
zkey.XtoM = await readG1(fd, curve, toObject);
zkey.XtoMplus1 = await readG1(fd, curve, toObject);
zkey.XtoMplus2 = await readG1(fd, curve, toObject);
zkey.Qm = await readG1(fd, curve, toObject); zkey.Qm = await readG1(fd, curve, toObject);
zkey.Ql = await readG1(fd, curve, toObject); zkey.Ql = await readG1(fd, curve, toObject);
zkey.Qr = await readG1(fd, curve, toObject); zkey.Qr = await readG1(fd, curve, toObject);

Binary file not shown.

View File

@ -1,55 +1,55 @@
{ {
"A": [ "A": [
"15743209584538732831984522947865045943191698736126835167107429821444692635700", "8839447420316742728199672120007516770398996562499593209826233055164831459834",
"15304499734695470270217999401312954213615077608391938626547048969059391815770", "16189635412848654749378322490220441430077839960004046391626438625637726226000",
"1" "1"
], ],
"B": [ "B": [
"3011437941647082010337336879820112189520787585056958119182126144516922325699", "17465184056494179801925813691588125272949911271611543454528130157857909913246",
"14293021774310121677905381158509930628442641616993815871854561496752240048132", "869328347486379578626658936503731002520626692524913211521742050768236719305",
"1" "1"
], ],
"C": [ "C": [
"17023913191405186346489422835812580810015512803033000441904349097055703180515", "19519544555708553879767666138947412440629548042175907283737565586445507479903",
"11228876974248468319926028828930973923072635393190630092554386478523728646602", "17669026430269534969805497624294901955270334914625983358714826411609764475804",
"1" "1"
], ],
"Z": [ "Z": [
"21787485149860139414155053903444419266452989172629957435807448984274998525743", "3346839295724370624732530222814040339873780027932771271059227118623825895313",
"2537376736563984101921166856341942675021784850064711527768725712244516210693", "10771064980375572846317420996468711290464809627547728487032820584132296464087",
"1" "1"
], ],
"T1": [ "T1": [
"9982560943557310174756809994489647193274022193173772342571072376360853826159", "6168675305758589840782279635487697914964888136358086288899584897562377682341",
"2193374861650642053413940227444385900509799625539732490553578296834818806014", "1310251258624946189756801650980878849173726360620822836933820834682621444297",
"1" "1"
], ],
"T2": [ "T2": [
"1935051902238074558682471125149626614935744241552612922092977226651069265819", "16452753478240443931891239628843197353427455171472174094729996434600044435135",
"15728245714470497509947599396234528395359156386509927514699449257668858437022", "8929495594150478290096744687495763476858314760863627578988262303134274489344",
"1" "1"
], ],
"T3": [ "T3": [
"18565050802152066143639524874000298798967497331659460012952465075688981418065", "19819502442073307622314428521645368167900579868696060575639423061202619148825",
"18124252316135049195270348857308050282660839058495893905635826459440493046467", "1296256729870262422650485730805825715543370241968740278951378382748106685",
"1" "1"
], ],
"eval_a": "18560625457154932877354134783576059795528977185011370741206750467310685514420", "eval_a": "17308412617343213496686623338374754645623487581648979513260734198232305768219",
"eval_b": "2968882576386486226736180104429680319564132166278962733938101279863400669397", "eval_b": "18345454810685357058582137490005137834611428833597017516916268835300742089352",
"eval_c": "14065677607789115870968882944412413440929947283607968973583982627560459103752", "eval_c": "16074233345199063790683870465201170590190471729874269213657192492651425327675",
"eval_s1": "17673322793248695230976965373575045530576580704252056363216368719625468122334", "eval_s1": "14015572845284403142110641193521146039944984657769005309306690365631231445048",
"eval_s2": "831541334231628590558915969572942800627020663197326186193303197959043192699", "eval_s2": "7691129033989434863426855513508666093916526662958551024915431222123575206817",
"eval_t": "8179926370148644196892921681282394306069033457557483827929857756544255424016", "eval_t": "5852485600510874249119136745640279381547655754620311863376257247975117708663",
"eval_zw": "7342206155372820933732681194284651788067168695182187676476085111006912772156", "eval_zw": "13923465555995912889009033724768828925333434248874337536329403180953424994345",
"eval_r": "11261053049659093980937042550692833529286331232997878682705148472953954402090", "eval_r": "1366062923125011032494175183956831254719864451259174775709441138581956258656",
"Wxi": [ "Wxi": [
"6125149678611859223282479698302269532216717966631378380250981750098717210374", "338371644772673995306261030076125401282839784249944929895162794096576157571",
"13207465019087327267137821712205429411984497896597119936649478058261276282566", "17341033938816793745315773504010937698365013917156300011885252183580989524581",
"1" "1"
], ],
"Wxiw": [ "Wxiw": [
"13714076431412195084554498803436795524319005402640663193692974043979445012470", "17454198881576966899691410005788764637613831450763965078826728621580498180724",
"4405441109329384737176946029242914012963938939164670332792981962524535185412", "5460326051028606573687415138444061925446401900718369209656673120203041901304",
"1" "1"
], ],
"protocol": "plonk" "protocol": "plonk"