arnaucube
arnaucube/snarkjsPublic Self-hosted repository
snarkjs/src/setup.js
src/setup.jsRaw
  1const bigInt = require("big-integer");
  2
  3const ZnField = require("./znfield.js");
  4const PolField = require("./polfield.js");
  5const G1Curve = require("./g1curve");
  6const G2Curve = require("./g2curve");
  7
  8const F = new ZnField(bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
  9const PolF = new PolField(F);
 10const G1 = new G1Curve();
 11const G2 = new G2Curve();
 12
 13module.exports = function setup(circuit) {
 14    const setup = {
 15        vk_proof : {
 16            nSignals: circuit.nSignals,
 17            nPublic: circuit.nPublic
 18        },
 19        vk_verifier: {
 20            nPublic: circuit.nPublic
 21        },
 22        toxic: {}
 23    };
 24
 25    calculatePolinomials(setup, circuit);
 26    setup.toxic.t = F.random();
 27    calculateEncriptedValuesAtT(setup, circuit);
 28    calculateHexps(setup, circuit);
 29};
 30
 31function calculatePolinomials(setup, circuit) {
 32    // Calculate the points that must cross each polinomial
 33    const aPoints = [];
 34    const bPoints = [];
 35    const cPoints = [];
 36    for (let s = 0; circuit.nSignals; s++) {
 37        aPoints[s] = [];
 38        bPoints[s] = [];
 39        cPoints[s] = [];
 40        for (let c=0; c<circuit.nConstrains; c++) {
 41            aPoints[s].push([bigInt(c), circuit.a(c, s)]);
 42            bPoints[s].push([bigInt(c), circuit.b(c, s)]);
 43            cPoints[s].push([bigInt(c), circuit.c(c, s)]);
 44        }
 45    }
 46
 47    // Calculate the polinomials using Lagrange
 48    setup.vk_proof.polsA = [];
 49    setup.vk_proof.polsB = [];
 50    setup.vk_proof.polsC = [];
 51    for (let s=0; s<circuit.nSignals; s++) {
 52        setup.vk_proof.polsA.push(PolF.lagrange( aPoints[s] ));
 53        setup.vk_proof.polsB.push(PolF.lagrange( bPoints[s] ));
 54        setup.vk_proof.polsC.push(PolF.lagrange( cPoints[s] ));
 55    }
 56
 57    // Calculate Z polinomial
 58    // Z = 1
 59    setup.vk_proof.polZ = [bigInt(1)];
 60    for (let c=0; c<circuit.nConstrains; c++) {
 61        // Z = Z * (x - p_c)
 62        setup.vk_proof.polZ = PolF.mul(
 63            setup.vk_proof.polZ,
 64            [F.neg(bigInt(c)), bigInt(1)] );
 65    }
 66}
 67
 68function calculateEncriptedValuesAtT(setup, circuit) {
 69    setup.vk_proof.A = [];
 70    setup.vk_proof.B = [];
 71    setup.vk_proof.C = [];
 72    setup.vk_proof.Ap = [];
 73    setup.vk_proof.Bp = [];
 74    setup.vk_proof.Cp = [];
 75    setup.vk_proof.Kp = [];
 76    setup.vk_verifier.A = [];
 77
 78    setup.toxic.ka = F.random();
 79    setup.toxic.kb = F.random();
 80    setup.toxic.kc = F.random();
 81    setup.toxic.kbeta = F.random();
 82    setup.toxic.kgamma = F.random();
 83
 84    const gb = F.mul(setup.toxic.kbeta, setup.toxic.kgamma);
 85
 86    setup.vk_verifier.vk_a = G2.mulEscalar( G2.g, setup.toxic.ka);
 87    setup.vk_verifier.vk_b = G1.mulEscalar( G1.g, setup.toxic.kb);
 88    setup.vk_verifier.vk_c = G2.mulEscalar( G2.g, setup.toxic.kc);
 89    setup.vk_verifier.vk_gb_1 = G1.mulEscalar( G1.g, gb);
 90    setup.vk_verifier.vk_gb_2 = G2.mulEscalar( G2.g, gb);
 91    setup.vk_verifier.vk_g = G2.mulEscalar( G2.g, setup.toxic.kgamma);
 92
 93    for (let s=0; s<circuit.nSignals; s++) {
 94
 95        // A[i] = G1 * polA(t)
 96        const A = G1.mulEscalar(
 97            G1.g,
 98            PolF.eval(setup.vk_proof.polsA[s], setup.vk_proof.t));
 99        setup.vk_proof.A.push(A);
100
101        if (s < circuit.nPublicSignals) {
102            setup.vk_verifier.A.pusj(A);
103        }
104
105        // B1[i] = G1 * polB(t)
106        const B1 = G1.mulEscalar(
107            G1.g,
108            PolF.eval(setup.vk_proof.polsB[s], setup.vk_proof.t));
109
110        // B2[i] = G2 * polB(t)
111        const B2 = G2.mulEscalar(
112            G2.g,
113            PolF.eval(setup.vk_proof.polsB[s], setup.vk_proof.t));
114        setup.vk_proof.B.push(B2);
115
116        // C[i] = G1 * polC(t)
117        const C = G1.mulEscalar(
118            G1.g,
119            PolF.eval(setup.vk_proof.polsC[s], setup.vk_proof.t));
120        setup.vk_proof.C.push (C);
121
122        // K = G1 * (A+B+C)
123        const K = G1.mulEscalar(
124            G1.g,
125            G1.add(G1.add(A, B1), C));
126
127        setup.vk_proof.Ap.push(G1.mulEscalar(A, setup.toxic.ka));
128        setup.vk_proof.Bp.push(G1.mulEscalar(B1, setup.toxic.kb));
129        setup.vk_proof.Cp.push(G1.mulEscalar(C, setup.toxic.kc));
130        setup.vk_proof.Kp.push(G1.mulEscalar(K, setup.toxic.beta));
131    }
132
133    setup.vk_verifier.vk_z = G2.mulEscalar(
134        G2.g,
135        PolF.eval(setup.vk_proof.polZ, setup.vk_proof.t));
136}
137
138function calculateHexps(setup, circuit) {
139    let maxA = 0;
140    let maxB = 0;
141    let maxC = 0;
142    for (let s=0; s<circuit.nSignals; s++) {
143        maxA = Math.max(maxA, setup.vk_proof.polsA[s]);
144        maxB = Math.max(maxB, setup.vk_proof.polsB[s]);
145        maxC = Math.max(maxC, setup.vk_proof.polsC[s]);
146    }
147
148    let maxFull = Math.max(maxA * maxB - 1, maxC);
149
150    const maxH = maxFull - setup.vk_proof.polZ.length + 1;
151
152    setup.vk_proof.hExps = new Array(maxH);
153    setup.vk_proof.hExps[0] = G1.g;
154    let eT = setup.toxic.t;
155    for (let i=1; i<maxH; i++) {
156        setup.vk_proof.hExps[i] = G1.mulEscalar(G1.g, eT);
157        eT = F.mul(eT, setup.toxic.t);
158    }
159}
160