arnaucube
arnaucube/snarkjsPublic Self-hosted repository
snarkjs/src/setup.js
src/setup.jsRaw
  1/*
  2    Copyright 2018 0kims association
  3
  4    This file is part of zksnark javascript library.
  5
  6    zksnark javascript library is free software: you can redistribute it and/or modify
  7    it under the terms of the GNU General Public License as published by
  8    the Free Software Foundation, either version 3 of the License, or
  9    (at your option) any later version.
 10
 11    zksnark javascript library is distributed in the hope that it will be useful,
 12    but WITHOUT ANY WARRANTY; without even the implied warranty of
 13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14    GNU General Public License for more details.
 15
 16    You should have received a copy of the GNU General Public License
 17    along with zksnark javascript library.  If not, see <https://www.gnu.org/licenses/>.
 18*/
 19
 20const bigInt = require("./bigint.js");
 21
 22const BN128 = require("./BN128.js");
 23const PolField = require("./polfield.js");
 24const ZqField = require("./zqfield.js");
 25const RatField = require("./ratfield.js");
 26
 27const bn128 = new BN128();
 28const G1 = bn128.G1;
 29const G2 = bn128.G2;
 30const PolF = new PolField(new ZqField(bn128.r));
 31const RatPolF = new PolField(new RatField(new ZqField(bn128.r)));
 32const F = new ZqField(bn128.r);
 33
 34module.exports = function setup(circuit) {
 35    const setup = {
 36        vk_proof : {
 37            nVars: circuit.nVars,
 38            nPublic: circuit.nPubInputs + circuit.nOutputs
 39        },
 40        vk_verifier: {
 41            nPublic: circuit.nPubInputs + circuit.nOutputs
 42        },
 43        toxic: {}
 44    };
 45
 46    calculatePolinomials(setup, circuit);
 47    setup.toxic.t = F.random();
 48    calculateEncriptedValuesAtT(setup, circuit);
 49    calculateHexps(setup, circuit);
 50
 51    return setup;
 52};
 53
 54function calculatePolinomials(setup, circuit) {
 55    // Calculate the points that must cross each polinomial
 56    const aPoints = [];
 57    const bPoints = [];
 58    const cPoints = [];
 59    for (let s = 0; s<circuit.nSignals; s++) {
 60        aPoints[s] = [];
 61        bPoints[s] = [];
 62        cPoints[s] = [];
 63        for (let c=0; c<circuit.nConstrains; c++) {
 64            aPoints[s].push([[bigInt(c), F.one], [circuit.a(c, s), F.one]]);
 65            bPoints[s].push([[bigInt(c), F.one], [circuit.b(c, s), F.one]]);
 66            cPoints[s].push([[bigInt(c), F.one], [circuit.c(c, s), F.one]]);
 67        }
 68    }
 69
 70    // Calculate the polinomials using Lagrange
 71    setup.vk_proof.polsA = [];
 72    setup.vk_proof.polsB = [];
 73    setup.vk_proof.polsC = [];
 74    for (let s=0; s<circuit.nSignals; s++) {
 75//        console.log(`Caclcualte Pol ${s}/${circuit.nSignals}`);
 76        const pA = RatPolF.lagrange( aPoints[s] );
 77        const pB = RatPolF.lagrange( bPoints[s] );
 78        const pC = RatPolF.lagrange( cPoints[s] );
 79
 80        setup.vk_proof.polsA.push( unrat(pA) );
 81        setup.vk_proof.polsB.push( unrat(pB) );
 82        setup.vk_proof.polsC.push( unrat(pC) );
 83
 84    }
 85
 86    // Calculate Z polinomial
 87    // Z = 1
 88    setup.vk_proof.polZ = [bigInt(1)];
 89    for (let c=0; c<circuit.nConstrains; c++) {
 90        // Z = Z * (x - p_c)
 91        setup.vk_proof.polZ = PolF.mul(
 92            setup.vk_proof.polZ,
 93            [F.neg(bigInt(c)), bigInt(1)] );
 94    }
 95}
 96
 97function calculateEncriptedValuesAtT(setup, circuit) {
 98    setup.vk_proof.A = [];
 99    setup.vk_proof.B = [];
100    setup.vk_proof.C = [];
101    setup.vk_proof.Ap = [];
102    setup.vk_proof.Bp = [];
103    setup.vk_proof.Cp = [];
104    setup.vk_proof.Kp = [];
105    setup.vk_verifier.A = [];
106
107    setup.toxic.ka = F.random();
108    setup.toxic.kb = F.random();
109    setup.toxic.kc = F.random();
110    setup.toxic.kbeta = F.random();
111    setup.toxic.kgamma = F.random();
112
113    const gb = F.mul(setup.toxic.kbeta, setup.toxic.kgamma);
114
115    setup.vk_verifier.vk_a = G2.affine(G2.mulScalar( G2.g, setup.toxic.ka));
116    setup.vk_verifier.vk_b = G1.affine(G1.mulScalar( G1.g, setup.toxic.kb));
117    setup.vk_verifier.vk_c = G2.affine(G2.mulScalar( G2.g, setup.toxic.kc));
118    setup.vk_verifier.vk_gb_1 = G1.affine(G1.mulScalar( G1.g, gb));
119    setup.vk_verifier.vk_gb_2 = G2.affine(G2.mulScalar( G2.g, gb));
120    setup.vk_verifier.vk_g = G2.affine(G2.mulScalar( G2.g, setup.toxic.kgamma));
121
122    for (let s=0; s<circuit.nSignals; s++) {
123
124        // A[i] = G1 * polA(t)
125        const at = F.affine(PolF.eval(setup.vk_proof.polsA[s], setup.toxic.t));
126        const A = G1.affine(G1.mulScalar(G1.g, at));
127
128        setup.vk_proof.A.push(A);
129
130        if (s <= setup.vk_proof.nPublic) {
131            setup.vk_verifier.A.push(A);
132        }
133
134
135        // B1[i] = G1 * polB(t)
136        const bt = F.affine(PolF.eval(setup.vk_proof.polsB[s], setup.toxic.t));
137        const B1 = G1.affine(G1.mulScalar(G1.g, bt));
138
139        // B2[i] = G2 * polB(t)
140        const B2 = G2.affine(G2.mulScalar(G2.g, bt));
141
142        setup.vk_proof.B.push(B2);
143
144        // C[i] = G1 * polC(t)
145        const ct = F.affine(PolF.eval(setup.vk_proof.polsC[s], setup.toxic.t));
146        const C = G1.affine(G1.mulScalar( G1.g, ct));
147        setup.vk_proof.C.push (C);
148
149        // K = G1 * (A+B+C)
150
151        const kt = F.affine(F.add(F.add(at, bt), ct));
152        const K = G1.affine(G1.mulScalar( G1.g, kt));
153
154
155
156        const Ktest = G1.affine(G1.add(G1.add(A, B1), C));
157
158        if (!G1.equals(K, Ktest)) {
159            console.log ("=====FAIL======");
160        }
161
162
163
164        setup.vk_proof.Ap.push(G1.affine(G1.mulScalar(A, setup.toxic.ka)));
165        setup.vk_proof.Bp.push(G1.affine(G1.mulScalar(B1, setup.toxic.kb)));
166        setup.vk_proof.Cp.push(G1.affine(G1.mulScalar(C, setup.toxic.kc)));
167        setup.vk_proof.Kp.push(G1.affine(G1.mulScalar(K, setup.toxic.kbeta)));
168    }
169
170    setup.vk_verifier.vk_z = G2.affine(G2.mulScalar(
171        G2.g,
172        PolF.eval(setup.vk_proof.polZ, setup.toxic.t)));
173}
174
175function calculateHexps(setup, circuit) {
176    let maxA = 0;
177    let maxB = 0;
178    let maxC = 0;
179    for (let s=0; s<circuit.nSignals; s++) {
180        maxA = Math.max(maxA, setup.vk_proof.polsA[s].length);
181        maxB = Math.max(maxB, setup.vk_proof.polsB[s].length);
182        maxC = Math.max(maxC, setup.vk_proof.polsC[s].length);
183    }
184
185    let maxFull = Math.max(maxA * maxB - 1, maxC);
186
187    const maxH = maxFull - setup.vk_proof.polZ.length + 1;
188
189    setup.vk_proof.hExps = new Array(maxH);
190    setup.vk_proof.hExps[0] = G1.g;
191    let eT = setup.toxic.t;
192    for (let i=1; i<maxH; i++) {
193        setup.vk_proof.hExps[i] = G1.affine(G1.mulScalar(G1.g, eT));
194        eT = F.mul(eT, setup.toxic.t);
195    }
196}
197
198function unrat(p) {
199    const res = new Array(p.length);
200    for (let i=0; i<p.length; i++) {
201        res[i] = RatPolF.F.toF(p[i]);
202    }
203    return res;
204}
205