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    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