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