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