websnark/tools/buildpkey.js
tools/buildpkey.jsRaw
1const bigInt = require("big-integer");
2const assert = require("assert");
3
4function writeUint32(h, val) {
5 h.dataView.setUint32(h.offset, val, true);
6 h.offset += 4;
7}
8
9function writeUint32ToPointer(h, p, val) {
10 h.dataView.setUint32(p, val, true);
11}
12
13
14function alloc(h, n) {
15 const o = h.offset;
16 h.offset += n;
17 return o;
18}
19
20function writeBigInt(h, bi) {
21 for (let i=0; i<8; i++) {
22 const v = bi.shiftRight(i*32).and(0xFFFFFFFF).toJSNumber();
23 writeUint32(h, v);
24 }
25}
26
27function toMontgomeryQ(p) {
28 const q = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
29 return p.times(bigInt.one.shiftLeft(256)).mod(q);
30}
31
32function toMontgomeryR(p) {
33 const r = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
34 return p.times(bigInt.one.shiftLeft(256)).mod(r);
35}
36
37function writePoint(h, p) {
38 writeBigInt(h, toMontgomeryQ(p[0]));
39 writeBigInt(h, toMontgomeryQ(p[1]));
40}
41
42function writePoint2(h, p) {
43 writeBigInt(h, toMontgomeryQ(p[0][0]));
44 writeBigInt(h, toMontgomeryQ(p[0][1]));
45 writeBigInt(h, toMontgomeryQ(p[1][0]));
46 writeBigInt(h, toMontgomeryQ(p[1][1]));
47}
48
49function writeTransformedPolynomial(h, p) {
50
51 const keys = Object.keys(p);
52
53 writeUint32(h, keys.length);
54
55 for (let i=0; i<keys.length; i++) {
56 writeUint32(h, keys[i]);
57 writeBigInt(h, toMontgomeryR(p[keys[i]]));
58 }
59}
60
61function calculateBuffLen(provingKey) {
62 function polSize(pol) {
63 const l= Object.keys(pol).length;
64 return 36*l + 4;
65 }
66
67 let size = 40;
68
69 // alfa1, beta1, delta1
70 size += 3 * (32*2);
71
72 // beta2, delta2
73 size += 2 * (32*4);
74
75 for (let i=0; i<provingKey.nVars; i++) {
76 size += polSize(provingKey.polsA[i]);
77 size += polSize(provingKey.polsB[i]);
78 }
79
80 size += provingKey.nVars* (32*2);
81 size += provingKey.nVars* (32*2);
82 size += provingKey.nVars* (32*4);
83 size += (provingKey.nVars - provingKey.nPublic - 1)* (32*2);
84 size += provingKey.domainSize * (32*2);
85
86 return size;
87}
88
89
90function buildPKey(provingKey) {
91 const buffLen = calculateBuffLen(provingKey);
92
93 const buff = new ArrayBuffer(buffLen);
94
95 const h = {
96 dataView: new DataView(buff),
97 offset: 0
98 };
99
100
101 writeUint32(h, provingKey.nVars);
102 writeUint32(h, provingKey.nPublic);
103 writeUint32(h, provingKey.domainSize);
104 const pPolsA = alloc(h, 4);
105 const pPolsB = alloc(h, 4);
106 const pPointsA = alloc(h, 4);
107 const pPointsB1 = alloc(h, 4);
108 const pPointsB2 = alloc(h, 4);
109 const pPointsC = alloc(h, 4);
110 const pPointsHExps = alloc(h, 4);
111
112 writePoint(h, provingKey.vk_alfa_1);
113 writePoint(h, provingKey.vk_beta_1);
114 writePoint(h, provingKey.vk_delta_1);
115 writePoint2(h, provingKey.vk_beta_2);
116 writePoint2(h, provingKey.vk_delta_2);
117
118 writeUint32ToPointer(h, pPolsA, h.offset);
119 for (let i=0; i<provingKey.nVars; i++) {
120 writeTransformedPolynomial(h, provingKey.polsA[i]);
121 }
122
123 writeUint32ToPointer(h, pPolsB, h.offset);
124 for (let i=0; i<provingKey.nVars; i++) {
125 writeTransformedPolynomial(h, provingKey.polsB[i]);
126 }
127
128 writeUint32ToPointer(h, pPointsA, h.offset);
129 for (let i=0; i<provingKey.nVars; i++) {
130 writePoint(h, provingKey.A[i]);
131 }
132
133 writeUint32ToPointer(h, pPointsB1, h.offset);
134 for (let i=0; i<provingKey.nVars; i++) {
135 writePoint(h, provingKey.B1[i]);
136 }
137
138 writeUint32ToPointer(h, pPointsB2, h.offset);
139 for (let i=0; i<provingKey.nVars; i++) {
140 writePoint2(h, provingKey.B2[i]);
141 }
142
143 writeUint32ToPointer(h, pPointsC, h.offset);
144 for (let i=provingKey.nPublic+1; i<provingKey.nVars; i++) {
145 writePoint(h, provingKey.C[i]);
146 }
147
148 writeUint32ToPointer(h, pPointsHExps, h.offset);
149 for (let i=0; i<provingKey.domainSize; i++) {
150 writePoint(h, provingKey.hExps[i]);
151 }
152
153 assert.equal(h.offset, buffLen);
154
155 return Buffer.from(buff);
156}
157
158module.exports = buildPKey;
159
160/*
161NSignals
162NPublic
163DomainSize (2 multiple)
164pPolsA
165pPolsB
166pPointsA
167pPointsB1
168pPointsB2
169pPointsC
170pPointsHExps
171Alfa1
172Beta1
173Delta1
174Beta2
175Delta2
176 PolinomialA_0
177 PolinomialA_1
178 PolinomialA_2
179 ...
180 PolinomialA_NVars-1
181
182 PolinomialB_0
183 PolinomialB_1
184 PolinomialB_2
185 ...
186 PolinomialB_NVars-1
187
188 PointA_0
189 PointA_1
190 ...
191 PointA_NVars-1
192
193 PointB1_0
194 PointB1_1
195 ...
196 PointB1_NVars-1
197
198 PointB2_0
199 PointB2_1
200 ...
201 PointB2_NVars-1
202
203 PointC_nPublics+1
204 PointC_nPublics+2
205 ...
206 PointC_nPublics+NVars
207
208 PointHExp_0
209 PointHExp_1
210 ...
211 PointHExp_DomainSize-1
212*/