arnaucube
arnaucube/snarkjsPublic Self-hosted repository
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