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