snarkjs/src/bigint.js
src/bigint.jsRaw
1/*
2 Copyright 2018 0kims association.
3
4 This file is part of snarkjs.
5
6 snarkjs 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 snarkjs 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 snarkjs. 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 == b;
200 };
201 wBigInt.prototype.eq = wBigInt.prototype.equals;
202
203 wBigInt.prototype.neq = function(b) {
204 return this != b;
205 };
206
207} else {
208
209 var oldProto = bigInt.prototype;
210 wBigInt = function(a) {
211 if ((typeof a == "string") && (a.slice(0,2) == "0x")) {
212 return bigInt(a.slice(2), 16);
213 } else {
214 return bigInt(a);
215 }
216 };
217 wBigInt.one = bigInt.one;
218 wBigInt.zero = bigInt.zero;
219 wBigInt.prototype = oldProto;
220
221 // Affine
222 wBigInt.genAffine = (q) => {
223 const nq = wBigInt.zero.minus(q);
224 return (a) => {
225 let aux = a;
226 if (aux.isNegative()) {
227 if (aux.lesserOrEquals(nq)) {
228 aux = aux.mod(q);
229 }
230 if (aux.isNegative()) {
231 aux = aux.add(q);
232 }
233 } else {
234 if (aux.greaterOrEquals(q)) {
235 aux = aux.mod(q);
236 }
237 }
238 return aux;
239 };
240 };
241
242
243 // Inverse
244 wBigInt.genInverse = (q) => {
245 return (a) => a.affine(q).modInv(q);
246 };
247
248 // Add
249 wBigInt.genAdd = (q) => {
250 if (q) {
251 return (a,b) => {
252 const r = a.add(b);
253 return r.greaterOrEquals(q) ? r.minus(q) : r;
254 };
255 } else {
256 return (a,b) => a.add(b);
257 }
258 };
259
260 // Sub
261 wBigInt.genSub = (q) => {
262 if (q) {
263 return (a,b) => a.greaterOrEquals(b) ? a.minus(b) : a.minus(b).add(q);
264 } else {
265 return (a,b) => a.minus(b);
266 }
267 };
268
269 wBigInt.genNeg = (q) => {
270 if (q) {
271 return (a) => a.isZero() ? a : q.minus(a);
272 } else {
273 return (a) => wBigInt.zero.minus(a);
274 }
275 };
276
277 // Mul
278 wBigInt.genMul = (q) => {
279 if (q) {
280 return (a,b) => a.times(b).mod(q);
281 } else {
282 return (a,b) => a.times(b);
283 }
284 };
285
286 // Shr
287 wBigInt.genShr = () => {
288 return (a,b) => a.shiftRight(wBigInt(b).value);
289 };
290
291 // Shr
292 wBigInt.genShl = (q) => {
293 if (q) {
294 return (a,b) => a.shiftLeft(wBigInt(b).value).mod(q);
295 } else {
296 return (a,b) => a.shiftLeft(wBigInt(b).value);
297 }
298 };
299
300 // Square
301 wBigInt.genSquare = (q) => {
302 if (q) {
303 return (a) => a.square().mod(q);
304 } else {
305 return (a) => a.square();
306 }
307 };
308
309 // Double
310 wBigInt.genDouble = (q) => {
311 if (q) {
312 return (a) => a.add(a).mod(q);
313 } else {
314 return (a) => a.add(a);
315 }
316 };
317
318 // Equals
319 wBigInt.genEquals = (q) => {
320 if (q) {
321 return (a,b) => a.affine(q).equals(b.affine(q));
322 } else {
323 return (a,b) => a.equals(b);
324 }
325 };
326
327 // IsZero
328 wBigInt.genIsZero = (q) => {
329 if (q) {
330 return (a) => (a.affine(q).isZero());
331 } else {
332 return (a) => a.isZero();
333 }
334 };
335}
336
337
338
339wBigInt.affine = function(a, q) {
340 return wBigInt.genAffine(q)(a);
341};
342
343wBigInt.prototype.affine = function (q) {
344 return wBigInt.affine(this, q);
345};
346
347wBigInt.inverse = function(a, q) {
348 return wBigInt.genInverse(q)(a);
349};
350
351wBigInt.prototype.inverse = function (q) {
352 return wBigInt.genInverse(q)(this);
353};
354
355wBigInt.add = function(a, b, q) {
356 return wBigInt.genAdd(q)(a,b);
357};
358
359wBigInt.prototype.add = function (a, q) {
360 return wBigInt.genAdd(q)(this, a);
361};
362
363wBigInt.sub = function(a, b, q) {
364 return wBigInt.genSub(q)(a,b);
365};
366
367wBigInt.prototype.sub = function (a, q) {
368 return wBigInt.genSub(q)(this, a);
369};
370
371wBigInt.neg = function(a, q) {
372 return wBigInt.genNeg(q)(a);
373};
374
375wBigInt.prototype.neg = function (q) {
376 return wBigInt.genNeg(q)(this);
377};
378
379wBigInt.mul = function(a, b, q) {
380 return wBigInt.genMul(q)(a,b);
381};
382
383wBigInt.prototype.mul = function (a, q) {
384 return wBigInt.genMul(q)(this, a);
385};
386
387wBigInt.shr = function(a, b, q) {
388 return wBigInt.genShr(q)(a,b);
389};
390
391wBigInt.prototype.shr = function (a, q) {
392 return wBigInt.genShr(q)(this, a);
393};
394
395wBigInt.shl = function(a, b, q) {
396 return wBigInt.genShl(q)(a,b);
397};
398
399wBigInt.prototype.shl = function (a, q) {
400 return wBigInt.genShl(q)(this, a);
401};
402
403wBigInt.equals = function(a, b, q) {
404 return wBigInt.genEquals(q)(a,b);
405};
406
407wBigInt.prototype.equals = function (a, q) {
408 return wBigInt.genEquals(q)(this, a);
409};
410
411wBigInt.square = function(a, q) {
412 return wBigInt.genSquare(q)(a);
413};
414
415wBigInt.prototype.square = function (q) {
416 return wBigInt.genSquare(q)(this);
417};
418
419wBigInt.double = function(a, q) {
420 return wBigInt.genDouble(q)(a);
421};
422
423wBigInt.prototype.double = function (q) {
424 return wBigInt.genDouble(q)(this);
425};
426
427wBigInt.isZero = function(a, q) {
428 return wBigInt.genIsZero(q)(a);
429};
430
431wBigInt.prototype.isZero = function (q) {
432 return wBigInt.genIsZero(q)(this);
433};
434
435
436module.exports = wBigInt;
437