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