snarkjs/src/bigint.js
src/bigint.jsRaw
1/*
2 Copyright 2018 0kims association.
3
4 This file is part of zksnark JavaScript library.
5
6 zksnark JavaScript library is a free software: you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as published by the
8 Free Software Foundation, either version 3 of the License, or (at your option)
9 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 MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 more details.
15
16 You should have received a copy of the GNU General Public License along with
17 zksnark JavaScript library. If not, see <https://www.gnu.org/licenses/>.
18*/
19
20/* global BigInt */
21const bigInt = require("big-integer");
22
23let wBigInt;
24
25if (typeof(BigInt) != "undefined") {
26 wBigInt = BigInt;
27 wBigInt.one = wBigInt(1);
28 wBigInt.zero = wBigInt(0);
29
30 // Affine
31 wBigInt.genAffine = (q) => {
32 const nq = -q;
33 return (a) => {
34 let aux = a;
35 if (aux < 0) {
36 if (aux <= nq) {
37 aux = aux % q;
38 }
39 if (aux < wBigInt.zero) {
40 aux = aux + q;
41 }
42 } else {
43 if (aux >= q) {
44 aux = aux % q;
45 }
46 }
47 return aux.valueOf();
48 };
49 };
50
51
52 // Inverse
53 wBigInt.genInverse = (q) => {
54 return (a) => {
55 let t = wBigInt.zero;
56 let r = q;
57 let newt = wBigInt.one;
58 let newr = wBigInt.affine(a, q);
59 while (newr!=wBigInt.zero) {
60 let q = r/newr;
61 [t, newt] = [newt, t-q*newt];
62 [r, newr] = [newr, r-q*newr];
63 }
64 if (t<wBigInt.zero) t += q;
65 return t;
66 };
67 };
68
69
70 // Add
71 wBigInt.genAdd = (q) => {
72 if (q) {
73 return (a,b) => (a+b) % q;
74 } else {
75 return (a,b) => a+b;
76 }
77 };
78
79 // Sub
80 wBigInt.genSub = (q) => {
81 if (q) {
82 return (a,b) => (a-b) % q;
83 } else {
84 return (a,b) => a-b;
85 }
86 };
87
88
89 // Neg
90 wBigInt.genNeg = (q) => {
91 if (q) {
92 return (a) => (-a) % q;
93 } else {
94 return (a) => -a;
95 }
96 };
97
98 // Mul
99 wBigInt.genMul = (q) => {
100 if (q) {
101 return (a,b) => (a*b) % q;
102 } else {
103 return (a,b) => a*b;
104 }
105 };
106
107 // Shr
108 wBigInt.genShr = () => {
109 return (a,b) => a >> wBigInt(b);
110 };
111
112 // Shl
113 wBigInt.genShl = (q) => {
114 if (q) {
115 return (a,b) => (a << wBigInt(b)) % q;
116 } else {
117 return (a,b) => a << wBigInt(b);
118 }
119 };
120
121 // Equals
122 wBigInt.genEquals = (q) => {
123 if (q) {
124 return (a,b) => (a.affine(q) == b.affine(q));
125 } else {
126 return (a,b) => a == b;
127 }
128 };
129
130 // Square
131 wBigInt.genSquare = (q) => {
132 if (q) {
133 return (a) => (a*a) %q;
134 } else {
135 return (a) => a*a;
136 }
137 };
138
139
140 // Double
141 wBigInt.genDouble = (q) => {
142 if (q) {
143 return (a) => (a+a) %q;
144 } else {
145 return (a) => a+a;
146 }
147 };
148
149 // IsZero
150 wBigInt.genIsZero = (q) => {
151 if (q) {
152 return (a) => (a.affine(q) == wBigInt.zero);
153 } else {
154 return (a) => a == wBigInt.zero;
155 }
156 };
157
158
159 // Other minor functions
160 wBigInt.prototype.isOdd = function() {
161 return (this & wBigInt.one) == wBigInt(1);
162 };
163
164 wBigInt.prototype.isNegative = function() {
165 return this < wBigInt.zero;
166 };
167
168 wBigInt.prototype.and = function(m) {
169 return this & m;
170 };
171
172 wBigInt.prototype.mod = function(c) {
173 return this % c;
174 };
175
176 wBigInt.prototype.modPow = function(e, m) {
177 return this ** e % m;
178 };
179
180 wBigInt.prototype.greaterOrEquals = function(b) {
181 return this >= b;
182 };
183
184 wBigInt.prototype.greater = function(b) {
185 return this > b;
186 };
187 wBigInt.prototype.gt = wBigInt.prototype.greater;
188
189 wBigInt.prototype.lesserOrEquals = function(b) {
190 return this <= b;
191 };
192
193 wBigInt.prototype.lesser = function(b) {
194 return this < b;
195 };
196 wBigInt.prototype.lt = wBigInt.prototype.lesser;
197
198 wBigInt.prototype.equals = function(b) {
199 return this.valueOf == b.valueOf;
200 };
201 wBigInt.prototype.eq = wBigInt.prototype.equals;
202
203} else {
204
205 wBigInt = bigInt;
206
207 // Affine
208 wBigInt.genAffine = (q) => {
209 const nq = wBigInt.zero.minus(q);
210 return (a) => {
211 let aux = a;
212 if (aux.isNegative()) {
213 if (aux.lesserOrEquals(nq)) {
214 aux = aux.mod(q);
215 }
216 if (aux.isNegative()) {
217 aux = aux.add(q);
218 }
219 } else {
220 if (aux.greaterOrEquals(q)) {
221 aux = aux.mod(q);
222 }
223 }
224 return aux;
225 };
226 };
227
228
229 // Inverse
230 wBigInt.genInverse = (q) => {
231 return (a) => a.affine(q).modInv(q);
232 };
233
234 // Add
235 wBigInt.genAdd = (q) => {
236 if (q) {
237 return (a,b) => {
238 const r = a.add(b);
239 return r.greaterOrEquals(q) ? r.minus(q) : r;
240 };
241 } else {
242 return (a,b) => a.add(b);
243 }
244 };
245
246 // Sub
247 wBigInt.genSub = (q) => {
248 if (q) {
249 return (a,b) => a.greaterOrEquals(b) ? a.minus(b) : a.minus(b).add(q);
250 } else {
251 return (a,b) => a.minus(b);
252 }
253 };
254
255 wBigInt.genNeg = (q) => {
256 if (q) {
257 return (a) => a.isZero() ? a : q.minus(a);
258 } else {
259 return (a) => wBigInt.zero.minus(a);
260 }
261 };
262
263 // Mul
264 wBigInt.genMul = (q) => {
265 if (q) {
266 return (a,b) => a.times(b).mod(q);
267 } else {
268 return (a,b) => a.times(b);
269 }
270 };
271
272 // Shr
273 wBigInt.genShr = () => {
274 return (a,b) => a.shiftRight(wBigInt(b).value);
275 };
276
277 // Shr
278 wBigInt.genShl = (q) => {
279 if (q) {
280 return (a,b) => a.shiftLeft(wBigInt(b).value).mod(q);
281 } else {
282 return (a,b) => a.shiftLeft(wBigInt(b).value);
283 }
284 };
285
286 // Square
287 wBigInt.genSquare = (q) => {
288 if (q) {
289 return (a) => a.square().mod(q);
290 } else {
291 return (a) => a.square();
292 }
293 };
294
295 // Double
296 wBigInt.genDouble = (q) => {
297 if (q) {
298 return (a) => a.add(a).mod(q);
299 } else {
300 return (a) => a.add(a);
301 }
302 };
303
304 // Equals
305 wBigInt.genEquals = (q) => {
306 if (q) {
307 return (a,b) => a.affine(q).equals(b.affine(q));
308 } else {
309 return (a,b) => a.equals(b);
310 }
311 };
312
313 // IsZero
314 wBigInt.genIsZero = (q) => {
315 if (q) {
316 return (a) => (a.affine(q).isZero());
317 } else {
318 return (a) => a.isZero();
319 }
320 };
321}
322
323
324
325wBigInt.affine = function(a, q) {
326 return wBigInt.genAffine(q)(a);
327};
328
329wBigInt.prototype.affine = function (q) {
330 return wBigInt.affine(this, q);
331};
332
333wBigInt.inverse = function(a, q) {
334 return wBigInt.genInverse(q)(a);
335};
336
337wBigInt.prototype.inverse = function (q) {
338 return wBigInt.genInverse(this, q);
339};
340
341wBigInt.add = function(a, b, q) {
342 return wBigInt.genAdd(q)(a,b);
343};
344
345wBigInt.prototype.add = function (a, q) {
346 return wBigInt.genAdd(q)(this, a);
347};
348
349wBigInt.sub = function(a, b, q) {
350 return wBigInt.genSub(q)(a,b);
351};
352
353wBigInt.prototype.sub = function (a, q) {
354 return wBigInt.genSub(q)(this, a);
355};
356
357wBigInt.neg = function(a, q) {
358 return wBigInt.genNeg(q)(a);
359};
360
361wBigInt.prototype.neg = function (q) {
362 return wBigInt.genNeg(q)(this);
363};
364
365wBigInt.mul = function(a, b, q) {
366 return wBigInt.genMul(q)(a,b);
367};
368
369wBigInt.prototype.mul = function (a, q) {
370 return wBigInt.genMul(q)(this, a);
371};
372
373wBigInt.shr = function(a, b, q) {
374 return wBigInt.genShr(q)(a,b);
375};
376
377wBigInt.prototype.shr = function (a, q) {
378 return wBigInt.genShr(q)(this, a);
379};
380
381wBigInt.shl = function(a, b, q) {
382 return wBigInt.genShl(q)(a,b);
383};
384
385wBigInt.prototype.shl = function (a, q) {
386 return wBigInt.genShl(q)(this, a);
387};
388
389wBigInt.equals = function(a, b, q) {
390 return wBigInt.genEquals(q)(a,b);
391};
392
393wBigInt.prototype.equals = function (a, q) {
394 return wBigInt.genEquals(q)(this, a);
395};
396
397wBigInt.square = function(a, q) {
398 return wBigInt.genSquare(q)(a);
399};
400
401wBigInt.prototype.square = function (q) {
402 return wBigInt.genSquare(q)(this);
403};
404
405wBigInt.double = function(a, q) {
406 return wBigInt.genDouble(q)(a);
407};
408
409wBigInt.prototype.double = function (q) {
410 return wBigInt.genDouble(q)(this);
411};
412
413wBigInt.isZero = function(a, q) {
414 return wBigInt.genIsZero(q)(a);
415};
416
417wBigInt.prototype.isZero = function (q) {
418 return wBigInt.genIsZero(q)(this);
419};
420
421
422module.exports = wBigInt;
423