diff --git a/build/websnark.js b/build/websnark.js
index 4cbfd61..48fab7f 100644
--- a/build/websnark.js
+++ b/build/websnark.js
@@ -28,16 +28,30 @@
/* globals window */
-const buildGroth16 = require("./src/groth16.js");
+const buildGroth16 = require("./src/groth16");
+const utils = require("./src/utils");
-buildGroth16().then( (groth16) => {
+buildGroth16().then((groth16) => {
window.groth16 = groth16;
- window.genZKSnarkProof = function(witness, provingKey, cb) {
-
- const p = groth16.proof(witness, provingKey);
+ window.zkSnarkProofToSolidityInput = utils.toSolidityInput;
+ window.genZKSnarkProofAndWitness = function (input, circuitJson, provingKey, cb) {
+ const p = utils.genWitnessAndProve(groth16, input, circuitJson, provingKey);
if (cb) {
- p.then( (proof) => {
+ p.then((proof) => {
+ cb(null, proof);
+ }, (err) => {
+ cb(err);
+ });
+ } else {
+ return p;
+ }
+ };
+
+ window.genZKSnarkProof = function (witness, provingKey, cb) {
+ const p = groth16.proof(witness, provingKey);
+ if (cb) {
+ p.then((proof) => {
cb(null, proof);
}, (err) => {
cb(err);
@@ -47,10 +61,7 @@ buildGroth16().then( (groth16) => {
}
};
});
-
-
-
-},{"./src/groth16.js":13}],3:[function(require,module,exports){
+},{"./src/groth16":17,"./src/utils":18}],3:[function(require,module,exports){
(function (global){
'use strict';
@@ -1336,1454 +1347,1454 @@ function fromByteArray (uint8) {
}
},{}],8:[function(require,module,exports){
-var bigInt = (function (undefined) {
- "use strict";
-
- var BASE = 1e7,
- LOG_BASE = 7,
- MAX_INT = 9007199254740992,
- MAX_INT_ARR = smallToArray(MAX_INT),
- DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
-
- var supportsNativeBigInt = typeof BigInt === "function";
-
- function Integer(v, radix, alphabet, caseSensitive) {
- if (typeof v === "undefined") return Integer[0];
- if (typeof radix !== "undefined") return +radix === 10 && !alphabet ? parseValue(v) : parseBase(v, radix, alphabet, caseSensitive);
- return parseValue(v);
- }
-
- function BigInteger(value, sign) {
- this.value = value;
- this.sign = sign;
- this.isSmall = false;
- }
- BigInteger.prototype = Object.create(Integer.prototype);
-
- function SmallInteger(value) {
- this.value = value;
- this.sign = value < 0;
- this.isSmall = true;
- }
- SmallInteger.prototype = Object.create(Integer.prototype);
-
- function NativeBigInt(value) {
- this.value = value;
- }
- NativeBigInt.prototype = Object.create(Integer.prototype);
-
- function isPrecise(n) {
- return -MAX_INT < n && n < MAX_INT;
- }
-
- function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
- if (n < 1e7)
- return [n];
- if (n < 1e14)
- return [n % 1e7, Math.floor(n / 1e7)];
- return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)];
- }
-
- function arrayToSmall(arr) { // If BASE changes this function may need to change
- trim(arr);
- var length = arr.length;
- if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) {
- switch (length) {
- case 0: return 0;
- case 1: return arr[0];
- case 2: return arr[0] + arr[1] * BASE;
- default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE;
- }
- }
- return arr;
- }
-
- function trim(v) {
- var i = v.length;
- while (v[--i] === 0);
- v.length = i + 1;
- }
-
- function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
- var x = new Array(length);
- var i = -1;
- while (++i < length) {
- x[i] = 0;
- }
- return x;
- }
-
- function truncate(n) {
- if (n > 0) return Math.floor(n);
- return Math.ceil(n);
- }
-
- function add(a, b) { // assumes a and b are arrays with a.length >= b.length
- var l_a = a.length,
- l_b = b.length,
- r = new Array(l_a),
- carry = 0,
- base = BASE,
- sum, i;
- for (i = 0; i < l_b; i++) {
- sum = a[i] + b[i] + carry;
- carry = sum >= base ? 1 : 0;
- r[i] = sum - carry * base;
- }
- while (i < l_a) {
- sum = a[i] + carry;
- carry = sum === base ? 1 : 0;
- r[i++] = sum - carry * base;
- }
- if (carry > 0) r.push(carry);
- return r;
- }
-
- function addAny(a, b) {
- if (a.length >= b.length) return add(a, b);
- return add(b, a);
- }
-
- function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
- var l = a.length,
- r = new Array(l),
- base = BASE,
- sum, i;
- for (i = 0; i < l; i++) {
- sum = a[i] - base + carry;
- carry = Math.floor(sum / base);
- r[i] = sum - carry * base;
- carry += 1;
- }
- while (carry > 0) {
- r[i++] = carry % base;
- carry = Math.floor(carry / base);
- }
- return r;
- }
-
- BigInteger.prototype.add = function (v) {
- var n = parseValue(v);
- if (this.sign !== n.sign) {
- return this.subtract(n.negate());
- }
- var a = this.value, b = n.value;
- if (n.isSmall) {
- return new BigInteger(addSmall(a, Math.abs(b)), this.sign);
- }
- return new BigInteger(addAny(a, b), this.sign);
- };
- BigInteger.prototype.plus = BigInteger.prototype.add;
-
- SmallInteger.prototype.add = function (v) {
- var n = parseValue(v);
- var a = this.value;
- if (a < 0 !== n.sign) {
- return this.subtract(n.negate());
- }
- var b = n.value;
- if (n.isSmall) {
- if (isPrecise(a + b)) return new SmallInteger(a + b);
- b = smallToArray(Math.abs(b));
- }
- return new BigInteger(addSmall(b, Math.abs(a)), a < 0);
- };
- SmallInteger.prototype.plus = SmallInteger.prototype.add;
-
- NativeBigInt.prototype.add = function (v) {
- return new NativeBigInt(this.value + parseValue(v).value);
- }
- NativeBigInt.prototype.plus = NativeBigInt.prototype.add;
-
- function subtract(a, b) { // assumes a and b are arrays with a >= b
- var a_l = a.length,
- b_l = b.length,
- r = new Array(a_l),
- borrow = 0,
- base = BASE,
- i, difference;
- for (i = 0; i < b_l; i++) {
- difference = a[i] - borrow - b[i];
- if (difference < 0) {
- difference += base;
- borrow = 1;
- } else borrow = 0;
- r[i] = difference;
- }
- for (i = b_l; i < a_l; i++) {
- difference = a[i] - borrow;
- if (difference < 0) difference += base;
- else {
- r[i++] = difference;
- break;
- }
- r[i] = difference;
- }
- for (; i < a_l; i++) {
- r[i] = a[i];
- }
- trim(r);
- return r;
- }
-
- function subtractAny(a, b, sign) {
- var value;
- if (compareAbs(a, b) >= 0) {
- value = subtract(a, b);
- } else {
- value = subtract(b, a);
- sign = !sign;
- }
- value = arrayToSmall(value);
- if (typeof value === "number") {
- if (sign) value = -value;
- return new SmallInteger(value);
- }
- return new BigInteger(value, sign);
- }
-
- function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
- var l = a.length,
- r = new Array(l),
- carry = -b,
- base = BASE,
- i, difference;
- for (i = 0; i < l; i++) {
- difference = a[i] + carry;
- carry = Math.floor(difference / base);
- difference %= base;
- r[i] = difference < 0 ? difference + base : difference;
- }
- r = arrayToSmall(r);
- if (typeof r === "number") {
- if (sign) r = -r;
- return new SmallInteger(r);
- } return new BigInteger(r, sign);
- }
-
- BigInteger.prototype.subtract = function (v) {
- var n = parseValue(v);
- if (this.sign !== n.sign) {
- return this.add(n.negate());
- }
- var a = this.value, b = n.value;
- if (n.isSmall)
- return subtractSmall(a, Math.abs(b), this.sign);
- return subtractAny(a, b, this.sign);
- };
- BigInteger.prototype.minus = BigInteger.prototype.subtract;
-
- SmallInteger.prototype.subtract = function (v) {
- var n = parseValue(v);
- var a = this.value;
- if (a < 0 !== n.sign) {
- return this.add(n.negate());
- }
- var b = n.value;
- if (n.isSmall) {
- return new SmallInteger(a - b);
- }
- return subtractSmall(b, Math.abs(a), a >= 0);
- };
- SmallInteger.prototype.minus = SmallInteger.prototype.subtract;
-
- NativeBigInt.prototype.subtract = function (v) {
- return new NativeBigInt(this.value - parseValue(v).value);
- }
- NativeBigInt.prototype.minus = NativeBigInt.prototype.subtract;
-
- BigInteger.prototype.negate = function () {
- return new BigInteger(this.value, !this.sign);
- };
- SmallInteger.prototype.negate = function () {
- var sign = this.sign;
- var small = new SmallInteger(-this.value);
- small.sign = !sign;
- return small;
- };
- NativeBigInt.prototype.negate = function () {
- return new NativeBigInt(-this.value);
- }
-
- BigInteger.prototype.abs = function () {
- return new BigInteger(this.value, false);
- };
- SmallInteger.prototype.abs = function () {
- return new SmallInteger(Math.abs(this.value));
- };
- NativeBigInt.prototype.abs = function () {
- return new NativeBigInt(this.value >= 0 ? this.value : -this.value);
- }
-
-
- function multiplyLong(a, b) {
- var a_l = a.length,
- b_l = b.length,
- l = a_l + b_l,
- r = createArray(l),
- base = BASE,
- product, carry, i, a_i, b_j;
- for (i = 0; i < a_l; ++i) {
- a_i = a[i];
- for (var j = 0; j < b_l; ++j) {
- b_j = b[j];
- product = a_i * b_j + r[i + j];
- carry = Math.floor(product / base);
- r[i + j] = product - carry * base;
- r[i + j + 1] += carry;
- }
- }
- trim(r);
- return r;
- }
-
- function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
- var l = a.length,
- r = new Array(l),
- base = BASE,
- carry = 0,
- product, i;
- for (i = 0; i < l; i++) {
- product = a[i] * b + carry;
- carry = Math.floor(product / base);
- r[i] = product - carry * base;
- }
- while (carry > 0) {
- r[i++] = carry % base;
- carry = Math.floor(carry / base);
- }
- return r;
- }
-
- function shiftLeft(x, n) {
- var r = [];
- while (n-- > 0) r.push(0);
- return r.concat(x);
- }
-
- function multiplyKaratsuba(x, y) {
- var n = Math.max(x.length, y.length);
-
- if (n <= 30) return multiplyLong(x, y);
- n = Math.ceil(n / 2);
-
- var b = x.slice(n),
- a = x.slice(0, n),
- d = y.slice(n),
- c = y.slice(0, n);
-
- var ac = multiplyKaratsuba(a, c),
- bd = multiplyKaratsuba(b, d),
- abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d));
-
- var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n));
- trim(product);
- return product;
- }
-
- // The following function is derived from a surface fit of a graph plotting the performance difference
- // between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
- function useKaratsuba(l1, l2) {
- return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0;
- }
-
- BigInteger.prototype.multiply = function (v) {
- var n = parseValue(v),
- a = this.value, b = n.value,
- sign = this.sign !== n.sign,
- abs;
- if (n.isSmall) {
- if (b === 0) return Integer[0];
- if (b === 1) return this;
- if (b === -1) return this.negate();
- abs = Math.abs(b);
- if (abs < BASE) {
- return new BigInteger(multiplySmall(a, abs), sign);
- }
- b = smallToArray(abs);
- }
- if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
- return new BigInteger(multiplyKaratsuba(a, b), sign);
- return new BigInteger(multiplyLong(a, b), sign);
- };
-
- BigInteger.prototype.times = BigInteger.prototype.multiply;
-
- function multiplySmallAndArray(a, b, sign) { // a >= 0
- if (a < BASE) {
- return new BigInteger(multiplySmall(b, a), sign);
- }
- return new BigInteger(multiplyLong(b, smallToArray(a)), sign);
- }
- SmallInteger.prototype._multiplyBySmall = function (a) {
- if (isPrecise(a.value * this.value)) {
- return new SmallInteger(a.value * this.value);
- }
- return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign);
- };
- BigInteger.prototype._multiplyBySmall = function (a) {
- if (a.value === 0) return Integer[0];
- if (a.value === 1) return this;
- if (a.value === -1) return this.negate();
- return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign);
- };
- SmallInteger.prototype.multiply = function (v) {
- return parseValue(v)._multiplyBySmall(this);
- };
- SmallInteger.prototype.times = SmallInteger.prototype.multiply;
-
- NativeBigInt.prototype.multiply = function (v) {
- return new NativeBigInt(this.value * parseValue(v).value);
- }
- NativeBigInt.prototype.times = NativeBigInt.prototype.multiply;
-
- function square(a) {
- //console.assert(2 * BASE * BASE < MAX_INT);
- var l = a.length,
- r = createArray(l + l),
- base = BASE,
- product, carry, i, a_i, a_j;
- for (i = 0; i < l; i++) {
- a_i = a[i];
- carry = 0 - a_i * a_i;
- for (var j = i; j < l; j++) {
- a_j = a[j];
- product = 2 * (a_i * a_j) + r[i + j] + carry;
- carry = Math.floor(product / base);
- r[i + j] = product - carry * base;
- }
- r[i + l] = carry;
- }
- trim(r);
- return r;
- }
-
- BigInteger.prototype.square = function () {
- return new BigInteger(square(this.value), false);
- };
-
- SmallInteger.prototype.square = function () {
- var value = this.value * this.value;
- if (isPrecise(value)) return new SmallInteger(value);
- return new BigInteger(square(smallToArray(Math.abs(this.value))), false);
- };
-
- NativeBigInt.prototype.square = function (v) {
- return new NativeBigInt(this.value * this.value);
- }
-
- function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
- var a_l = a.length,
- b_l = b.length,
- base = BASE,
- result = createArray(b.length),
- divisorMostSignificantDigit = b[b_l - 1],
- // normalization
- lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)),
- remainder = multiplySmall(a, lambda),
- divisor = multiplySmall(b, lambda),
- quotientDigit, shift, carry, borrow, i, l, q;
- if (remainder.length <= a_l) remainder.push(0);
- divisor.push(0);
- divisorMostSignificantDigit = divisor[b_l - 1];
- for (shift = a_l - b_l; shift >= 0; shift--) {
- quotientDigit = base - 1;
- if (remainder[shift + b_l] !== divisorMostSignificantDigit) {
- quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit);
- }
- // quotientDigit <= base - 1
- carry = 0;
- borrow = 0;
- l = divisor.length;
- for (i = 0; i < l; i++) {
- carry += quotientDigit * divisor[i];
- q = Math.floor(carry / base);
- borrow += remainder[shift + i] - (carry - q * base);
- carry = q;
- if (borrow < 0) {
- remainder[shift + i] = borrow + base;
- borrow = -1;
- } else {
- remainder[shift + i] = borrow;
- borrow = 0;
- }
- }
- while (borrow !== 0) {
- quotientDigit -= 1;
- carry = 0;
- for (i = 0; i < l; i++) {
- carry += remainder[shift + i] - base + divisor[i];
- if (carry < 0) {
- remainder[shift + i] = carry + base;
- carry = 0;
- } else {
- remainder[shift + i] = carry;
- carry = 1;
- }
- }
- borrow += carry;
- }
- result[shift] = quotientDigit;
- }
- // denormalization
- remainder = divModSmall(remainder, lambda)[0];
- return [arrayToSmall(result), arrayToSmall(remainder)];
- }
-
- function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
- // Performs faster than divMod1 on larger input sizes.
- var a_l = a.length,
- b_l = b.length,
- result = [],
- part = [],
- base = BASE,
- guess, xlen, highx, highy, check;
- while (a_l) {
- part.unshift(a[--a_l]);
- trim(part);
- if (compareAbs(part, b) < 0) {
- result.push(0);
- continue;
- }
- xlen = part.length;
- highx = part[xlen - 1] * base + part[xlen - 2];
- highy = b[b_l - 1] * base + b[b_l - 2];
- if (xlen > b_l) {
- highx = (highx + 1) * base;
- }
- guess = Math.ceil(highx / highy);
- do {
- check = multiplySmall(b, guess);
- if (compareAbs(check, part) <= 0) break;
- guess--;
- } while (guess);
- result.push(guess);
- part = subtract(part, check);
- }
- result.reverse();
- return [arrayToSmall(result), arrayToSmall(part)];
- }
-
- function divModSmall(value, lambda) {
- var length = value.length,
- quotient = createArray(length),
- base = BASE,
- i, q, remainder, divisor;
- remainder = 0;
- for (i = length - 1; i >= 0; --i) {
- divisor = remainder * base + value[i];
- q = truncate(divisor / lambda);
- remainder = divisor - q * lambda;
- quotient[i] = q | 0;
- }
- return [quotient, remainder | 0];
- }
-
- function divModAny(self, v) {
- var value, n = parseValue(v);
- if (supportsNativeBigInt) {
- return [new NativeBigInt(self.value / n.value), new NativeBigInt(self.value % n.value)];
- }
- var a = self.value, b = n.value;
- var quotient;
- if (b === 0) throw new Error("Cannot divide by zero");
- if (self.isSmall) {
- if (n.isSmall) {
- return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)];
- }
- return [Integer[0], self];
- }
- if (n.isSmall) {
- if (b === 1) return [self, Integer[0]];
- if (b == -1) return [self.negate(), Integer[0]];
- var abs = Math.abs(b);
- if (abs < BASE) {
- value = divModSmall(a, abs);
- quotient = arrayToSmall(value[0]);
- var remainder = value[1];
- if (self.sign) remainder = -remainder;
- if (typeof quotient === "number") {
- if (self.sign !== n.sign) quotient = -quotient;
- return [new SmallInteger(quotient), new SmallInteger(remainder)];
- }
- return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)];
- }
- b = smallToArray(abs);
- }
- var comparison = compareAbs(a, b);
- if (comparison === -1) return [Integer[0], self];
- if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]];
-
- // divMod1 is faster on smaller input sizes
- if (a.length + b.length <= 200)
- value = divMod1(a, b);
- else value = divMod2(a, b);
-
- quotient = value[0];
- var qSign = self.sign !== n.sign,
- mod = value[1],
- mSign = self.sign;
- if (typeof quotient === "number") {
- if (qSign) quotient = -quotient;
- quotient = new SmallInteger(quotient);
- } else quotient = new BigInteger(quotient, qSign);
- if (typeof mod === "number") {
- if (mSign) mod = -mod;
- mod = new SmallInteger(mod);
- } else mod = new BigInteger(mod, mSign);
- return [quotient, mod];
- }
-
- BigInteger.prototype.divmod = function (v) {
- var result = divModAny(this, v);
- return {
- quotient: result[0],
- remainder: result[1]
- };
- };
- NativeBigInt.prototype.divmod = SmallInteger.prototype.divmod = BigInteger.prototype.divmod;
-
-
- BigInteger.prototype.divide = function (v) {
- return divModAny(this, v)[0];
- };
- NativeBigInt.prototype.over = NativeBigInt.prototype.divide = function (v) {
- return new NativeBigInt(this.value / parseValue(v).value);
- };
- SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
-
- BigInteger.prototype.mod = function (v) {
- return divModAny(this, v)[1];
- };
- NativeBigInt.prototype.mod = NativeBigInt.prototype.remainder = function (v) {
- return new NativeBigInt(this.value % parseValue(v).value);
- };
- SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
-
- BigInteger.prototype.pow = function (v) {
- var n = parseValue(v),
- a = this.value,
- b = n.value,
- value, x, y;
- if (b === 0) return Integer[1];
- if (a === 0) return Integer[0];
- if (a === 1) return Integer[1];
- if (a === -1) return n.isEven() ? Integer[1] : Integer[-1];
- if (n.sign) {
- return Integer[0];
- }
- if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large.");
- if (this.isSmall) {
- if (isPrecise(value = Math.pow(a, b)))
- return new SmallInteger(truncate(value));
- }
- x = this;
- y = Integer[1];
- while (true) {
- if (b & 1 === 1) {
- y = y.times(x);
- --b;
- }
- if (b === 0) break;
- b /= 2;
- x = x.square();
- }
- return y;
- };
- SmallInteger.prototype.pow = BigInteger.prototype.pow;
-
- NativeBigInt.prototype.pow = function (v) {
- var n = parseValue(v);
- var a = this.value, b = n.value;
- var _0 = BigInt(0), _1 = BigInt(1), _2 = BigInt(2);
- if (b === _0) return Integer[1];
- if (a === _0) return Integer[0];
- if (a === _1) return Integer[1];
- if (a === BigInt(-1)) return n.isEven() ? Integer[1] : Integer[-1];
- if (n.isNegative()) return new NativeBigInt(_0);
- var x = this;
- var y = Integer[1];
- while (true) {
- if ((b & _1) === _1) {
- y = y.times(x);
- --b;
- }
- if (b === _0) break;
- b /= _2;
- x = x.square();
- }
- return y;
- }
-
- BigInteger.prototype.modPow = function (exp, mod) {
- exp = parseValue(exp);
- mod = parseValue(mod);
- if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
- var r = Integer[1],
- base = this.mod(mod);
- while (exp.isPositive()) {
- if (base.isZero()) return Integer[0];
- if (exp.isOdd()) r = r.multiply(base).mod(mod);
- exp = exp.divide(2);
- base = base.square().mod(mod);
- }
- return r;
- };
- NativeBigInt.prototype.modPow = SmallInteger.prototype.modPow = BigInteger.prototype.modPow;
-
- function compareAbs(a, b) {
- if (a.length !== b.length) {
- return a.length > b.length ? 1 : -1;
- }
- for (var i = a.length - 1; i >= 0; i--) {
- if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
- }
- return 0;
- }
-
- BigInteger.prototype.compareAbs = function (v) {
- var n = parseValue(v),
- a = this.value,
- b = n.value;
- if (n.isSmall) return 1;
- return compareAbs(a, b);
- };
- SmallInteger.prototype.compareAbs = function (v) {
- var n = parseValue(v),
- a = Math.abs(this.value),
- b = n.value;
- if (n.isSmall) {
- b = Math.abs(b);
- return a === b ? 0 : a > b ? 1 : -1;
- }
- return -1;
- };
- NativeBigInt.prototype.compareAbs = function (v) {
- var a = this.value;
- var b = parseValue(v).value;
- a = a >= 0 ? a : -a;
- b = b >= 0 ? b : -b;
- return a === b ? 0 : a > b ? 1 : -1;
- }
-
- BigInteger.prototype.compare = function (v) {
- // See discussion about comparison with Infinity:
- // https://github.com/peterolson/BigInteger.js/issues/61
- if (v === Infinity) {
- return -1;
- }
- if (v === -Infinity) {
- return 1;
- }
-
- var n = parseValue(v),
- a = this.value,
- b = n.value;
- if (this.sign !== n.sign) {
- return n.sign ? 1 : -1;
- }
- if (n.isSmall) {
- return this.sign ? -1 : 1;
- }
- return compareAbs(a, b) * (this.sign ? -1 : 1);
- };
- BigInteger.prototype.compareTo = BigInteger.prototype.compare;
-
- SmallInteger.prototype.compare = function (v) {
- if (v === Infinity) {
- return -1;
- }
- if (v === -Infinity) {
- return 1;
- }
-
- var n = parseValue(v),
- a = this.value,
- b = n.value;
- if (n.isSmall) {
- return a == b ? 0 : a > b ? 1 : -1;
- }
- if (a < 0 !== n.sign) {
- return a < 0 ? -1 : 1;
- }
- return a < 0 ? 1 : -1;
- };
- SmallInteger.prototype.compareTo = SmallInteger.prototype.compare;
-
- NativeBigInt.prototype.compare = function (v) {
- if (v === Infinity) {
- return -1;
- }
- if (v === -Infinity) {
- return 1;
- }
- var a = this.value;
- var b = parseValue(v).value;
- return a === b ? 0 : a > b ? 1 : -1;
- }
- NativeBigInt.prototype.compareTo = NativeBigInt.prototype.compare;
-
- BigInteger.prototype.equals = function (v) {
- return this.compare(v) === 0;
- };
- NativeBigInt.prototype.eq = NativeBigInt.prototype.equals = SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals;
-
- BigInteger.prototype.notEquals = function (v) {
- return this.compare(v) !== 0;
- };
- NativeBigInt.prototype.neq = NativeBigInt.prototype.notEquals = SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals;
-
- BigInteger.prototype.greater = function (v) {
- return this.compare(v) > 0;
- };
- NativeBigInt.prototype.gt = NativeBigInt.prototype.greater = SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater;
-
- BigInteger.prototype.lesser = function (v) {
- return this.compare(v) < 0;
- };
- NativeBigInt.prototype.lt = NativeBigInt.prototype.lesser = SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser;
-
- BigInteger.prototype.greaterOrEquals = function (v) {
- return this.compare(v) >= 0;
- };
- NativeBigInt.prototype.geq = NativeBigInt.prototype.greaterOrEquals = SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals;
-
- BigInteger.prototype.lesserOrEquals = function (v) {
- return this.compare(v) <= 0;
- };
- NativeBigInt.prototype.leq = NativeBigInt.prototype.lesserOrEquals = SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals;
-
- BigInteger.prototype.isEven = function () {
- return (this.value[0] & 1) === 0;
- };
- SmallInteger.prototype.isEven = function () {
- return (this.value & 1) === 0;
- };
- NativeBigInt.prototype.isEven = function () {
- return (this.value & BigInt(1)) === BigInt(0);
- }
-
- BigInteger.prototype.isOdd = function () {
- return (this.value[0] & 1) === 1;
- };
- SmallInteger.prototype.isOdd = function () {
- return (this.value & 1) === 1;
- };
- NativeBigInt.prototype.isOdd = function () {
- return (this.value & BigInt(1)) === BigInt(1);
- }
-
- BigInteger.prototype.isPositive = function () {
- return !this.sign;
- };
- SmallInteger.prototype.isPositive = function () {
- return this.value > 0;
- };
- NativeBigInt.prototype.isPositive = SmallInteger.prototype.isPositive;
-
- BigInteger.prototype.isNegative = function () {
- return this.sign;
- };
- SmallInteger.prototype.isNegative = function () {
- return this.value < 0;
- };
- NativeBigInt.prototype.isNegative = SmallInteger.prototype.isNegative;
-
- BigInteger.prototype.isUnit = function () {
- return false;
- };
- SmallInteger.prototype.isUnit = function () {
- return Math.abs(this.value) === 1;
- };
- NativeBigInt.prototype.isUnit = function () {
- return this.abs().value === BigInt(1);
- }
-
- BigInteger.prototype.isZero = function () {
- return false;
- };
- SmallInteger.prototype.isZero = function () {
- return this.value === 0;
- };
- NativeBigInt.prototype.isZero = function () {
- return this.value === BigInt(0);
- }
-
- BigInteger.prototype.isDivisibleBy = function (v) {
- var n = parseValue(v);
- if (n.isZero()) return false;
- if (n.isUnit()) return true;
- if (n.compareAbs(2) === 0) return this.isEven();
- return this.mod(n).isZero();
- };
- NativeBigInt.prototype.isDivisibleBy = SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy;
-
- function isBasicPrime(v) {
- var n = v.abs();
- if (n.isUnit()) return false;
- if (n.equals(2) || n.equals(3) || n.equals(5)) return true;
- if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false;
- if (n.lesser(49)) return true;
- // we don't know if it's prime: let the other functions figure it out
- }
-
- function millerRabinTest(n, a) {
- var nPrev = n.prev(),
- b = nPrev,
- r = 0,
- d, t, i, x;
- while (b.isEven()) b = b.divide(2), r++;
- next: for (i = 0; i < a.length; i++) {
- if (n.lesser(a[i])) continue;
- x = bigInt(a[i]).modPow(b, n);
- if (x.isUnit() || x.equals(nPrev)) continue;
- for (d = r - 1; d != 0; d--) {
- x = x.square().mod(n);
- if (x.isUnit()) return false;
- if (x.equals(nPrev)) continue next;
- }
- return false;
- }
- return true;
- }
-
- // Set "strict" to true to force GRH-supported lower bound of 2*log(N)^2
- BigInteger.prototype.isPrime = function (strict) {
- var isPrime = isBasicPrime(this);
- if (isPrime !== undefined) return isPrime;
- var n = this.abs();
- var bits = n.bitLength();
- if (bits <= 64)
- return millerRabinTest(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]);
- var logN = Math.log(2) * bits.toJSNumber();
- var t = Math.ceil((strict === true) ? (2 * Math.pow(logN, 2)) : logN);
- for (var a = [], i = 0; i < t; i++) {
- a.push(bigInt(i + 2));
- }
- return millerRabinTest(n, a);
- };
- NativeBigInt.prototype.isPrime = SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
-
- BigInteger.prototype.isProbablePrime = function (iterations) {
- var isPrime = isBasicPrime(this);
- if (isPrime !== undefined) return isPrime;
- var n = this.abs();
- var t = iterations === undefined ? 5 : iterations;
- for (var a = [], i = 0; i < t; i++) {
- a.push(bigInt.randBetween(2, n.minus(2)));
- }
- return millerRabinTest(n, a);
- };
- NativeBigInt.prototype.isProbablePrime = SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime;
-
- BigInteger.prototype.modInv = function (n) {
- var t = bigInt.zero, newT = bigInt.one, r = parseValue(n), newR = this.abs(), q, lastT, lastR;
- while (!newR.isZero()) {
- q = r.divide(newR);
- lastT = t;
- lastR = r;
- t = newT;
- r = newR;
- newT = lastT.subtract(q.multiply(newT));
- newR = lastR.subtract(q.multiply(newR));
- }
- if (!r.isUnit()) throw new Error(this.toString() + " and " + n.toString() + " are not co-prime");
- if (t.compare(0) === -1) {
- t = t.add(n);
- }
- if (this.isNegative()) {
- return t.negate();
- }
- return t;
- };
-
- NativeBigInt.prototype.modInv = SmallInteger.prototype.modInv = BigInteger.prototype.modInv;
-
- BigInteger.prototype.next = function () {
- var value = this.value;
- if (this.sign) {
- return subtractSmall(value, 1, this.sign);
- }
- return new BigInteger(addSmall(value, 1), this.sign);
- };
- SmallInteger.prototype.next = function () {
- var value = this.value;
- if (value + 1 < MAX_INT) return new SmallInteger(value + 1);
- return new BigInteger(MAX_INT_ARR, false);
- };
- NativeBigInt.prototype.next = function () {
- return new NativeBigInt(this.value + BigInt(1));
- }
-
- BigInteger.prototype.prev = function () {
- var value = this.value;
- if (this.sign) {
- return new BigInteger(addSmall(value, 1), true);
- }
- return subtractSmall(value, 1, this.sign);
- };
- SmallInteger.prototype.prev = function () {
- var value = this.value;
- if (value - 1 > -MAX_INT) return new SmallInteger(value - 1);
- return new BigInteger(MAX_INT_ARR, true);
- };
- NativeBigInt.prototype.prev = function () {
- return new NativeBigInt(this.value - BigInt(1));
- }
-
- var powersOfTwo = [1];
- while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
- var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
-
- function shift_isSmall(n) {
- return Math.abs(n) <= BASE;
- }
-
- BigInteger.prototype.shiftLeft = function (v) {
- var n = parseValue(v).toJSNumber();
- if (!shift_isSmall(n)) {
- throw new Error(String(n) + " is too large for shifting.");
- }
- if (n < 0) return this.shiftRight(-n);
- var result = this;
- if (result.isZero()) return result;
- while (n >= powers2Length) {
- result = result.multiply(highestPower2);
- n -= powers2Length - 1;
- }
- return result.multiply(powersOfTwo[n]);
- };
- NativeBigInt.prototype.shiftLeft = SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft;
-
- BigInteger.prototype.shiftRight = function (v) {
- var remQuo;
- var n = parseValue(v).toJSNumber();
- if (!shift_isSmall(n)) {
- throw new Error(String(n) + " is too large for shifting.");
- }
- if (n < 0) return this.shiftLeft(-n);
- var result = this;
- while (n >= powers2Length) {
- if (result.isZero() || (result.isNegative() && result.isUnit())) return result;
- remQuo = divModAny(result, highestPower2);
- result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
- n -= powers2Length - 1;
- }
- remQuo = divModAny(result, powersOfTwo[n]);
- return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
- };
- NativeBigInt.prototype.shiftRight = SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight;
-
- function bitwise(x, y, fn) {
- y = parseValue(y);
- var xSign = x.isNegative(), ySign = y.isNegative();
- var xRem = xSign ? x.not() : x,
- yRem = ySign ? y.not() : y;
- var xDigit = 0, yDigit = 0;
- var xDivMod = null, yDivMod = null;
- var result = [];
- while (!xRem.isZero() || !yRem.isZero()) {
- xDivMod = divModAny(xRem, highestPower2);
- xDigit = xDivMod[1].toJSNumber();
- if (xSign) {
- xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
- }
-
- yDivMod = divModAny(yRem, highestPower2);
- yDigit = yDivMod[1].toJSNumber();
- if (ySign) {
- yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
- }
-
- xRem = xDivMod[0];
- yRem = yDivMod[0];
- result.push(fn(xDigit, yDigit));
- }
- var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0);
- for (var i = result.length - 1; i >= 0; i -= 1) {
- sum = sum.multiply(highestPower2).add(bigInt(result[i]));
- }
- return sum;
- }
-
- BigInteger.prototype.not = function () {
- return this.negate().prev();
- };
- NativeBigInt.prototype.not = SmallInteger.prototype.not = BigInteger.prototype.not;
-
- BigInteger.prototype.and = function (n) {
- return bitwise(this, n, function (a, b) { return a & b; });
- };
- NativeBigInt.prototype.and = SmallInteger.prototype.and = BigInteger.prototype.and;
-
- BigInteger.prototype.or = function (n) {
- return bitwise(this, n, function (a, b) { return a | b; });
- };
- NativeBigInt.prototype.or = SmallInteger.prototype.or = BigInteger.prototype.or;
-
- BigInteger.prototype.xor = function (n) {
- return bitwise(this, n, function (a, b) { return a ^ b; });
- };
- NativeBigInt.prototype.xor = SmallInteger.prototype.xor = BigInteger.prototype.xor;
-
- var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I;
- function roughLOB(n) { // get lowestOneBit (rough)
- // SmallInteger: return Min(lowestOneBit(n), 1 << 30)
- // BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
- var v = n.value,
- x = typeof v === "number" ? v | LOBMASK_I :
- typeof v === "bigint" ? v | BigInt(LOBMASK_I) :
- v[0] + v[1] * BASE | LOBMASK_BI;
- return x & -x;
- }
-
- function integerLogarithm(value, base) {
- if (base.compareTo(value) <= 0) {
- var tmp = integerLogarithm(value, base.square(base));
- var p = tmp.p;
- var e = tmp.e;
- var t = p.multiply(base);
- return t.compareTo(value) <= 0 ? { p: t, e: e * 2 + 1 } : { p: p, e: e * 2 };
- }
- return { p: bigInt(1), e: 0 };
- }
-
- BigInteger.prototype.bitLength = function () {
- var n = this;
- if (n.compareTo(bigInt(0)) < 0) {
- n = n.negate().subtract(bigInt(1));
- }
- if (n.compareTo(bigInt(0)) === 0) {
- return bigInt(0);
- }
- return bigInt(integerLogarithm(n, bigInt(2)).e).add(bigInt(1));
- }
- NativeBigInt.prototype.bitLength = SmallInteger.prototype.bitLength = BigInteger.prototype.bitLength;
-
- function max(a, b) {
- a = parseValue(a);
- b = parseValue(b);
- return a.greater(b) ? a : b;
- }
- function min(a, b) {
- a = parseValue(a);
- b = parseValue(b);
- return a.lesser(b) ? a : b;
- }
- function gcd(a, b) {
- a = parseValue(a).abs();
- b = parseValue(b).abs();
- if (a.equals(b)) return a;
- if (a.isZero()) return b;
- if (b.isZero()) return a;
- var c = Integer[1], d, t;
- while (a.isEven() && b.isEven()) {
- d = min(roughLOB(a), roughLOB(b));
- a = a.divide(d);
- b = b.divide(d);
- c = c.multiply(d);
- }
- while (a.isEven()) {
- a = a.divide(roughLOB(a));
- }
- do {
- while (b.isEven()) {
- b = b.divide(roughLOB(b));
- }
- if (a.greater(b)) {
- t = b; b = a; a = t;
- }
- b = b.subtract(a);
- } while (!b.isZero());
- return c.isUnit() ? a : a.multiply(c);
- }
- function lcm(a, b) {
- a = parseValue(a).abs();
- b = parseValue(b).abs();
- return a.divide(gcd(a, b)).multiply(b);
- }
- function randBetween(a, b) {
- a = parseValue(a);
- b = parseValue(b);
- var low = min(a, b), high = max(a, b);
- var range = high.subtract(low).add(1);
- if (range.isSmall) return low.add(Math.floor(Math.random() * range));
- var digits = toBase(range, BASE).value;
- var result = [], restricted = true;
- for (var i = 0; i < digits.length; i++) {
- var top = restricted ? digits[i] : BASE;
- var digit = truncate(Math.random() * top);
- result.push(digit);
- if (digit < top) restricted = false;
- }
- return low.add(Integer.fromArray(result, BASE, false));
- }
-
- var parseBase = function (text, base, alphabet, caseSensitive) {
- alphabet = alphabet || DEFAULT_ALPHABET;
- text = String(text);
- if (!caseSensitive) {
- text = text.toLowerCase();
- alphabet = alphabet.toLowerCase();
- }
- var length = text.length;
- var i;
- var absBase = Math.abs(base);
- var alphabetValues = {};
- for (i = 0; i < alphabet.length; i++) {
- alphabetValues[alphabet[i]] = i;
- }
- for (i = 0; i < length; i++) {
- var c = text[i];
- if (c === "-") continue;
- if (c in alphabetValues) {
- if (alphabetValues[c] >= absBase) {
- if (c === "1" && absBase === 1) continue;
- throw new Error(c + " is not a valid digit in base " + base + ".");
- }
- }
- }
- base = parseValue(base);
- var digits = [];
- var isNegative = text[0] === "-";
- for (i = isNegative ? 1 : 0; i < text.length; i++) {
- var c = text[i];
- if (c in alphabetValues) digits.push(parseValue(alphabetValues[c]));
- else if (c === "<") {
- var start = i;
- do { i++; } while (text[i] !== ">" && i < text.length);
- digits.push(parseValue(text.slice(start + 1, i)));
- }
- else throw new Error(c + " is not a valid character");
- }
- return parseBaseFromArray(digits, base, isNegative);
- };
-
- function parseBaseFromArray(digits, base, isNegative) {
- var val = Integer[0], pow = Integer[1], i;
- for (i = digits.length - 1; i >= 0; i--) {
- val = val.add(digits[i].times(pow));
- pow = pow.times(base);
- }
- return isNegative ? val.negate() : val;
- }
-
- function stringify(digit, alphabet) {
- alphabet = alphabet || DEFAULT_ALPHABET;
- if (digit < alphabet.length) {
- return alphabet[digit];
- }
- return "<" + digit + ">";
- }
-
- function toBase(n, base) {
- base = bigInt(base);
- if (base.isZero()) {
- if (n.isZero()) return { value: [0], isNegative: false };
- throw new Error("Cannot convert nonzero numbers to base 0.");
- }
- if (base.equals(-1)) {
- if (n.isZero()) return { value: [0], isNegative: false };
- if (n.isNegative())
- return {
- value: [].concat.apply([], Array.apply(null, Array(-n.toJSNumber()))
- .map(Array.prototype.valueOf, [1, 0])
- ),
- isNegative: false
- };
-
- var arr = Array.apply(null, Array(n.toJSNumber() - 1))
- .map(Array.prototype.valueOf, [0, 1]);
- arr.unshift([1]);
- return {
- value: [].concat.apply([], arr),
- isNegative: false
- };
- }
-
- var neg = false;
- if (n.isNegative() && base.isPositive()) {
- neg = true;
- n = n.abs();
- }
- if (base.isUnit()) {
- if (n.isZero()) return { value: [0], isNegative: false };
-
- return {
- value: Array.apply(null, Array(n.toJSNumber()))
- .map(Number.prototype.valueOf, 1),
- isNegative: neg
- };
- }
- var out = [];
- var left = n, divmod;
- while (left.isNegative() || left.compareAbs(base) >= 0) {
- divmod = left.divmod(base);
- left = divmod.quotient;
- var digit = divmod.remainder;
- if (digit.isNegative()) {
- digit = base.minus(digit).abs();
- left = left.next();
- }
- out.push(digit.toJSNumber());
- }
- out.push(left.toJSNumber());
- return { value: out.reverse(), isNegative: neg };
- }
-
- function toBaseString(n, base, alphabet) {
- var arr = toBase(n, base);
- return (arr.isNegative ? "-" : "") + arr.value.map(function (x) {
- return stringify(x, alphabet);
- }).join('');
- }
-
- BigInteger.prototype.toArray = function (radix) {
- return toBase(this, radix);
- };
-
- SmallInteger.prototype.toArray = function (radix) {
- return toBase(this, radix);
- };
-
- NativeBigInt.prototype.toArray = function (radix) {
- return toBase(this, radix);
- };
-
- BigInteger.prototype.toString = function (radix, alphabet) {
- if (radix === undefined) radix = 10;
- if (radix !== 10) return toBaseString(this, radix, alphabet);
- var v = this.value, l = v.length, str = String(v[--l]), zeros = "0000000", digit;
- while (--l >= 0) {
- digit = String(v[l]);
- str += zeros.slice(digit.length) + digit;
- }
- var sign = this.sign ? "-" : "";
- return sign + str;
- };
-
- SmallInteger.prototype.toString = function (radix, alphabet) {
- if (radix === undefined) radix = 10;
- if (radix != 10) return toBaseString(this, radix, alphabet);
- return String(this.value);
- };
-
- NativeBigInt.prototype.toString = SmallInteger.prototype.toString;
-
- NativeBigInt.prototype.toJSON = BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function () { return this.toString(); }
-
- BigInteger.prototype.valueOf = function () {
- return parseInt(this.toString(), 10);
- };
- BigInteger.prototype.toJSNumber = BigInteger.prototype.valueOf;
-
- SmallInteger.prototype.valueOf = function () {
- return this.value;
- };
- SmallInteger.prototype.toJSNumber = SmallInteger.prototype.valueOf;
- NativeBigInt.prototype.valueOf = NativeBigInt.prototype.toJSNumber = function () {
- return parseInt(this.toString(), 10);
- }
-
- function parseStringValue(v) {
- if (isPrecise(+v)) {
- var x = +v;
- if (x === truncate(x))
- return supportsNativeBigInt ? new NativeBigInt(BigInt(x)) : new SmallInteger(x);
- throw new Error("Invalid integer: " + v);
- }
- var sign = v[0] === "-";
- if (sign) v = v.slice(1);
- var split = v.split(/e/i);
- if (split.length > 2) throw new Error("Invalid integer: " + split.join("e"));
- if (split.length === 2) {
- var exp = split[1];
- if (exp[0] === "+") exp = exp.slice(1);
- exp = +exp;
- if (exp !== truncate(exp) || !isPrecise(exp)) throw new Error("Invalid integer: " + exp + " is not a valid exponent.");
- var text = split[0];
- var decimalPlace = text.indexOf(".");
- if (decimalPlace >= 0) {
- exp -= text.length - decimalPlace - 1;
- text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1);
- }
- if (exp < 0) throw new Error("Cannot include negative exponent part for integers");
- text += (new Array(exp + 1)).join("0");
- v = text;
- }
- var isValid = /^([0-9][0-9]*)$/.test(v);
- if (!isValid) throw new Error("Invalid integer: " + v);
- if (supportsNativeBigInt) {
- return new NativeBigInt(BigInt(sign ? "-" + v : v));
- }
- var r = [], max = v.length, l = LOG_BASE, min = max - l;
- while (max > 0) {
- r.push(+v.slice(min, max));
- min -= l;
- if (min < 0) min = 0;
- max -= l;
- }
- trim(r);
- return new BigInteger(r, sign);
- }
-
- function parseNumberValue(v) {
- if (supportsNativeBigInt) {
- return new NativeBigInt(BigInt(v));
- }
- if (isPrecise(v)) {
- if (v !== truncate(v)) throw new Error(v + " is not an integer.");
- return new SmallInteger(v);
- }
- return parseStringValue(v.toString());
- }
-
- function parseValue(v) {
- if (typeof v === "number") {
- return parseNumberValue(v);
- }
- if (typeof v === "string") {
- return parseStringValue(v);
- }
- if (typeof v === "bigint") {
- return new NativeBigInt(v);
- }
- return v;
- }
- // Pre-define numbers in range [-999,999]
- for (var i = 0; i < 1000; i++) {
- Integer[i] = parseValue(i);
- if (i > 0) Integer[-i] = parseValue(-i);
- }
- // Backwards compatibility
- Integer.one = Integer[1];
- Integer.zero = Integer[0];
- Integer.minusOne = Integer[-1];
- Integer.max = max;
- Integer.min = min;
- Integer.gcd = gcd;
- Integer.lcm = lcm;
- Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger || x instanceof NativeBigInt; };
- Integer.randBetween = randBetween;
-
- Integer.fromArray = function (digits, base, isNegative) {
- return parseBaseFromArray(digits.map(parseValue), parseValue(base || 10), isNegative);
- };
-
- return Integer;
-})();
-
-// Node.js check
-if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
- module.exports = bigInt;
-}
-
-//amd check
-if (typeof define === "function" && define.amd) {
- define("big-integer", [], function () {
- return bigInt;
- });
-}
+var bigInt = (function (undefined) {
+ "use strict";
+
+ var BASE = 1e7,
+ LOG_BASE = 7,
+ MAX_INT = 9007199254740992,
+ MAX_INT_ARR = smallToArray(MAX_INT),
+ DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+ var supportsNativeBigInt = typeof BigInt === "function";
+
+ function Integer(v, radix, alphabet, caseSensitive) {
+ if (typeof v === "undefined") return Integer[0];
+ if (typeof radix !== "undefined") return +radix === 10 && !alphabet ? parseValue(v) : parseBase(v, radix, alphabet, caseSensitive);
+ return parseValue(v);
+ }
+
+ function BigInteger(value, sign) {
+ this.value = value;
+ this.sign = sign;
+ this.isSmall = false;
+ }
+ BigInteger.prototype = Object.create(Integer.prototype);
+
+ function SmallInteger(value) {
+ this.value = value;
+ this.sign = value < 0;
+ this.isSmall = true;
+ }
+ SmallInteger.prototype = Object.create(Integer.prototype);
+
+ function NativeBigInt(value) {
+ this.value = value;
+ }
+ NativeBigInt.prototype = Object.create(Integer.prototype);
+
+ function isPrecise(n) {
+ return -MAX_INT < n && n < MAX_INT;
+ }
+
+ function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
+ if (n < 1e7)
+ return [n];
+ if (n < 1e14)
+ return [n % 1e7, Math.floor(n / 1e7)];
+ return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)];
+ }
+
+ function arrayToSmall(arr) { // If BASE changes this function may need to change
+ trim(arr);
+ var length = arr.length;
+ if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) {
+ switch (length) {
+ case 0: return 0;
+ case 1: return arr[0];
+ case 2: return arr[0] + arr[1] * BASE;
+ default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE;
+ }
+ }
+ return arr;
+ }
+
+ function trim(v) {
+ var i = v.length;
+ while (v[--i] === 0);
+ v.length = i + 1;
+ }
+
+ function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
+ var x = new Array(length);
+ var i = -1;
+ while (++i < length) {
+ x[i] = 0;
+ }
+ return x;
+ }
+
+ function truncate(n) {
+ if (n > 0) return Math.floor(n);
+ return Math.ceil(n);
+ }
+
+ function add(a, b) { // assumes a and b are arrays with a.length >= b.length
+ var l_a = a.length,
+ l_b = b.length,
+ r = new Array(l_a),
+ carry = 0,
+ base = BASE,
+ sum, i;
+ for (i = 0; i < l_b; i++) {
+ sum = a[i] + b[i] + carry;
+ carry = sum >= base ? 1 : 0;
+ r[i] = sum - carry * base;
+ }
+ while (i < l_a) {
+ sum = a[i] + carry;
+ carry = sum === base ? 1 : 0;
+ r[i++] = sum - carry * base;
+ }
+ if (carry > 0) r.push(carry);
+ return r;
+ }
+
+ function addAny(a, b) {
+ if (a.length >= b.length) return add(a, b);
+ return add(b, a);
+ }
+
+ function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
+ var l = a.length,
+ r = new Array(l),
+ base = BASE,
+ sum, i;
+ for (i = 0; i < l; i++) {
+ sum = a[i] - base + carry;
+ carry = Math.floor(sum / base);
+ r[i] = sum - carry * base;
+ carry += 1;
+ }
+ while (carry > 0) {
+ r[i++] = carry % base;
+ carry = Math.floor(carry / base);
+ }
+ return r;
+ }
+
+ BigInteger.prototype.add = function (v) {
+ var n = parseValue(v);
+ if (this.sign !== n.sign) {
+ return this.subtract(n.negate());
+ }
+ var a = this.value, b = n.value;
+ if (n.isSmall) {
+ return new BigInteger(addSmall(a, Math.abs(b)), this.sign);
+ }
+ return new BigInteger(addAny(a, b), this.sign);
+ };
+ BigInteger.prototype.plus = BigInteger.prototype.add;
+
+ SmallInteger.prototype.add = function (v) {
+ var n = parseValue(v);
+ var a = this.value;
+ if (a < 0 !== n.sign) {
+ return this.subtract(n.negate());
+ }
+ var b = n.value;
+ if (n.isSmall) {
+ if (isPrecise(a + b)) return new SmallInteger(a + b);
+ b = smallToArray(Math.abs(b));
+ }
+ return new BigInteger(addSmall(b, Math.abs(a)), a < 0);
+ };
+ SmallInteger.prototype.plus = SmallInteger.prototype.add;
+
+ NativeBigInt.prototype.add = function (v) {
+ return new NativeBigInt(this.value + parseValue(v).value);
+ }
+ NativeBigInt.prototype.plus = NativeBigInt.prototype.add;
+
+ function subtract(a, b) { // assumes a and b are arrays with a >= b
+ var a_l = a.length,
+ b_l = b.length,
+ r = new Array(a_l),
+ borrow = 0,
+ base = BASE,
+ i, difference;
+ for (i = 0; i < b_l; i++) {
+ difference = a[i] - borrow - b[i];
+ if (difference < 0) {
+ difference += base;
+ borrow = 1;
+ } else borrow = 0;
+ r[i] = difference;
+ }
+ for (i = b_l; i < a_l; i++) {
+ difference = a[i] - borrow;
+ if (difference < 0) difference += base;
+ else {
+ r[i++] = difference;
+ break;
+ }
+ r[i] = difference;
+ }
+ for (; i < a_l; i++) {
+ r[i] = a[i];
+ }
+ trim(r);
+ return r;
+ }
+
+ function subtractAny(a, b, sign) {
+ var value;
+ if (compareAbs(a, b) >= 0) {
+ value = subtract(a, b);
+ } else {
+ value = subtract(b, a);
+ sign = !sign;
+ }
+ value = arrayToSmall(value);
+ if (typeof value === "number") {
+ if (sign) value = -value;
+ return new SmallInteger(value);
+ }
+ return new BigInteger(value, sign);
+ }
+
+ function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
+ var l = a.length,
+ r = new Array(l),
+ carry = -b,
+ base = BASE,
+ i, difference;
+ for (i = 0; i < l; i++) {
+ difference = a[i] + carry;
+ carry = Math.floor(difference / base);
+ difference %= base;
+ r[i] = difference < 0 ? difference + base : difference;
+ }
+ r = arrayToSmall(r);
+ if (typeof r === "number") {
+ if (sign) r = -r;
+ return new SmallInteger(r);
+ } return new BigInteger(r, sign);
+ }
+
+ BigInteger.prototype.subtract = function (v) {
+ var n = parseValue(v);
+ if (this.sign !== n.sign) {
+ return this.add(n.negate());
+ }
+ var a = this.value, b = n.value;
+ if (n.isSmall)
+ return subtractSmall(a, Math.abs(b), this.sign);
+ return subtractAny(a, b, this.sign);
+ };
+ BigInteger.prototype.minus = BigInteger.prototype.subtract;
+
+ SmallInteger.prototype.subtract = function (v) {
+ var n = parseValue(v);
+ var a = this.value;
+ if (a < 0 !== n.sign) {
+ return this.add(n.negate());
+ }
+ var b = n.value;
+ if (n.isSmall) {
+ return new SmallInteger(a - b);
+ }
+ return subtractSmall(b, Math.abs(a), a >= 0);
+ };
+ SmallInteger.prototype.minus = SmallInteger.prototype.subtract;
+
+ NativeBigInt.prototype.subtract = function (v) {
+ return new NativeBigInt(this.value - parseValue(v).value);
+ }
+ NativeBigInt.prototype.minus = NativeBigInt.prototype.subtract;
+
+ BigInteger.prototype.negate = function () {
+ return new BigInteger(this.value, !this.sign);
+ };
+ SmallInteger.prototype.negate = function () {
+ var sign = this.sign;
+ var small = new SmallInteger(-this.value);
+ small.sign = !sign;
+ return small;
+ };
+ NativeBigInt.prototype.negate = function () {
+ return new NativeBigInt(-this.value);
+ }
+
+ BigInteger.prototype.abs = function () {
+ return new BigInteger(this.value, false);
+ };
+ SmallInteger.prototype.abs = function () {
+ return new SmallInteger(Math.abs(this.value));
+ };
+ NativeBigInt.prototype.abs = function () {
+ return new NativeBigInt(this.value >= 0 ? this.value : -this.value);
+ }
+
+
+ function multiplyLong(a, b) {
+ var a_l = a.length,
+ b_l = b.length,
+ l = a_l + b_l,
+ r = createArray(l),
+ base = BASE,
+ product, carry, i, a_i, b_j;
+ for (i = 0; i < a_l; ++i) {
+ a_i = a[i];
+ for (var j = 0; j < b_l; ++j) {
+ b_j = b[j];
+ product = a_i * b_j + r[i + j];
+ carry = Math.floor(product / base);
+ r[i + j] = product - carry * base;
+ r[i + j + 1] += carry;
+ }
+ }
+ trim(r);
+ return r;
+ }
+
+ function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
+ var l = a.length,
+ r = new Array(l),
+ base = BASE,
+ carry = 0,
+ product, i;
+ for (i = 0; i < l; i++) {
+ product = a[i] * b + carry;
+ carry = Math.floor(product / base);
+ r[i] = product - carry * base;
+ }
+ while (carry > 0) {
+ r[i++] = carry % base;
+ carry = Math.floor(carry / base);
+ }
+ return r;
+ }
+
+ function shiftLeft(x, n) {
+ var r = [];
+ while (n-- > 0) r.push(0);
+ return r.concat(x);
+ }
+
+ function multiplyKaratsuba(x, y) {
+ var n = Math.max(x.length, y.length);
+
+ if (n <= 30) return multiplyLong(x, y);
+ n = Math.ceil(n / 2);
+
+ var b = x.slice(n),
+ a = x.slice(0, n),
+ d = y.slice(n),
+ c = y.slice(0, n);
+
+ var ac = multiplyKaratsuba(a, c),
+ bd = multiplyKaratsuba(b, d),
+ abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d));
+
+ var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n));
+ trim(product);
+ return product;
+ }
+
+ // The following function is derived from a surface fit of a graph plotting the performance difference
+ // between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
+ function useKaratsuba(l1, l2) {
+ return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0;
+ }
+
+ BigInteger.prototype.multiply = function (v) {
+ var n = parseValue(v),
+ a = this.value, b = n.value,
+ sign = this.sign !== n.sign,
+ abs;
+ if (n.isSmall) {
+ if (b === 0) return Integer[0];
+ if (b === 1) return this;
+ if (b === -1) return this.negate();
+ abs = Math.abs(b);
+ if (abs < BASE) {
+ return new BigInteger(multiplySmall(a, abs), sign);
+ }
+ b = smallToArray(abs);
+ }
+ if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
+ return new BigInteger(multiplyKaratsuba(a, b), sign);
+ return new BigInteger(multiplyLong(a, b), sign);
+ };
+
+ BigInteger.prototype.times = BigInteger.prototype.multiply;
+
+ function multiplySmallAndArray(a, b, sign) { // a >= 0
+ if (a < BASE) {
+ return new BigInteger(multiplySmall(b, a), sign);
+ }
+ return new BigInteger(multiplyLong(b, smallToArray(a)), sign);
+ }
+ SmallInteger.prototype._multiplyBySmall = function (a) {
+ if (isPrecise(a.value * this.value)) {
+ return new SmallInteger(a.value * this.value);
+ }
+ return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign);
+ };
+ BigInteger.prototype._multiplyBySmall = function (a) {
+ if (a.value === 0) return Integer[0];
+ if (a.value === 1) return this;
+ if (a.value === -1) return this.negate();
+ return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign);
+ };
+ SmallInteger.prototype.multiply = function (v) {
+ return parseValue(v)._multiplyBySmall(this);
+ };
+ SmallInteger.prototype.times = SmallInteger.prototype.multiply;
+
+ NativeBigInt.prototype.multiply = function (v) {
+ return new NativeBigInt(this.value * parseValue(v).value);
+ }
+ NativeBigInt.prototype.times = NativeBigInt.prototype.multiply;
+
+ function square(a) {
+ //console.assert(2 * BASE * BASE < MAX_INT);
+ var l = a.length,
+ r = createArray(l + l),
+ base = BASE,
+ product, carry, i, a_i, a_j;
+ for (i = 0; i < l; i++) {
+ a_i = a[i];
+ carry = 0 - a_i * a_i;
+ for (var j = i; j < l; j++) {
+ a_j = a[j];
+ product = 2 * (a_i * a_j) + r[i + j] + carry;
+ carry = Math.floor(product / base);
+ r[i + j] = product - carry * base;
+ }
+ r[i + l] = carry;
+ }
+ trim(r);
+ return r;
+ }
+
+ BigInteger.prototype.square = function () {
+ return new BigInteger(square(this.value), false);
+ };
+
+ SmallInteger.prototype.square = function () {
+ var value = this.value * this.value;
+ if (isPrecise(value)) return new SmallInteger(value);
+ return new BigInteger(square(smallToArray(Math.abs(this.value))), false);
+ };
+
+ NativeBigInt.prototype.square = function (v) {
+ return new NativeBigInt(this.value * this.value);
+ }
+
+ function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
+ var a_l = a.length,
+ b_l = b.length,
+ base = BASE,
+ result = createArray(b.length),
+ divisorMostSignificantDigit = b[b_l - 1],
+ // normalization
+ lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)),
+ remainder = multiplySmall(a, lambda),
+ divisor = multiplySmall(b, lambda),
+ quotientDigit, shift, carry, borrow, i, l, q;
+ if (remainder.length <= a_l) remainder.push(0);
+ divisor.push(0);
+ divisorMostSignificantDigit = divisor[b_l - 1];
+ for (shift = a_l - b_l; shift >= 0; shift--) {
+ quotientDigit = base - 1;
+ if (remainder[shift + b_l] !== divisorMostSignificantDigit) {
+ quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit);
+ }
+ // quotientDigit <= base - 1
+ carry = 0;
+ borrow = 0;
+ l = divisor.length;
+ for (i = 0; i < l; i++) {
+ carry += quotientDigit * divisor[i];
+ q = Math.floor(carry / base);
+ borrow += remainder[shift + i] - (carry - q * base);
+ carry = q;
+ if (borrow < 0) {
+ remainder[shift + i] = borrow + base;
+ borrow = -1;
+ } else {
+ remainder[shift + i] = borrow;
+ borrow = 0;
+ }
+ }
+ while (borrow !== 0) {
+ quotientDigit -= 1;
+ carry = 0;
+ for (i = 0; i < l; i++) {
+ carry += remainder[shift + i] - base + divisor[i];
+ if (carry < 0) {
+ remainder[shift + i] = carry + base;
+ carry = 0;
+ } else {
+ remainder[shift + i] = carry;
+ carry = 1;
+ }
+ }
+ borrow += carry;
+ }
+ result[shift] = quotientDigit;
+ }
+ // denormalization
+ remainder = divModSmall(remainder, lambda)[0];
+ return [arrayToSmall(result), arrayToSmall(remainder)];
+ }
+
+ function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
+ // Performs faster than divMod1 on larger input sizes.
+ var a_l = a.length,
+ b_l = b.length,
+ result = [],
+ part = [],
+ base = BASE,
+ guess, xlen, highx, highy, check;
+ while (a_l) {
+ part.unshift(a[--a_l]);
+ trim(part);
+ if (compareAbs(part, b) < 0) {
+ result.push(0);
+ continue;
+ }
+ xlen = part.length;
+ highx = part[xlen - 1] * base + part[xlen - 2];
+ highy = b[b_l - 1] * base + b[b_l - 2];
+ if (xlen > b_l) {
+ highx = (highx + 1) * base;
+ }
+ guess = Math.ceil(highx / highy);
+ do {
+ check = multiplySmall(b, guess);
+ if (compareAbs(check, part) <= 0) break;
+ guess--;
+ } while (guess);
+ result.push(guess);
+ part = subtract(part, check);
+ }
+ result.reverse();
+ return [arrayToSmall(result), arrayToSmall(part)];
+ }
+
+ function divModSmall(value, lambda) {
+ var length = value.length,
+ quotient = createArray(length),
+ base = BASE,
+ i, q, remainder, divisor;
+ remainder = 0;
+ for (i = length - 1; i >= 0; --i) {
+ divisor = remainder * base + value[i];
+ q = truncate(divisor / lambda);
+ remainder = divisor - q * lambda;
+ quotient[i] = q | 0;
+ }
+ return [quotient, remainder | 0];
+ }
+
+ function divModAny(self, v) {
+ var value, n = parseValue(v);
+ if (supportsNativeBigInt) {
+ return [new NativeBigInt(self.value / n.value), new NativeBigInt(self.value % n.value)];
+ }
+ var a = self.value, b = n.value;
+ var quotient;
+ if (b === 0) throw new Error("Cannot divide by zero");
+ if (self.isSmall) {
+ if (n.isSmall) {
+ return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)];
+ }
+ return [Integer[0], self];
+ }
+ if (n.isSmall) {
+ if (b === 1) return [self, Integer[0]];
+ if (b == -1) return [self.negate(), Integer[0]];
+ var abs = Math.abs(b);
+ if (abs < BASE) {
+ value = divModSmall(a, abs);
+ quotient = arrayToSmall(value[0]);
+ var remainder = value[1];
+ if (self.sign) remainder = -remainder;
+ if (typeof quotient === "number") {
+ if (self.sign !== n.sign) quotient = -quotient;
+ return [new SmallInteger(quotient), new SmallInteger(remainder)];
+ }
+ return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)];
+ }
+ b = smallToArray(abs);
+ }
+ var comparison = compareAbs(a, b);
+ if (comparison === -1) return [Integer[0], self];
+ if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]];
+
+ // divMod1 is faster on smaller input sizes
+ if (a.length + b.length <= 200)
+ value = divMod1(a, b);
+ else value = divMod2(a, b);
+
+ quotient = value[0];
+ var qSign = self.sign !== n.sign,
+ mod = value[1],
+ mSign = self.sign;
+ if (typeof quotient === "number") {
+ if (qSign) quotient = -quotient;
+ quotient = new SmallInteger(quotient);
+ } else quotient = new BigInteger(quotient, qSign);
+ if (typeof mod === "number") {
+ if (mSign) mod = -mod;
+ mod = new SmallInteger(mod);
+ } else mod = new BigInteger(mod, mSign);
+ return [quotient, mod];
+ }
+
+ BigInteger.prototype.divmod = function (v) {
+ var result = divModAny(this, v);
+ return {
+ quotient: result[0],
+ remainder: result[1]
+ };
+ };
+ NativeBigInt.prototype.divmod = SmallInteger.prototype.divmod = BigInteger.prototype.divmod;
+
+
+ BigInteger.prototype.divide = function (v) {
+ return divModAny(this, v)[0];
+ };
+ NativeBigInt.prototype.over = NativeBigInt.prototype.divide = function (v) {
+ return new NativeBigInt(this.value / parseValue(v).value);
+ };
+ SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
+
+ BigInteger.prototype.mod = function (v) {
+ return divModAny(this, v)[1];
+ };
+ NativeBigInt.prototype.mod = NativeBigInt.prototype.remainder = function (v) {
+ return new NativeBigInt(this.value % parseValue(v).value);
+ };
+ SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
+
+ BigInteger.prototype.pow = function (v) {
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value,
+ value, x, y;
+ if (b === 0) return Integer[1];
+ if (a === 0) return Integer[0];
+ if (a === 1) return Integer[1];
+ if (a === -1) return n.isEven() ? Integer[1] : Integer[-1];
+ if (n.sign) {
+ return Integer[0];
+ }
+ if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large.");
+ if (this.isSmall) {
+ if (isPrecise(value = Math.pow(a, b)))
+ return new SmallInteger(truncate(value));
+ }
+ x = this;
+ y = Integer[1];
+ while (true) {
+ if (b & 1 === 1) {
+ y = y.times(x);
+ --b;
+ }
+ if (b === 0) break;
+ b /= 2;
+ x = x.square();
+ }
+ return y;
+ };
+ SmallInteger.prototype.pow = BigInteger.prototype.pow;
+
+ NativeBigInt.prototype.pow = function (v) {
+ var n = parseValue(v);
+ var a = this.value, b = n.value;
+ var _0 = BigInt(0), _1 = BigInt(1), _2 = BigInt(2);
+ if (b === _0) return Integer[1];
+ if (a === _0) return Integer[0];
+ if (a === _1) return Integer[1];
+ if (a === BigInt(-1)) return n.isEven() ? Integer[1] : Integer[-1];
+ if (n.isNegative()) return new NativeBigInt(_0);
+ var x = this;
+ var y = Integer[1];
+ while (true) {
+ if ((b & _1) === _1) {
+ y = y.times(x);
+ --b;
+ }
+ if (b === _0) break;
+ b /= _2;
+ x = x.square();
+ }
+ return y;
+ }
+
+ BigInteger.prototype.modPow = function (exp, mod) {
+ exp = parseValue(exp);
+ mod = parseValue(mod);
+ if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
+ var r = Integer[1],
+ base = this.mod(mod);
+ while (exp.isPositive()) {
+ if (base.isZero()) return Integer[0];
+ if (exp.isOdd()) r = r.multiply(base).mod(mod);
+ exp = exp.divide(2);
+ base = base.square().mod(mod);
+ }
+ return r;
+ };
+ NativeBigInt.prototype.modPow = SmallInteger.prototype.modPow = BigInteger.prototype.modPow;
+
+ function compareAbs(a, b) {
+ if (a.length !== b.length) {
+ return a.length > b.length ? 1 : -1;
+ }
+ for (var i = a.length - 1; i >= 0; i--) {
+ if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
+ }
+ return 0;
+ }
+
+ BigInteger.prototype.compareAbs = function (v) {
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value;
+ if (n.isSmall) return 1;
+ return compareAbs(a, b);
+ };
+ SmallInteger.prototype.compareAbs = function (v) {
+ var n = parseValue(v),
+ a = Math.abs(this.value),
+ b = n.value;
+ if (n.isSmall) {
+ b = Math.abs(b);
+ return a === b ? 0 : a > b ? 1 : -1;
+ }
+ return -1;
+ };
+ NativeBigInt.prototype.compareAbs = function (v) {
+ var a = this.value;
+ var b = parseValue(v).value;
+ a = a >= 0 ? a : -a;
+ b = b >= 0 ? b : -b;
+ return a === b ? 0 : a > b ? 1 : -1;
+ }
+
+ BigInteger.prototype.compare = function (v) {
+ // See discussion about comparison with Infinity:
+ // https://github.com/peterolson/BigInteger.js/issues/61
+ if (v === Infinity) {
+ return -1;
+ }
+ if (v === -Infinity) {
+ return 1;
+ }
+
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value;
+ if (this.sign !== n.sign) {
+ return n.sign ? 1 : -1;
+ }
+ if (n.isSmall) {
+ return this.sign ? -1 : 1;
+ }
+ return compareAbs(a, b) * (this.sign ? -1 : 1);
+ };
+ BigInteger.prototype.compareTo = BigInteger.prototype.compare;
+
+ SmallInteger.prototype.compare = function (v) {
+ if (v === Infinity) {
+ return -1;
+ }
+ if (v === -Infinity) {
+ return 1;
+ }
+
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value;
+ if (n.isSmall) {
+ return a == b ? 0 : a > b ? 1 : -1;
+ }
+ if (a < 0 !== n.sign) {
+ return a < 0 ? -1 : 1;
+ }
+ return a < 0 ? 1 : -1;
+ };
+ SmallInteger.prototype.compareTo = SmallInteger.prototype.compare;
+
+ NativeBigInt.prototype.compare = function (v) {
+ if (v === Infinity) {
+ return -1;
+ }
+ if (v === -Infinity) {
+ return 1;
+ }
+ var a = this.value;
+ var b = parseValue(v).value;
+ return a === b ? 0 : a > b ? 1 : -1;
+ }
+ NativeBigInt.prototype.compareTo = NativeBigInt.prototype.compare;
+
+ BigInteger.prototype.equals = function (v) {
+ return this.compare(v) === 0;
+ };
+ NativeBigInt.prototype.eq = NativeBigInt.prototype.equals = SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals;
+
+ BigInteger.prototype.notEquals = function (v) {
+ return this.compare(v) !== 0;
+ };
+ NativeBigInt.prototype.neq = NativeBigInt.prototype.notEquals = SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals;
+
+ BigInteger.prototype.greater = function (v) {
+ return this.compare(v) > 0;
+ };
+ NativeBigInt.prototype.gt = NativeBigInt.prototype.greater = SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater;
+
+ BigInteger.prototype.lesser = function (v) {
+ return this.compare(v) < 0;
+ };
+ NativeBigInt.prototype.lt = NativeBigInt.prototype.lesser = SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser;
+
+ BigInteger.prototype.greaterOrEquals = function (v) {
+ return this.compare(v) >= 0;
+ };
+ NativeBigInt.prototype.geq = NativeBigInt.prototype.greaterOrEquals = SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals;
+
+ BigInteger.prototype.lesserOrEquals = function (v) {
+ return this.compare(v) <= 0;
+ };
+ NativeBigInt.prototype.leq = NativeBigInt.prototype.lesserOrEquals = SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals;
+
+ BigInteger.prototype.isEven = function () {
+ return (this.value[0] & 1) === 0;
+ };
+ SmallInteger.prototype.isEven = function () {
+ return (this.value & 1) === 0;
+ };
+ NativeBigInt.prototype.isEven = function () {
+ return (this.value & BigInt(1)) === BigInt(0);
+ }
+
+ BigInteger.prototype.isOdd = function () {
+ return (this.value[0] & 1) === 1;
+ };
+ SmallInteger.prototype.isOdd = function () {
+ return (this.value & 1) === 1;
+ };
+ NativeBigInt.prototype.isOdd = function () {
+ return (this.value & BigInt(1)) === BigInt(1);
+ }
+
+ BigInteger.prototype.isPositive = function () {
+ return !this.sign;
+ };
+ SmallInteger.prototype.isPositive = function () {
+ return this.value > 0;
+ };
+ NativeBigInt.prototype.isPositive = SmallInteger.prototype.isPositive;
+
+ BigInteger.prototype.isNegative = function () {
+ return this.sign;
+ };
+ SmallInteger.prototype.isNegative = function () {
+ return this.value < 0;
+ };
+ NativeBigInt.prototype.isNegative = SmallInteger.prototype.isNegative;
+
+ BigInteger.prototype.isUnit = function () {
+ return false;
+ };
+ SmallInteger.prototype.isUnit = function () {
+ return Math.abs(this.value) === 1;
+ };
+ NativeBigInt.prototype.isUnit = function () {
+ return this.abs().value === BigInt(1);
+ }
+
+ BigInteger.prototype.isZero = function () {
+ return false;
+ };
+ SmallInteger.prototype.isZero = function () {
+ return this.value === 0;
+ };
+ NativeBigInt.prototype.isZero = function () {
+ return this.value === BigInt(0);
+ }
+
+ BigInteger.prototype.isDivisibleBy = function (v) {
+ var n = parseValue(v);
+ if (n.isZero()) return false;
+ if (n.isUnit()) return true;
+ if (n.compareAbs(2) === 0) return this.isEven();
+ return this.mod(n).isZero();
+ };
+ NativeBigInt.prototype.isDivisibleBy = SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy;
+
+ function isBasicPrime(v) {
+ var n = v.abs();
+ if (n.isUnit()) return false;
+ if (n.equals(2) || n.equals(3) || n.equals(5)) return true;
+ if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false;
+ if (n.lesser(49)) return true;
+ // we don't know if it's prime: let the other functions figure it out
+ }
+
+ function millerRabinTest(n, a) {
+ var nPrev = n.prev(),
+ b = nPrev,
+ r = 0,
+ d, t, i, x;
+ while (b.isEven()) b = b.divide(2), r++;
+ next: for (i = 0; i < a.length; i++) {
+ if (n.lesser(a[i])) continue;
+ x = bigInt(a[i]).modPow(b, n);
+ if (x.isUnit() || x.equals(nPrev)) continue;
+ for (d = r - 1; d != 0; d--) {
+ x = x.square().mod(n);
+ if (x.isUnit()) return false;
+ if (x.equals(nPrev)) continue next;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ // Set "strict" to true to force GRH-supported lower bound of 2*log(N)^2
+ BigInteger.prototype.isPrime = function (strict) {
+ var isPrime = isBasicPrime(this);
+ if (isPrime !== undefined) return isPrime;
+ var n = this.abs();
+ var bits = n.bitLength();
+ if (bits <= 64)
+ return millerRabinTest(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]);
+ var logN = Math.log(2) * bits.toJSNumber();
+ var t = Math.ceil((strict === true) ? (2 * Math.pow(logN, 2)) : logN);
+ for (var a = [], i = 0; i < t; i++) {
+ a.push(bigInt(i + 2));
+ }
+ return millerRabinTest(n, a);
+ };
+ NativeBigInt.prototype.isPrime = SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
+
+ BigInteger.prototype.isProbablePrime = function (iterations) {
+ var isPrime = isBasicPrime(this);
+ if (isPrime !== undefined) return isPrime;
+ var n = this.abs();
+ var t = iterations === undefined ? 5 : iterations;
+ for (var a = [], i = 0; i < t; i++) {
+ a.push(bigInt.randBetween(2, n.minus(2)));
+ }
+ return millerRabinTest(n, a);
+ };
+ NativeBigInt.prototype.isProbablePrime = SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime;
+
+ BigInteger.prototype.modInv = function (n) {
+ var t = bigInt.zero, newT = bigInt.one, r = parseValue(n), newR = this.abs(), q, lastT, lastR;
+ while (!newR.isZero()) {
+ q = r.divide(newR);
+ lastT = t;
+ lastR = r;
+ t = newT;
+ r = newR;
+ newT = lastT.subtract(q.multiply(newT));
+ newR = lastR.subtract(q.multiply(newR));
+ }
+ if (!r.isUnit()) throw new Error(this.toString() + " and " + n.toString() + " are not co-prime");
+ if (t.compare(0) === -1) {
+ t = t.add(n);
+ }
+ if (this.isNegative()) {
+ return t.negate();
+ }
+ return t;
+ };
+
+ NativeBigInt.prototype.modInv = SmallInteger.prototype.modInv = BigInteger.prototype.modInv;
+
+ BigInteger.prototype.next = function () {
+ var value = this.value;
+ if (this.sign) {
+ return subtractSmall(value, 1, this.sign);
+ }
+ return new BigInteger(addSmall(value, 1), this.sign);
+ };
+ SmallInteger.prototype.next = function () {
+ var value = this.value;
+ if (value + 1 < MAX_INT) return new SmallInteger(value + 1);
+ return new BigInteger(MAX_INT_ARR, false);
+ };
+ NativeBigInt.prototype.next = function () {
+ return new NativeBigInt(this.value + BigInt(1));
+ }
+
+ BigInteger.prototype.prev = function () {
+ var value = this.value;
+ if (this.sign) {
+ return new BigInteger(addSmall(value, 1), true);
+ }
+ return subtractSmall(value, 1, this.sign);
+ };
+ SmallInteger.prototype.prev = function () {
+ var value = this.value;
+ if (value - 1 > -MAX_INT) return new SmallInteger(value - 1);
+ return new BigInteger(MAX_INT_ARR, true);
+ };
+ NativeBigInt.prototype.prev = function () {
+ return new NativeBigInt(this.value - BigInt(1));
+ }
+
+ var powersOfTwo = [1];
+ while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
+ var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
+
+ function shift_isSmall(n) {
+ return Math.abs(n) <= BASE;
+ }
+
+ BigInteger.prototype.shiftLeft = function (v) {
+ var n = parseValue(v).toJSNumber();
+ if (!shift_isSmall(n)) {
+ throw new Error(String(n) + " is too large for shifting.");
+ }
+ if (n < 0) return this.shiftRight(-n);
+ var result = this;
+ if (result.isZero()) return result;
+ while (n >= powers2Length) {
+ result = result.multiply(highestPower2);
+ n -= powers2Length - 1;
+ }
+ return result.multiply(powersOfTwo[n]);
+ };
+ NativeBigInt.prototype.shiftLeft = SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft;
+
+ BigInteger.prototype.shiftRight = function (v) {
+ var remQuo;
+ var n = parseValue(v).toJSNumber();
+ if (!shift_isSmall(n)) {
+ throw new Error(String(n) + " is too large for shifting.");
+ }
+ if (n < 0) return this.shiftLeft(-n);
+ var result = this;
+ while (n >= powers2Length) {
+ if (result.isZero() || (result.isNegative() && result.isUnit())) return result;
+ remQuo = divModAny(result, highestPower2);
+ result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
+ n -= powers2Length - 1;
+ }
+ remQuo = divModAny(result, powersOfTwo[n]);
+ return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
+ };
+ NativeBigInt.prototype.shiftRight = SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight;
+
+ function bitwise(x, y, fn) {
+ y = parseValue(y);
+ var xSign = x.isNegative(), ySign = y.isNegative();
+ var xRem = xSign ? x.not() : x,
+ yRem = ySign ? y.not() : y;
+ var xDigit = 0, yDigit = 0;
+ var xDivMod = null, yDivMod = null;
+ var result = [];
+ while (!xRem.isZero() || !yRem.isZero()) {
+ xDivMod = divModAny(xRem, highestPower2);
+ xDigit = xDivMod[1].toJSNumber();
+ if (xSign) {
+ xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
+ }
+
+ yDivMod = divModAny(yRem, highestPower2);
+ yDigit = yDivMod[1].toJSNumber();
+ if (ySign) {
+ yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
+ }
+
+ xRem = xDivMod[0];
+ yRem = yDivMod[0];
+ result.push(fn(xDigit, yDigit));
+ }
+ var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0);
+ for (var i = result.length - 1; i >= 0; i -= 1) {
+ sum = sum.multiply(highestPower2).add(bigInt(result[i]));
+ }
+ return sum;
+ }
+
+ BigInteger.prototype.not = function () {
+ return this.negate().prev();
+ };
+ NativeBigInt.prototype.not = SmallInteger.prototype.not = BigInteger.prototype.not;
+
+ BigInteger.prototype.and = function (n) {
+ return bitwise(this, n, function (a, b) { return a & b; });
+ };
+ NativeBigInt.prototype.and = SmallInteger.prototype.and = BigInteger.prototype.and;
+
+ BigInteger.prototype.or = function (n) {
+ return bitwise(this, n, function (a, b) { return a | b; });
+ };
+ NativeBigInt.prototype.or = SmallInteger.prototype.or = BigInteger.prototype.or;
+
+ BigInteger.prototype.xor = function (n) {
+ return bitwise(this, n, function (a, b) { return a ^ b; });
+ };
+ NativeBigInt.prototype.xor = SmallInteger.prototype.xor = BigInteger.prototype.xor;
+
+ var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I;
+ function roughLOB(n) { // get lowestOneBit (rough)
+ // SmallInteger: return Min(lowestOneBit(n), 1 << 30)
+ // BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
+ var v = n.value,
+ x = typeof v === "number" ? v | LOBMASK_I :
+ typeof v === "bigint" ? v | BigInt(LOBMASK_I) :
+ v[0] + v[1] * BASE | LOBMASK_BI;
+ return x & -x;
+ }
+
+ function integerLogarithm(value, base) {
+ if (base.compareTo(value) <= 0) {
+ var tmp = integerLogarithm(value, base.square(base));
+ var p = tmp.p;
+ var e = tmp.e;
+ var t = p.multiply(base);
+ return t.compareTo(value) <= 0 ? { p: t, e: e * 2 + 1 } : { p: p, e: e * 2 };
+ }
+ return { p: bigInt(1), e: 0 };
+ }
+
+ BigInteger.prototype.bitLength = function () {
+ var n = this;
+ if (n.compareTo(bigInt(0)) < 0) {
+ n = n.negate().subtract(bigInt(1));
+ }
+ if (n.compareTo(bigInt(0)) === 0) {
+ return bigInt(0);
+ }
+ return bigInt(integerLogarithm(n, bigInt(2)).e).add(bigInt(1));
+ }
+ NativeBigInt.prototype.bitLength = SmallInteger.prototype.bitLength = BigInteger.prototype.bitLength;
+
+ function max(a, b) {
+ a = parseValue(a);
+ b = parseValue(b);
+ return a.greater(b) ? a : b;
+ }
+ function min(a, b) {
+ a = parseValue(a);
+ b = parseValue(b);
+ return a.lesser(b) ? a : b;
+ }
+ function gcd(a, b) {
+ a = parseValue(a).abs();
+ b = parseValue(b).abs();
+ if (a.equals(b)) return a;
+ if (a.isZero()) return b;
+ if (b.isZero()) return a;
+ var c = Integer[1], d, t;
+ while (a.isEven() && b.isEven()) {
+ d = min(roughLOB(a), roughLOB(b));
+ a = a.divide(d);
+ b = b.divide(d);
+ c = c.multiply(d);
+ }
+ while (a.isEven()) {
+ a = a.divide(roughLOB(a));
+ }
+ do {
+ while (b.isEven()) {
+ b = b.divide(roughLOB(b));
+ }
+ if (a.greater(b)) {
+ t = b; b = a; a = t;
+ }
+ b = b.subtract(a);
+ } while (!b.isZero());
+ return c.isUnit() ? a : a.multiply(c);
+ }
+ function lcm(a, b) {
+ a = parseValue(a).abs();
+ b = parseValue(b).abs();
+ return a.divide(gcd(a, b)).multiply(b);
+ }
+ function randBetween(a, b) {
+ a = parseValue(a);
+ b = parseValue(b);
+ var low = min(a, b), high = max(a, b);
+ var range = high.subtract(low).add(1);
+ if (range.isSmall) return low.add(Math.floor(Math.random() * range));
+ var digits = toBase(range, BASE).value;
+ var result = [], restricted = true;
+ for (var i = 0; i < digits.length; i++) {
+ var top = restricted ? digits[i] : BASE;
+ var digit = truncate(Math.random() * top);
+ result.push(digit);
+ if (digit < top) restricted = false;
+ }
+ return low.add(Integer.fromArray(result, BASE, false));
+ }
+
+ var parseBase = function (text, base, alphabet, caseSensitive) {
+ alphabet = alphabet || DEFAULT_ALPHABET;
+ text = String(text);
+ if (!caseSensitive) {
+ text = text.toLowerCase();
+ alphabet = alphabet.toLowerCase();
+ }
+ var length = text.length;
+ var i;
+ var absBase = Math.abs(base);
+ var alphabetValues = {};
+ for (i = 0; i < alphabet.length; i++) {
+ alphabetValues[alphabet[i]] = i;
+ }
+ for (i = 0; i < length; i++) {
+ var c = text[i];
+ if (c === "-") continue;
+ if (c in alphabetValues) {
+ if (alphabetValues[c] >= absBase) {
+ if (c === "1" && absBase === 1) continue;
+ throw new Error(c + " is not a valid digit in base " + base + ".");
+ }
+ }
+ }
+ base = parseValue(base);
+ var digits = [];
+ var isNegative = text[0] === "-";
+ for (i = isNegative ? 1 : 0; i < text.length; i++) {
+ var c = text[i];
+ if (c in alphabetValues) digits.push(parseValue(alphabetValues[c]));
+ else if (c === "<") {
+ var start = i;
+ do { i++; } while (text[i] !== ">" && i < text.length);
+ digits.push(parseValue(text.slice(start + 1, i)));
+ }
+ else throw new Error(c + " is not a valid character");
+ }
+ return parseBaseFromArray(digits, base, isNegative);
+ };
+
+ function parseBaseFromArray(digits, base, isNegative) {
+ var val = Integer[0], pow = Integer[1], i;
+ for (i = digits.length - 1; i >= 0; i--) {
+ val = val.add(digits[i].times(pow));
+ pow = pow.times(base);
+ }
+ return isNegative ? val.negate() : val;
+ }
+
+ function stringify(digit, alphabet) {
+ alphabet = alphabet || DEFAULT_ALPHABET;
+ if (digit < alphabet.length) {
+ return alphabet[digit];
+ }
+ return "<" + digit + ">";
+ }
+
+ function toBase(n, base) {
+ base = bigInt(base);
+ if (base.isZero()) {
+ if (n.isZero()) return { value: [0], isNegative: false };
+ throw new Error("Cannot convert nonzero numbers to base 0.");
+ }
+ if (base.equals(-1)) {
+ if (n.isZero()) return { value: [0], isNegative: false };
+ if (n.isNegative())
+ return {
+ value: [].concat.apply([], Array.apply(null, Array(-n.toJSNumber()))
+ .map(Array.prototype.valueOf, [1, 0])
+ ),
+ isNegative: false
+ };
+
+ var arr = Array.apply(null, Array(n.toJSNumber() - 1))
+ .map(Array.prototype.valueOf, [0, 1]);
+ arr.unshift([1]);
+ return {
+ value: [].concat.apply([], arr),
+ isNegative: false
+ };
+ }
+
+ var neg = false;
+ if (n.isNegative() && base.isPositive()) {
+ neg = true;
+ n = n.abs();
+ }
+ if (base.isUnit()) {
+ if (n.isZero()) return { value: [0], isNegative: false };
+
+ return {
+ value: Array.apply(null, Array(n.toJSNumber()))
+ .map(Number.prototype.valueOf, 1),
+ isNegative: neg
+ };
+ }
+ var out = [];
+ var left = n, divmod;
+ while (left.isNegative() || left.compareAbs(base) >= 0) {
+ divmod = left.divmod(base);
+ left = divmod.quotient;
+ var digit = divmod.remainder;
+ if (digit.isNegative()) {
+ digit = base.minus(digit).abs();
+ left = left.next();
+ }
+ out.push(digit.toJSNumber());
+ }
+ out.push(left.toJSNumber());
+ return { value: out.reverse(), isNegative: neg };
+ }
+
+ function toBaseString(n, base, alphabet) {
+ var arr = toBase(n, base);
+ return (arr.isNegative ? "-" : "") + arr.value.map(function (x) {
+ return stringify(x, alphabet);
+ }).join('');
+ }
+
+ BigInteger.prototype.toArray = function (radix) {
+ return toBase(this, radix);
+ };
+
+ SmallInteger.prototype.toArray = function (radix) {
+ return toBase(this, radix);
+ };
+
+ NativeBigInt.prototype.toArray = function (radix) {
+ return toBase(this, radix);
+ };
+
+ BigInteger.prototype.toString = function (radix, alphabet) {
+ if (radix === undefined) radix = 10;
+ if (radix !== 10) return toBaseString(this, radix, alphabet);
+ var v = this.value, l = v.length, str = String(v[--l]), zeros = "0000000", digit;
+ while (--l >= 0) {
+ digit = String(v[l]);
+ str += zeros.slice(digit.length) + digit;
+ }
+ var sign = this.sign ? "-" : "";
+ return sign + str;
+ };
+
+ SmallInteger.prototype.toString = function (radix, alphabet) {
+ if (radix === undefined) radix = 10;
+ if (radix != 10) return toBaseString(this, radix, alphabet);
+ return String(this.value);
+ };
+
+ NativeBigInt.prototype.toString = SmallInteger.prototype.toString;
+
+ NativeBigInt.prototype.toJSON = BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function () { return this.toString(); }
+
+ BigInteger.prototype.valueOf = function () {
+ return parseInt(this.toString(), 10);
+ };
+ BigInteger.prototype.toJSNumber = BigInteger.prototype.valueOf;
+
+ SmallInteger.prototype.valueOf = function () {
+ return this.value;
+ };
+ SmallInteger.prototype.toJSNumber = SmallInteger.prototype.valueOf;
+ NativeBigInt.prototype.valueOf = NativeBigInt.prototype.toJSNumber = function () {
+ return parseInt(this.toString(), 10);
+ }
+
+ function parseStringValue(v) {
+ if (isPrecise(+v)) {
+ var x = +v;
+ if (x === truncate(x))
+ return supportsNativeBigInt ? new NativeBigInt(BigInt(x)) : new SmallInteger(x);
+ throw new Error("Invalid integer: " + v);
+ }
+ var sign = v[0] === "-";
+ if (sign) v = v.slice(1);
+ var split = v.split(/e/i);
+ if (split.length > 2) throw new Error("Invalid integer: " + split.join("e"));
+ if (split.length === 2) {
+ var exp = split[1];
+ if (exp[0] === "+") exp = exp.slice(1);
+ exp = +exp;
+ if (exp !== truncate(exp) || !isPrecise(exp)) throw new Error("Invalid integer: " + exp + " is not a valid exponent.");
+ var text = split[0];
+ var decimalPlace = text.indexOf(".");
+ if (decimalPlace >= 0) {
+ exp -= text.length - decimalPlace - 1;
+ text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1);
+ }
+ if (exp < 0) throw new Error("Cannot include negative exponent part for integers");
+ text += (new Array(exp + 1)).join("0");
+ v = text;
+ }
+ var isValid = /^([0-9][0-9]*)$/.test(v);
+ if (!isValid) throw new Error("Invalid integer: " + v);
+ if (supportsNativeBigInt) {
+ return new NativeBigInt(BigInt(sign ? "-" + v : v));
+ }
+ var r = [], max = v.length, l = LOG_BASE, min = max - l;
+ while (max > 0) {
+ r.push(+v.slice(min, max));
+ min -= l;
+ if (min < 0) min = 0;
+ max -= l;
+ }
+ trim(r);
+ return new BigInteger(r, sign);
+ }
+
+ function parseNumberValue(v) {
+ if (supportsNativeBigInt) {
+ return new NativeBigInt(BigInt(v));
+ }
+ if (isPrecise(v)) {
+ if (v !== truncate(v)) throw new Error(v + " is not an integer.");
+ return new SmallInteger(v);
+ }
+ return parseStringValue(v.toString());
+ }
+
+ function parseValue(v) {
+ if (typeof v === "number") {
+ return parseNumberValue(v);
+ }
+ if (typeof v === "string") {
+ return parseStringValue(v);
+ }
+ if (typeof v === "bigint") {
+ return new NativeBigInt(v);
+ }
+ return v;
+ }
+ // Pre-define numbers in range [-999,999]
+ for (var i = 0; i < 1000; i++) {
+ Integer[i] = parseValue(i);
+ if (i > 0) Integer[-i] = parseValue(-i);
+ }
+ // Backwards compatibility
+ Integer.one = Integer[1];
+ Integer.zero = Integer[0];
+ Integer.minusOne = Integer[-1];
+ Integer.max = max;
+ Integer.min = min;
+ Integer.gcd = gcd;
+ Integer.lcm = lcm;
+ Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger || x instanceof NativeBigInt; };
+ Integer.randBetween = randBetween;
+
+ Integer.fromArray = function (digits, base, isNegative) {
+ return parseBaseFromArray(digits.map(parseValue), parseValue(base || 10), isNegative);
+ };
+
+ return Integer;
+})();
+
+// Node.js check
+if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
+ module.exports = bigInt;
+}
+
+//amd check
+if (typeof define === "function" && define.amd) {
+ define("big-integer", [], function () {
+ return bigInt;
+ });
+}
},{}],9:[function(require,module,exports){
(function (Buffer){
@@ -4931,6 +4942,976 @@ process.chdir = function (dir) {
process.umask = function() { return 0; };
},{}],13:[function(require,module,exports){
+(function (Buffer){
+/*
+ Copyright 2018 0kims association.
+
+ This file is part of snarkjs.
+
+ snarkjs is a free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ snarkjs is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ snarkjs. If not, see .
+*/
+
+/* global BigInt */
+const bigInt = require("big-integer");
+
+let wBigInt;
+
+if (typeof(BigInt) != "undefined") {
+ wBigInt = BigInt;
+ wBigInt.one = wBigInt(1);
+ wBigInt.zero = wBigInt(0);
+
+ // Affine
+ wBigInt.genAffine = (q) => {
+ const nq = -q;
+ return (a) => {
+ let aux = a;
+ if (aux < 0) {
+ if (aux <= nq) {
+ aux = aux % q;
+ }
+ if (aux < wBigInt.zero) {
+ aux = aux + q;
+ }
+ } else {
+ if (aux >= q) {
+ aux = aux % q;
+ }
+ }
+ return aux.valueOf();
+ };
+ };
+
+
+ // Inverse
+ wBigInt.genInverse = (q) => {
+ return (a) => {
+ let t = wBigInt.zero;
+ let r = q;
+ let newt = wBigInt.one;
+ let newr = wBigInt.affine(a, q);
+ while (newr!=wBigInt.zero) {
+ let q = r/newr;
+ [t, newt] = [newt, t-q*newt];
+ [r, newr] = [newr, r-q*newr];
+ }
+ if (t {
+ if (q) {
+ return (a,b) => (a+b) % q;
+ } else {
+ return (a,b) => a+b;
+ }
+ };
+
+ // Sub
+ wBigInt.genSub = (q) => {
+ if (q) {
+ return (a,b) => (a-b) % q;
+ } else {
+ return (a,b) => a-b;
+ }
+ };
+
+
+ // Neg
+ wBigInt.genNeg = (q) => {
+ if (q) {
+ return (a) => (-a) % q;
+ } else {
+ return (a) => -a;
+ }
+ };
+
+ // Mul
+ wBigInt.genMul = (q) => {
+ if (q) {
+ return (a,b) => (a*b) % q;
+ } else {
+ return (a,b) => a*b;
+ }
+ };
+
+ // Shr
+ wBigInt.genShr = () => {
+ return (a,b) => a >> wBigInt(b);
+ };
+
+ // Shl
+ wBigInt.genShl = (q) => {
+ if (q) {
+ return (a,b) => (a << wBigInt(b)) % q;
+ } else {
+ return (a,b) => a << wBigInt(b);
+ }
+ };
+
+ // Equals
+ wBigInt.genEquals = (q) => {
+ if (q) {
+ return (a,b) => (a.affine(q) == b.affine(q));
+ } else {
+ return (a,b) => a == b;
+ }
+ };
+
+ // Square
+ wBigInt.genSquare = (q) => {
+ if (q) {
+ return (a) => (a*a) %q;
+ } else {
+ return (a) => a*a;
+ }
+ };
+
+
+ // Double
+ wBigInt.genDouble = (q) => {
+ if (q) {
+ return (a) => (a+a) %q;
+ } else {
+ return (a) => a+a;
+ }
+ };
+
+ // IsZero
+ wBigInt.genIsZero = (q) => {
+ if (q) {
+ return (a) => (a.affine(q) == wBigInt.zero);
+ } else {
+ return (a) => a == wBigInt.zero;
+ }
+ };
+
+
+ // Other minor functions
+ wBigInt.prototype.isOdd = function() {
+ return (this & wBigInt.one) == wBigInt(1);
+ };
+
+ wBigInt.prototype.isNegative = function() {
+ return this < wBigInt.zero;
+ };
+
+ wBigInt.prototype.and = function(m) {
+ return this & m;
+ };
+
+ wBigInt.prototype.div = function(c) {
+ return this / c;
+ };
+
+ wBigInt.prototype.mod = function(c) {
+ return this % c;
+ };
+
+ wBigInt.prototype.modPow = function(e, m) {
+ let acc = wBigInt.one;
+ let exp = this;
+ let rem = e;
+ while (rem) {
+ if (rem & wBigInt.one) {
+ acc = (acc * exp) %m;
+ }
+ exp = (exp * exp) % m;
+ rem = rem >> wBigInt.one;
+ }
+ return acc;
+ };
+
+ wBigInt.prototype.greaterOrEquals = function(b) {
+ return this >= b;
+ };
+
+ wBigInt.prototype.greater = function(b) {
+ return this > b;
+ };
+ wBigInt.prototype.gt = wBigInt.prototype.greater;
+
+ wBigInt.prototype.lesserOrEquals = function(b) {
+ return this <= b;
+ };
+
+ wBigInt.prototype.lesser = function(b) {
+ return this < b;
+ };
+ wBigInt.prototype.lt = wBigInt.prototype.lesser;
+
+ wBigInt.prototype.equals = function(b) {
+ return this == b;
+ };
+ wBigInt.prototype.eq = wBigInt.prototype.equals;
+
+ wBigInt.prototype.neq = function(b) {
+ return this != b;
+ };
+
+} else {
+
+ var oldProto = bigInt.prototype;
+ wBigInt = function(a) {
+ if ((typeof a == "string") && (a.slice(0,2) == "0x")) {
+ return bigInt(a.slice(2), 16);
+ } else {
+ return bigInt(a);
+ }
+ };
+ wBigInt.one = bigInt.one;
+ wBigInt.zero = bigInt.zero;
+ wBigInt.prototype = oldProto;
+
+ wBigInt.prototype.div = function(c) {
+ return this.divide(c);
+ };
+
+ // Affine
+ wBigInt.genAffine = (q) => {
+ const nq = wBigInt.zero.minus(q);
+ return (a) => {
+ let aux = a;
+ if (aux.isNegative()) {
+ if (aux.lesserOrEquals(nq)) {
+ aux = aux.mod(q);
+ }
+ if (aux.isNegative()) {
+ aux = aux.add(q);
+ }
+ } else {
+ if (aux.greaterOrEquals(q)) {
+ aux = aux.mod(q);
+ }
+ }
+ return aux;
+ };
+ };
+
+
+ // Inverse
+ wBigInt.genInverse = (q) => {
+ return (a) => a.affine(q).modInv(q);
+ };
+
+ // Add
+ wBigInt.genAdd = (q) => {
+ if (q) {
+ return (a,b) => {
+ const r = a.add(b);
+ return r.greaterOrEquals(q) ? r.minus(q) : r;
+ };
+ } else {
+ return (a,b) => a.add(b);
+ }
+ };
+
+ // Sub
+ wBigInt.genSub = (q) => {
+ if (q) {
+ return (a,b) => a.greaterOrEquals(b) ? a.minus(b) : a.minus(b).add(q);
+ } else {
+ return (a,b) => a.minus(b);
+ }
+ };
+
+ wBigInt.genNeg = (q) => {
+ if (q) {
+ return (a) => a.isZero() ? a : q.minus(a);
+ } else {
+ return (a) => wBigInt.zero.minus(a);
+ }
+ };
+
+ // Mul
+ wBigInt.genMul = (q) => {
+ if (q) {
+ return (a,b) => a.times(b).mod(q);
+ } else {
+ return (a,b) => a.times(b);
+ }
+ };
+
+ // Shr
+ wBigInt.genShr = () => {
+ return (a,b) => a.shiftRight(wBigInt(b).value);
+ };
+
+ // Shr
+ wBigInt.genShl = (q) => {
+ if (q) {
+ return (a,b) => a.shiftLeft(wBigInt(b).value).mod(q);
+ } else {
+ return (a,b) => a.shiftLeft(wBigInt(b).value);
+ }
+ };
+
+ // Square
+ wBigInt.genSquare = (q) => {
+ if (q) {
+ return (a) => a.square().mod(q);
+ } else {
+ return (a) => a.square();
+ }
+ };
+
+ // Double
+ wBigInt.genDouble = (q) => {
+ if (q) {
+ return (a) => a.add(a).mod(q);
+ } else {
+ return (a) => a.add(a);
+ }
+ };
+
+ // Equals
+ wBigInt.genEquals = (q) => {
+ if (q) {
+ return (a,b) => a.affine(q).equals(b.affine(q));
+ } else {
+ return (a,b) => a.equals(b);
+ }
+ };
+
+ // IsZero
+ wBigInt.genIsZero = (q) => {
+ if (q) {
+ return (a) => (a.affine(q).isZero());
+ } else {
+ return (a) => a.isZero();
+ }
+ };
+}
+
+
+
+wBigInt.affine = function(a, q) {
+ return wBigInt.genAffine(q)(a);
+};
+
+wBigInt.prototype.affine = function (q) {
+ return wBigInt.affine(this, q);
+};
+
+wBigInt.inverse = function(a, q) {
+ return wBigInt.genInverse(q)(a);
+};
+
+wBigInt.prototype.inverse = function (q) {
+ return wBigInt.genInverse(q)(this);
+};
+
+wBigInt.add = function(a, b, q) {
+ return wBigInt.genAdd(q)(a,b);
+};
+
+wBigInt.prototype.add = function (a, q) {
+ return wBigInt.genAdd(q)(this, a);
+};
+
+wBigInt.sub = function(a, b, q) {
+ return wBigInt.genSub(q)(a,b);
+};
+
+wBigInt.prototype.sub = function (a, q) {
+ return wBigInt.genSub(q)(this, a);
+};
+
+wBigInt.neg = function(a, q) {
+ return wBigInt.genNeg(q)(a);
+};
+
+wBigInt.prototype.neg = function (q) {
+ return wBigInt.genNeg(q)(this);
+};
+
+wBigInt.mul = function(a, b, q) {
+ return wBigInt.genMul(q)(a,b);
+};
+
+wBigInt.prototype.mul = function (a, q) {
+ return wBigInt.genMul(q)(this, a);
+};
+
+wBigInt.shr = function(a, b, q) {
+ return wBigInt.genShr(q)(a,b);
+};
+
+wBigInt.prototype.shr = function (a, q) {
+ return wBigInt.genShr(q)(this, a);
+};
+
+wBigInt.shl = function(a, b, q) {
+ return wBigInt.genShl(q)(a,b);
+};
+
+wBigInt.prototype.shl = function (a, q) {
+ return wBigInt.genShl(q)(this, a);
+};
+
+wBigInt.equals = function(a, b, q) {
+ return wBigInt.genEquals(q)(a,b);
+};
+
+wBigInt.prototype.equals = function (a, q) {
+ return wBigInt.genEquals(q)(this, a);
+};
+
+wBigInt.square = function(a, q) {
+ return wBigInt.genSquare(q)(a);
+};
+
+wBigInt.prototype.square = function (q) {
+ return wBigInt.genSquare(q)(this);
+};
+
+wBigInt.double = function(a, q) {
+ return wBigInt.genDouble(q)(a);
+};
+
+wBigInt.prototype.double = function (q) {
+ return wBigInt.genDouble(q)(this);
+};
+
+wBigInt.isZero = function(a, q) {
+ return wBigInt.genIsZero(q)(a);
+};
+
+wBigInt.prototype.isZero = function (q) {
+ return wBigInt.genIsZero(q)(this);
+};
+
+wBigInt.leBuff2int = function(buff) {
+ let res = wBigInt.zero;
+ for (let i=0; i.
+*/
+
+const bigInt = require("./bigint");
+
+module.exports = calculateWitness;
+
+function calculateWitness(circuit, inputSignals, log) {
+ log = log || (() => {});
+ const ctx = new RTCtx(circuit, log);
+
+ function iterateSelector(values, sels, cb) {
+ if (!Array.isArray(values)) {
+ return cb(sels, values);
+ }
+ for (let i=0; i " + ctx.witness[i].toString());
+ }
+ return ctx.witness.slice(0, circuit.nVars);
+// return ctx.witness;
+}
+
+class RTCtx {
+ constructor(circuit, log) {
+ this.log = log || function() {};
+ this.scopes = [];
+ this.circuit = circuit;
+ this.witness = new Array(circuit.nSignals);
+ this.notInitSignals = {};
+ for (let c in this.circuit.components) {
+ this.notInitSignals[c] = this.circuit.components[c].inputSignals;
+ }
+ }
+
+ _sels2str(sels) {
+ let res = "";
+ for (let i=0; i {
+ if (this.notInitSignals[c] == 0) this.triggerComponent(c);
+ });
+ return this.witness[sId];
+ }
+
+ setVar(name, sels, value) {
+ function setVarArray(a, sels2, value) {
+ if (sels2.length == 1) {
+ a[sels2[0]] = value;
+ } else {
+ if (typeof(a[sels2[0]]) == "undefined") a[sels2[0]] = [];
+ setVarArray(a[sels2[0]], sels2.slice(1), value);
+ }
+ }
+ const scope = this.scopes[this.scopes.length-1];
+ if (sels.length == 0) {
+ scope[name] = value;
+ } else {
+ if (typeof(scope[name]) == "undefined") scope[name] = [];
+ setVarArray(scope[name], sels, value);
+ }
+ return value;
+ }
+
+ getVar(name, sels) {
+ function select(a, sels2) {
+ return (sels2.length == 0) ? a : select(a[sels2[0]], sels2.slice(1));
+ }
+ for (let i=this.scopes.length-1; i>=0; i--) {
+ if (typeof(this.scopes[i][name]) != "undefined") return select(this.scopes[i][name], sels);
+ }
+ throw new Error("Variable not defined: " + name);
+ }
+
+ getSignal(name, sels) {
+ let fullName = name=="one" ? "one" : this.currentComponent + "." + name;
+ fullName += this._sels2str(sels);
+ return this.getSignalFullName(fullName);
+ }
+
+
+ getPin(componentName, componentSels, signalName, signalSels) {
+ let fullName = componentName=="one" ? "one" : this.currentComponent + "." + componentName;
+ fullName += this._sels2str(componentSels) +
+ "."+
+ signalName+
+ this._sels2str(signalSels);
+ return this.getSignalFullName(fullName);
+ }
+
+ getSignalFullName(fullName) {
+ const sId = this.circuit.getSignalIdx(fullName);
+ if (typeof(this.witness[sId]) == "undefined") {
+ throw new Error("Signal not initialized: "+fullName);
+ }
+ this.log("get --->" + fullName + " = " + this.witness[sId].toString() );
+ return this.witness[sId];
+ }
+
+ assert(a,b) {
+ const ba = bigInt(a);
+ const bb = bigInt(b);
+ if (!ba.equals(bb)) {
+ throw new Error("Constraint doesn't match: " + ba.toString() + " != " + bb.toString());
+ }
+ }
+}
+
+},{"./bigint":13}],15:[function(require,module,exports){
+/*
+ Copyright 2018 0kims association.
+
+ This file is part of snarkjs.
+
+ snarkjs is a free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ snarkjs is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ snarkjs. If not, see .
+*/
+
+const bigInt = require("./bigint.js");
+
+const __P__ = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
+const __MASK__ = bigInt("28948022309329048855892746252171976963317496166410141009864396001978282409983"); // 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+const calculateWitness = require("./calculateWitness.js");
+
+module.exports = class Circuit {
+ constructor(circuitDef) {
+ this.nPubInputs = circuitDef.nPubInputs;
+ this.nPrvInputs = circuitDef.nPrvInputs;
+ this.nInputs = circuitDef.nInputs;
+ this.nOutputs = circuitDef.nOutputs;
+ this.nVars = circuitDef.nVars;
+ this.nSignals = circuitDef.nSignals;
+ this.nConstants = circuitDef.nConstants;
+
+ this.nConstraints = circuitDef.constraints.length;
+
+ this.signalName2Idx = circuitDef.signalName2Idx;
+ this.components = circuitDef.components;
+ this.componentName2Idx = circuitDef.componentName2Idx;
+ this.signals = circuitDef.signals;
+ this.constraints = circuitDef.constraints;
+
+ this.templates = {};
+ for (let t in circuitDef.templates) {
+ this.templates[t] = eval(" const __f= " +circuitDef.templates[t] + "\n__f");
+ }
+
+ this.functions = {};
+ for (let f in circuitDef.functions) {
+ this.functions[f] = {
+ params: circuitDef.functions[f].params,
+ func: eval(" const __f= " +circuitDef.functions[f].func + "\n__f;")
+ };
+ }
+ }
+
+ calculateWitness(input, log) {
+ return calculateWitness(this, input, log);
+ }
+
+ checkWitness(w) {
+ const evalLC = (lc, w) => {
+ let acc = bigInt(0);
+ for (let k in lc) {
+ acc= acc.add(bigInt(w[k]).mul(bigInt(lc[k]))).mod(__P__);
+ }
+ return acc;
+ }
+
+ const checkConstraint = (ct, w) => {
+ const a=evalLC(ct[0],w);
+ const b=evalLC(ct[1],w);
+ const c=evalLC(ct[2],w);
+ const res = (a.mul(b).sub(c)).affine(__P__);
+ if (!res.isZero()) return false;
+ return true;
+ }
+
+
+ for (let i=0; i {
+ let S = "";
+ for (let k in lc) {
+ let name = this.signals[k].names[0];
+ if (name == "one") name = "";
+ let v = bigInt(lc[k]);
+ let vs;
+ if (!v.lesserOrEquals(__P__.shr(bigInt(1)))) {
+ v = __P__.sub(v);
+ vs = "-"+v.toString();
+ } else {
+ if (S!="") {
+ vs = "+"+v.toString();
+ } else {
+ vs = "";
+ }
+ if (vs!="1") {
+ vs = vs + v.toString();;
+ }
+ }
+
+ S= S + " " + vs + name;
+ }
+ return S;
+ };
+ const S = `[ ${lc2str(c[0])} ] * [ ${lc2str(c[1])} ] - [ ${lc2str(c[2])} ] = 0`;
+ console.log(S);
+ }
+
+ printConstraints() {
+ for (let i=0; i=this.nOutputs) throw new Error("Accessing an invalid output: "+i);
+ return i+1;
+ }
+
+ // returns the index of the i'th input
+ inputIdx(i) {
+ if (i>=this.nInputs) throw new Error("Accessing an invalid input: "+i);
+ return this.nOutputs + 1 + i;
+ }
+
+ // returns the index of the i'th public input
+ pubInputIdx(i) {
+ if (i>=this.nPubInputs) throw new Error("Accessing an invalid pubInput: "+i);
+ return this.inputIdx(i);
+ }
+
+ // returns the index of the i'th private input
+ prvInputIdx(i) {
+ if (i>=this.nPrvInputs) throw new Error("Accessing an invalid prvInput: "+i);
+ return this.inputIdx(this.nPubInputs + i);
+ }
+
+ // returns the index of the i'th variable
+ varIdx(i) {
+ if (i>=this.nVars) throw new Error("Accessing an invalid variable: "+i);
+ return i;
+ }
+
+ // returns the index of the i'th constant
+ constantIdx(i) {
+ if (i>=this.nConstants) throw new Error("Accessing an invalid constant: "+i);
+ return this.nVars + i;
+ }
+
+ // returns the index of the i'th signal
+ signalIdx(i) {
+ if (i>=this.nSignls) throw new Error("Accessing an invalid signal: "+i);
+ return i;
+ }
+
+ signalNames(i) {
+ return this.signals[ this.getSignalIdx(i) ].names.join(", ");
+ }
+
+ a(constraint, signalIdx) {
+ return bigInt(this.constraints[constraint][0][signalIdx] || 0 );
+ }
+
+ b(constraint, signalIdx) {
+ return bigInt(this.constraints[constraint][1][signalIdx] || 0);
+ }
+
+ c(constraint, signalIdx) {
+ return bigInt(this.constraints[constraint][2][signalIdx] || 0);
+ }
+};
+
+},{"./bigint.js":13,"./calculateWitness.js":14}],16:[function(require,module,exports){
+/*
+ Copyright 2018 0kims association.
+
+ This file is part of snarkjs.
+
+ snarkjs is a free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ snarkjs is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ snarkjs. If not, see .
+*/
+
+const bigInt = require("./bigint.js");
+
+module.exports.stringifyBigInts = stringifyBigInts;
+module.exports.unstringifyBigInts = unstringifyBigInts;
+
+function stringifyBigInts(o) {
+ if ((typeof(o) == "bigint") || (o instanceof bigInt)) {
+ return o.toString(10);
+ } else if (Array.isArray(o)) {
+ return o.map(stringifyBigInts);
+ } else if (typeof o == "object") {
+ const res = {};
+ for (let k in o) {
+ res[k] = stringifyBigInts(o[k]);
+ }
+ return res;
+ } else {
+ return o;
+ }
+}
+
+function unstringifyBigInts(o) {
+ if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
+ return bigInt(o);
+ } else if (Array.isArray(o)) {
+ return o.map(unstringifyBigInts);
+ } else if (typeof o == "object") {
+ const res = {};
+ for (let k in o) {
+ res[k] = unstringifyBigInts(o[k]);
+ }
+ return res;
+ } else {
+ return o;
+ }
+}
+
+},{"./bigint.js":13}],17:[function(require,module,exports){
(function (process){
/*
Copyright 2019 0KIMS association.
@@ -5542,4 +6523,175 @@ class Groth16 {
module.exports = build;
}).call(this,require('_process'))
-},{"../build/groth16_wasm.js":1,"_process":12,"assert":3,"big-integer":8,"crypto":undefined,"worker_threads":undefined}]},{},[2]);
+},{"../build/groth16_wasm.js":1,"_process":12,"assert":3,"big-integer":8,"crypto":undefined,"worker_threads":undefined}],18:[function(require,module,exports){
+/*
+ Copyright 2019 0KIMS association.
+
+ This file is part of websnark (Web Assembly zkSnark Prover).
+
+ websnark is a free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ websnark is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with websnark. If not, see .
+*/
+
+const bigInt = require("big-integer");
+const Circuit = require("snarkjs/src/circuit");
+const bigInt2 = require("snarkjs/src/bigint");
+const hexifyBigInts = require("../tools/stringifybigint").hexifyBigInts;
+const unstringifyBigInts = require("../tools/stringifybigint").unstringifyBigInts;
+const stringifyBigInts2 = require("snarkjs/src/stringifybigint").stringifyBigInts;
+const unstringifyBigInts2 = require("snarkjs/src/stringifybigint").unstringifyBigInts;
+
+function bigInt2BytesLE(_a, len) {
+ const b = Array(len);
+ let v = bigInt(_a);
+ for (let i=0; i.
+*/
+
+const bigInt = require("big-integer");
+
+module.exports.stringifyBigInts = stringifyBigInts;
+module.exports.unstringifyBigInts = unstringifyBigInts;
+module.exports.hexifyBigInts = hexifyBigInts;
+
+function stringifyBigInts(o) {
+ if ((typeof(o) == "bigint") || (o instanceof bigInt)) {
+ return o.toString(10);
+ } else if (Array.isArray(o)) {
+ return o.map(stringifyBigInts);
+ } else if (typeof o == "object") {
+ const res = {};
+ for (let k in o) {
+ res[k] = stringifyBigInts(o[k]);
+ }
+ return res;
+ } else {
+ return o;
+ }
+}
+
+function unstringifyBigInts(o) {
+ if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
+ return bigInt(o);
+ } else if (Array.isArray(o)) {
+ return o.map(unstringifyBigInts);
+ } else if (typeof o == "object" && !(o instanceof bigInt)) {
+ const res = {};
+ for (let k in o) {
+ res[k] = unstringifyBigInts(o[k]);
+ }
+ return res;
+ } else {
+ return o;
+ }
+}
+
+function hexifyBigInts(o) {
+ if (typeof (o) === "bigInt" || (o instanceof bigInt)) {
+ let str = o.toString(16);
+ while (str.length < 64) str = "0" + str;
+ str = "0x" + str;
+ return str;
+ } else if (Array.isArray(o)) {
+ return o.map(hexifyBigInts);
+ } else if (typeof o == "object") {
+ const res = {};
+ for (let k in o) {
+ res[k] = hexifyBigInts(o[k]);
+ }
+ return res;
+ } else {
+ return o;
+ }
+}
+
+},{"big-integer":8}]},{},[2]);
diff --git a/example/websnark.js b/example/websnark.js
index 4cbfd61..48fab7f 100644
--- a/example/websnark.js
+++ b/example/websnark.js
@@ -28,16 +28,30 @@
/* globals window */
-const buildGroth16 = require("./src/groth16.js");
+const buildGroth16 = require("./src/groth16");
+const utils = require("./src/utils");
-buildGroth16().then( (groth16) => {
+buildGroth16().then((groth16) => {
window.groth16 = groth16;
- window.genZKSnarkProof = function(witness, provingKey, cb) {
-
- const p = groth16.proof(witness, provingKey);
+ window.zkSnarkProofToSolidityInput = utils.toSolidityInput;
+ window.genZKSnarkProofAndWitness = function (input, circuitJson, provingKey, cb) {
+ const p = utils.genWitnessAndProve(groth16, input, circuitJson, provingKey);
if (cb) {
- p.then( (proof) => {
+ p.then((proof) => {
+ cb(null, proof);
+ }, (err) => {
+ cb(err);
+ });
+ } else {
+ return p;
+ }
+ };
+
+ window.genZKSnarkProof = function (witness, provingKey, cb) {
+ const p = groth16.proof(witness, provingKey);
+ if (cb) {
+ p.then((proof) => {
cb(null, proof);
}, (err) => {
cb(err);
@@ -47,10 +61,7 @@ buildGroth16().then( (groth16) => {
}
};
});
-
-
-
-},{"./src/groth16.js":13}],3:[function(require,module,exports){
+},{"./src/groth16":17,"./src/utils":18}],3:[function(require,module,exports){
(function (global){
'use strict';
@@ -1336,1454 +1347,1454 @@ function fromByteArray (uint8) {
}
},{}],8:[function(require,module,exports){
-var bigInt = (function (undefined) {
- "use strict";
-
- var BASE = 1e7,
- LOG_BASE = 7,
- MAX_INT = 9007199254740992,
- MAX_INT_ARR = smallToArray(MAX_INT),
- DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
-
- var supportsNativeBigInt = typeof BigInt === "function";
-
- function Integer(v, radix, alphabet, caseSensitive) {
- if (typeof v === "undefined") return Integer[0];
- if (typeof radix !== "undefined") return +radix === 10 && !alphabet ? parseValue(v) : parseBase(v, radix, alphabet, caseSensitive);
- return parseValue(v);
- }
-
- function BigInteger(value, sign) {
- this.value = value;
- this.sign = sign;
- this.isSmall = false;
- }
- BigInteger.prototype = Object.create(Integer.prototype);
-
- function SmallInteger(value) {
- this.value = value;
- this.sign = value < 0;
- this.isSmall = true;
- }
- SmallInteger.prototype = Object.create(Integer.prototype);
-
- function NativeBigInt(value) {
- this.value = value;
- }
- NativeBigInt.prototype = Object.create(Integer.prototype);
-
- function isPrecise(n) {
- return -MAX_INT < n && n < MAX_INT;
- }
-
- function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
- if (n < 1e7)
- return [n];
- if (n < 1e14)
- return [n % 1e7, Math.floor(n / 1e7)];
- return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)];
- }
-
- function arrayToSmall(arr) { // If BASE changes this function may need to change
- trim(arr);
- var length = arr.length;
- if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) {
- switch (length) {
- case 0: return 0;
- case 1: return arr[0];
- case 2: return arr[0] + arr[1] * BASE;
- default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE;
- }
- }
- return arr;
- }
-
- function trim(v) {
- var i = v.length;
- while (v[--i] === 0);
- v.length = i + 1;
- }
-
- function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
- var x = new Array(length);
- var i = -1;
- while (++i < length) {
- x[i] = 0;
- }
- return x;
- }
-
- function truncate(n) {
- if (n > 0) return Math.floor(n);
- return Math.ceil(n);
- }
-
- function add(a, b) { // assumes a and b are arrays with a.length >= b.length
- var l_a = a.length,
- l_b = b.length,
- r = new Array(l_a),
- carry = 0,
- base = BASE,
- sum, i;
- for (i = 0; i < l_b; i++) {
- sum = a[i] + b[i] + carry;
- carry = sum >= base ? 1 : 0;
- r[i] = sum - carry * base;
- }
- while (i < l_a) {
- sum = a[i] + carry;
- carry = sum === base ? 1 : 0;
- r[i++] = sum - carry * base;
- }
- if (carry > 0) r.push(carry);
- return r;
- }
-
- function addAny(a, b) {
- if (a.length >= b.length) return add(a, b);
- return add(b, a);
- }
-
- function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
- var l = a.length,
- r = new Array(l),
- base = BASE,
- sum, i;
- for (i = 0; i < l; i++) {
- sum = a[i] - base + carry;
- carry = Math.floor(sum / base);
- r[i] = sum - carry * base;
- carry += 1;
- }
- while (carry > 0) {
- r[i++] = carry % base;
- carry = Math.floor(carry / base);
- }
- return r;
- }
-
- BigInteger.prototype.add = function (v) {
- var n = parseValue(v);
- if (this.sign !== n.sign) {
- return this.subtract(n.negate());
- }
- var a = this.value, b = n.value;
- if (n.isSmall) {
- return new BigInteger(addSmall(a, Math.abs(b)), this.sign);
- }
- return new BigInteger(addAny(a, b), this.sign);
- };
- BigInteger.prototype.plus = BigInteger.prototype.add;
-
- SmallInteger.prototype.add = function (v) {
- var n = parseValue(v);
- var a = this.value;
- if (a < 0 !== n.sign) {
- return this.subtract(n.negate());
- }
- var b = n.value;
- if (n.isSmall) {
- if (isPrecise(a + b)) return new SmallInteger(a + b);
- b = smallToArray(Math.abs(b));
- }
- return new BigInteger(addSmall(b, Math.abs(a)), a < 0);
- };
- SmallInteger.prototype.plus = SmallInteger.prototype.add;
-
- NativeBigInt.prototype.add = function (v) {
- return new NativeBigInt(this.value + parseValue(v).value);
- }
- NativeBigInt.prototype.plus = NativeBigInt.prototype.add;
-
- function subtract(a, b) { // assumes a and b are arrays with a >= b
- var a_l = a.length,
- b_l = b.length,
- r = new Array(a_l),
- borrow = 0,
- base = BASE,
- i, difference;
- for (i = 0; i < b_l; i++) {
- difference = a[i] - borrow - b[i];
- if (difference < 0) {
- difference += base;
- borrow = 1;
- } else borrow = 0;
- r[i] = difference;
- }
- for (i = b_l; i < a_l; i++) {
- difference = a[i] - borrow;
- if (difference < 0) difference += base;
- else {
- r[i++] = difference;
- break;
- }
- r[i] = difference;
- }
- for (; i < a_l; i++) {
- r[i] = a[i];
- }
- trim(r);
- return r;
- }
-
- function subtractAny(a, b, sign) {
- var value;
- if (compareAbs(a, b) >= 0) {
- value = subtract(a, b);
- } else {
- value = subtract(b, a);
- sign = !sign;
- }
- value = arrayToSmall(value);
- if (typeof value === "number") {
- if (sign) value = -value;
- return new SmallInteger(value);
- }
- return new BigInteger(value, sign);
- }
-
- function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
- var l = a.length,
- r = new Array(l),
- carry = -b,
- base = BASE,
- i, difference;
- for (i = 0; i < l; i++) {
- difference = a[i] + carry;
- carry = Math.floor(difference / base);
- difference %= base;
- r[i] = difference < 0 ? difference + base : difference;
- }
- r = arrayToSmall(r);
- if (typeof r === "number") {
- if (sign) r = -r;
- return new SmallInteger(r);
- } return new BigInteger(r, sign);
- }
-
- BigInteger.prototype.subtract = function (v) {
- var n = parseValue(v);
- if (this.sign !== n.sign) {
- return this.add(n.negate());
- }
- var a = this.value, b = n.value;
- if (n.isSmall)
- return subtractSmall(a, Math.abs(b), this.sign);
- return subtractAny(a, b, this.sign);
- };
- BigInteger.prototype.minus = BigInteger.prototype.subtract;
-
- SmallInteger.prototype.subtract = function (v) {
- var n = parseValue(v);
- var a = this.value;
- if (a < 0 !== n.sign) {
- return this.add(n.negate());
- }
- var b = n.value;
- if (n.isSmall) {
- return new SmallInteger(a - b);
- }
- return subtractSmall(b, Math.abs(a), a >= 0);
- };
- SmallInteger.prototype.minus = SmallInteger.prototype.subtract;
-
- NativeBigInt.prototype.subtract = function (v) {
- return new NativeBigInt(this.value - parseValue(v).value);
- }
- NativeBigInt.prototype.minus = NativeBigInt.prototype.subtract;
-
- BigInteger.prototype.negate = function () {
- return new BigInteger(this.value, !this.sign);
- };
- SmallInteger.prototype.negate = function () {
- var sign = this.sign;
- var small = new SmallInteger(-this.value);
- small.sign = !sign;
- return small;
- };
- NativeBigInt.prototype.negate = function () {
- return new NativeBigInt(-this.value);
- }
-
- BigInteger.prototype.abs = function () {
- return new BigInteger(this.value, false);
- };
- SmallInteger.prototype.abs = function () {
- return new SmallInteger(Math.abs(this.value));
- };
- NativeBigInt.prototype.abs = function () {
- return new NativeBigInt(this.value >= 0 ? this.value : -this.value);
- }
-
-
- function multiplyLong(a, b) {
- var a_l = a.length,
- b_l = b.length,
- l = a_l + b_l,
- r = createArray(l),
- base = BASE,
- product, carry, i, a_i, b_j;
- for (i = 0; i < a_l; ++i) {
- a_i = a[i];
- for (var j = 0; j < b_l; ++j) {
- b_j = b[j];
- product = a_i * b_j + r[i + j];
- carry = Math.floor(product / base);
- r[i + j] = product - carry * base;
- r[i + j + 1] += carry;
- }
- }
- trim(r);
- return r;
- }
-
- function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
- var l = a.length,
- r = new Array(l),
- base = BASE,
- carry = 0,
- product, i;
- for (i = 0; i < l; i++) {
- product = a[i] * b + carry;
- carry = Math.floor(product / base);
- r[i] = product - carry * base;
- }
- while (carry > 0) {
- r[i++] = carry % base;
- carry = Math.floor(carry / base);
- }
- return r;
- }
-
- function shiftLeft(x, n) {
- var r = [];
- while (n-- > 0) r.push(0);
- return r.concat(x);
- }
-
- function multiplyKaratsuba(x, y) {
- var n = Math.max(x.length, y.length);
-
- if (n <= 30) return multiplyLong(x, y);
- n = Math.ceil(n / 2);
-
- var b = x.slice(n),
- a = x.slice(0, n),
- d = y.slice(n),
- c = y.slice(0, n);
-
- var ac = multiplyKaratsuba(a, c),
- bd = multiplyKaratsuba(b, d),
- abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d));
-
- var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n));
- trim(product);
- return product;
- }
-
- // The following function is derived from a surface fit of a graph plotting the performance difference
- // between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
- function useKaratsuba(l1, l2) {
- return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0;
- }
-
- BigInteger.prototype.multiply = function (v) {
- var n = parseValue(v),
- a = this.value, b = n.value,
- sign = this.sign !== n.sign,
- abs;
- if (n.isSmall) {
- if (b === 0) return Integer[0];
- if (b === 1) return this;
- if (b === -1) return this.negate();
- abs = Math.abs(b);
- if (abs < BASE) {
- return new BigInteger(multiplySmall(a, abs), sign);
- }
- b = smallToArray(abs);
- }
- if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
- return new BigInteger(multiplyKaratsuba(a, b), sign);
- return new BigInteger(multiplyLong(a, b), sign);
- };
-
- BigInteger.prototype.times = BigInteger.prototype.multiply;
-
- function multiplySmallAndArray(a, b, sign) { // a >= 0
- if (a < BASE) {
- return new BigInteger(multiplySmall(b, a), sign);
- }
- return new BigInteger(multiplyLong(b, smallToArray(a)), sign);
- }
- SmallInteger.prototype._multiplyBySmall = function (a) {
- if (isPrecise(a.value * this.value)) {
- return new SmallInteger(a.value * this.value);
- }
- return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign);
- };
- BigInteger.prototype._multiplyBySmall = function (a) {
- if (a.value === 0) return Integer[0];
- if (a.value === 1) return this;
- if (a.value === -1) return this.negate();
- return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign);
- };
- SmallInteger.prototype.multiply = function (v) {
- return parseValue(v)._multiplyBySmall(this);
- };
- SmallInteger.prototype.times = SmallInteger.prototype.multiply;
-
- NativeBigInt.prototype.multiply = function (v) {
- return new NativeBigInt(this.value * parseValue(v).value);
- }
- NativeBigInt.prototype.times = NativeBigInt.prototype.multiply;
-
- function square(a) {
- //console.assert(2 * BASE * BASE < MAX_INT);
- var l = a.length,
- r = createArray(l + l),
- base = BASE,
- product, carry, i, a_i, a_j;
- for (i = 0; i < l; i++) {
- a_i = a[i];
- carry = 0 - a_i * a_i;
- for (var j = i; j < l; j++) {
- a_j = a[j];
- product = 2 * (a_i * a_j) + r[i + j] + carry;
- carry = Math.floor(product / base);
- r[i + j] = product - carry * base;
- }
- r[i + l] = carry;
- }
- trim(r);
- return r;
- }
-
- BigInteger.prototype.square = function () {
- return new BigInteger(square(this.value), false);
- };
-
- SmallInteger.prototype.square = function () {
- var value = this.value * this.value;
- if (isPrecise(value)) return new SmallInteger(value);
- return new BigInteger(square(smallToArray(Math.abs(this.value))), false);
- };
-
- NativeBigInt.prototype.square = function (v) {
- return new NativeBigInt(this.value * this.value);
- }
-
- function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
- var a_l = a.length,
- b_l = b.length,
- base = BASE,
- result = createArray(b.length),
- divisorMostSignificantDigit = b[b_l - 1],
- // normalization
- lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)),
- remainder = multiplySmall(a, lambda),
- divisor = multiplySmall(b, lambda),
- quotientDigit, shift, carry, borrow, i, l, q;
- if (remainder.length <= a_l) remainder.push(0);
- divisor.push(0);
- divisorMostSignificantDigit = divisor[b_l - 1];
- for (shift = a_l - b_l; shift >= 0; shift--) {
- quotientDigit = base - 1;
- if (remainder[shift + b_l] !== divisorMostSignificantDigit) {
- quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit);
- }
- // quotientDigit <= base - 1
- carry = 0;
- borrow = 0;
- l = divisor.length;
- for (i = 0; i < l; i++) {
- carry += quotientDigit * divisor[i];
- q = Math.floor(carry / base);
- borrow += remainder[shift + i] - (carry - q * base);
- carry = q;
- if (borrow < 0) {
- remainder[shift + i] = borrow + base;
- borrow = -1;
- } else {
- remainder[shift + i] = borrow;
- borrow = 0;
- }
- }
- while (borrow !== 0) {
- quotientDigit -= 1;
- carry = 0;
- for (i = 0; i < l; i++) {
- carry += remainder[shift + i] - base + divisor[i];
- if (carry < 0) {
- remainder[shift + i] = carry + base;
- carry = 0;
- } else {
- remainder[shift + i] = carry;
- carry = 1;
- }
- }
- borrow += carry;
- }
- result[shift] = quotientDigit;
- }
- // denormalization
- remainder = divModSmall(remainder, lambda)[0];
- return [arrayToSmall(result), arrayToSmall(remainder)];
- }
-
- function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
- // Performs faster than divMod1 on larger input sizes.
- var a_l = a.length,
- b_l = b.length,
- result = [],
- part = [],
- base = BASE,
- guess, xlen, highx, highy, check;
- while (a_l) {
- part.unshift(a[--a_l]);
- trim(part);
- if (compareAbs(part, b) < 0) {
- result.push(0);
- continue;
- }
- xlen = part.length;
- highx = part[xlen - 1] * base + part[xlen - 2];
- highy = b[b_l - 1] * base + b[b_l - 2];
- if (xlen > b_l) {
- highx = (highx + 1) * base;
- }
- guess = Math.ceil(highx / highy);
- do {
- check = multiplySmall(b, guess);
- if (compareAbs(check, part) <= 0) break;
- guess--;
- } while (guess);
- result.push(guess);
- part = subtract(part, check);
- }
- result.reverse();
- return [arrayToSmall(result), arrayToSmall(part)];
- }
-
- function divModSmall(value, lambda) {
- var length = value.length,
- quotient = createArray(length),
- base = BASE,
- i, q, remainder, divisor;
- remainder = 0;
- for (i = length - 1; i >= 0; --i) {
- divisor = remainder * base + value[i];
- q = truncate(divisor / lambda);
- remainder = divisor - q * lambda;
- quotient[i] = q | 0;
- }
- return [quotient, remainder | 0];
- }
-
- function divModAny(self, v) {
- var value, n = parseValue(v);
- if (supportsNativeBigInt) {
- return [new NativeBigInt(self.value / n.value), new NativeBigInt(self.value % n.value)];
- }
- var a = self.value, b = n.value;
- var quotient;
- if (b === 0) throw new Error("Cannot divide by zero");
- if (self.isSmall) {
- if (n.isSmall) {
- return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)];
- }
- return [Integer[0], self];
- }
- if (n.isSmall) {
- if (b === 1) return [self, Integer[0]];
- if (b == -1) return [self.negate(), Integer[0]];
- var abs = Math.abs(b);
- if (abs < BASE) {
- value = divModSmall(a, abs);
- quotient = arrayToSmall(value[0]);
- var remainder = value[1];
- if (self.sign) remainder = -remainder;
- if (typeof quotient === "number") {
- if (self.sign !== n.sign) quotient = -quotient;
- return [new SmallInteger(quotient), new SmallInteger(remainder)];
- }
- return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)];
- }
- b = smallToArray(abs);
- }
- var comparison = compareAbs(a, b);
- if (comparison === -1) return [Integer[0], self];
- if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]];
-
- // divMod1 is faster on smaller input sizes
- if (a.length + b.length <= 200)
- value = divMod1(a, b);
- else value = divMod2(a, b);
-
- quotient = value[0];
- var qSign = self.sign !== n.sign,
- mod = value[1],
- mSign = self.sign;
- if (typeof quotient === "number") {
- if (qSign) quotient = -quotient;
- quotient = new SmallInteger(quotient);
- } else quotient = new BigInteger(quotient, qSign);
- if (typeof mod === "number") {
- if (mSign) mod = -mod;
- mod = new SmallInteger(mod);
- } else mod = new BigInteger(mod, mSign);
- return [quotient, mod];
- }
-
- BigInteger.prototype.divmod = function (v) {
- var result = divModAny(this, v);
- return {
- quotient: result[0],
- remainder: result[1]
- };
- };
- NativeBigInt.prototype.divmod = SmallInteger.prototype.divmod = BigInteger.prototype.divmod;
-
-
- BigInteger.prototype.divide = function (v) {
- return divModAny(this, v)[0];
- };
- NativeBigInt.prototype.over = NativeBigInt.prototype.divide = function (v) {
- return new NativeBigInt(this.value / parseValue(v).value);
- };
- SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
-
- BigInteger.prototype.mod = function (v) {
- return divModAny(this, v)[1];
- };
- NativeBigInt.prototype.mod = NativeBigInt.prototype.remainder = function (v) {
- return new NativeBigInt(this.value % parseValue(v).value);
- };
- SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
-
- BigInteger.prototype.pow = function (v) {
- var n = parseValue(v),
- a = this.value,
- b = n.value,
- value, x, y;
- if (b === 0) return Integer[1];
- if (a === 0) return Integer[0];
- if (a === 1) return Integer[1];
- if (a === -1) return n.isEven() ? Integer[1] : Integer[-1];
- if (n.sign) {
- return Integer[0];
- }
- if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large.");
- if (this.isSmall) {
- if (isPrecise(value = Math.pow(a, b)))
- return new SmallInteger(truncate(value));
- }
- x = this;
- y = Integer[1];
- while (true) {
- if (b & 1 === 1) {
- y = y.times(x);
- --b;
- }
- if (b === 0) break;
- b /= 2;
- x = x.square();
- }
- return y;
- };
- SmallInteger.prototype.pow = BigInteger.prototype.pow;
-
- NativeBigInt.prototype.pow = function (v) {
- var n = parseValue(v);
- var a = this.value, b = n.value;
- var _0 = BigInt(0), _1 = BigInt(1), _2 = BigInt(2);
- if (b === _0) return Integer[1];
- if (a === _0) return Integer[0];
- if (a === _1) return Integer[1];
- if (a === BigInt(-1)) return n.isEven() ? Integer[1] : Integer[-1];
- if (n.isNegative()) return new NativeBigInt(_0);
- var x = this;
- var y = Integer[1];
- while (true) {
- if ((b & _1) === _1) {
- y = y.times(x);
- --b;
- }
- if (b === _0) break;
- b /= _2;
- x = x.square();
- }
- return y;
- }
-
- BigInteger.prototype.modPow = function (exp, mod) {
- exp = parseValue(exp);
- mod = parseValue(mod);
- if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
- var r = Integer[1],
- base = this.mod(mod);
- while (exp.isPositive()) {
- if (base.isZero()) return Integer[0];
- if (exp.isOdd()) r = r.multiply(base).mod(mod);
- exp = exp.divide(2);
- base = base.square().mod(mod);
- }
- return r;
- };
- NativeBigInt.prototype.modPow = SmallInteger.prototype.modPow = BigInteger.prototype.modPow;
-
- function compareAbs(a, b) {
- if (a.length !== b.length) {
- return a.length > b.length ? 1 : -1;
- }
- for (var i = a.length - 1; i >= 0; i--) {
- if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
- }
- return 0;
- }
-
- BigInteger.prototype.compareAbs = function (v) {
- var n = parseValue(v),
- a = this.value,
- b = n.value;
- if (n.isSmall) return 1;
- return compareAbs(a, b);
- };
- SmallInteger.prototype.compareAbs = function (v) {
- var n = parseValue(v),
- a = Math.abs(this.value),
- b = n.value;
- if (n.isSmall) {
- b = Math.abs(b);
- return a === b ? 0 : a > b ? 1 : -1;
- }
- return -1;
- };
- NativeBigInt.prototype.compareAbs = function (v) {
- var a = this.value;
- var b = parseValue(v).value;
- a = a >= 0 ? a : -a;
- b = b >= 0 ? b : -b;
- return a === b ? 0 : a > b ? 1 : -1;
- }
-
- BigInteger.prototype.compare = function (v) {
- // See discussion about comparison with Infinity:
- // https://github.com/peterolson/BigInteger.js/issues/61
- if (v === Infinity) {
- return -1;
- }
- if (v === -Infinity) {
- return 1;
- }
-
- var n = parseValue(v),
- a = this.value,
- b = n.value;
- if (this.sign !== n.sign) {
- return n.sign ? 1 : -1;
- }
- if (n.isSmall) {
- return this.sign ? -1 : 1;
- }
- return compareAbs(a, b) * (this.sign ? -1 : 1);
- };
- BigInteger.prototype.compareTo = BigInteger.prototype.compare;
-
- SmallInteger.prototype.compare = function (v) {
- if (v === Infinity) {
- return -1;
- }
- if (v === -Infinity) {
- return 1;
- }
-
- var n = parseValue(v),
- a = this.value,
- b = n.value;
- if (n.isSmall) {
- return a == b ? 0 : a > b ? 1 : -1;
- }
- if (a < 0 !== n.sign) {
- return a < 0 ? -1 : 1;
- }
- return a < 0 ? 1 : -1;
- };
- SmallInteger.prototype.compareTo = SmallInteger.prototype.compare;
-
- NativeBigInt.prototype.compare = function (v) {
- if (v === Infinity) {
- return -1;
- }
- if (v === -Infinity) {
- return 1;
- }
- var a = this.value;
- var b = parseValue(v).value;
- return a === b ? 0 : a > b ? 1 : -1;
- }
- NativeBigInt.prototype.compareTo = NativeBigInt.prototype.compare;
-
- BigInteger.prototype.equals = function (v) {
- return this.compare(v) === 0;
- };
- NativeBigInt.prototype.eq = NativeBigInt.prototype.equals = SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals;
-
- BigInteger.prototype.notEquals = function (v) {
- return this.compare(v) !== 0;
- };
- NativeBigInt.prototype.neq = NativeBigInt.prototype.notEquals = SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals;
-
- BigInteger.prototype.greater = function (v) {
- return this.compare(v) > 0;
- };
- NativeBigInt.prototype.gt = NativeBigInt.prototype.greater = SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater;
-
- BigInteger.prototype.lesser = function (v) {
- return this.compare(v) < 0;
- };
- NativeBigInt.prototype.lt = NativeBigInt.prototype.lesser = SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser;
-
- BigInteger.prototype.greaterOrEquals = function (v) {
- return this.compare(v) >= 0;
- };
- NativeBigInt.prototype.geq = NativeBigInt.prototype.greaterOrEquals = SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals;
-
- BigInteger.prototype.lesserOrEquals = function (v) {
- return this.compare(v) <= 0;
- };
- NativeBigInt.prototype.leq = NativeBigInt.prototype.lesserOrEquals = SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals;
-
- BigInteger.prototype.isEven = function () {
- return (this.value[0] & 1) === 0;
- };
- SmallInteger.prototype.isEven = function () {
- return (this.value & 1) === 0;
- };
- NativeBigInt.prototype.isEven = function () {
- return (this.value & BigInt(1)) === BigInt(0);
- }
-
- BigInteger.prototype.isOdd = function () {
- return (this.value[0] & 1) === 1;
- };
- SmallInteger.prototype.isOdd = function () {
- return (this.value & 1) === 1;
- };
- NativeBigInt.prototype.isOdd = function () {
- return (this.value & BigInt(1)) === BigInt(1);
- }
-
- BigInteger.prototype.isPositive = function () {
- return !this.sign;
- };
- SmallInteger.prototype.isPositive = function () {
- return this.value > 0;
- };
- NativeBigInt.prototype.isPositive = SmallInteger.prototype.isPositive;
-
- BigInteger.prototype.isNegative = function () {
- return this.sign;
- };
- SmallInteger.prototype.isNegative = function () {
- return this.value < 0;
- };
- NativeBigInt.prototype.isNegative = SmallInteger.prototype.isNegative;
-
- BigInteger.prototype.isUnit = function () {
- return false;
- };
- SmallInteger.prototype.isUnit = function () {
- return Math.abs(this.value) === 1;
- };
- NativeBigInt.prototype.isUnit = function () {
- return this.abs().value === BigInt(1);
- }
-
- BigInteger.prototype.isZero = function () {
- return false;
- };
- SmallInteger.prototype.isZero = function () {
- return this.value === 0;
- };
- NativeBigInt.prototype.isZero = function () {
- return this.value === BigInt(0);
- }
-
- BigInteger.prototype.isDivisibleBy = function (v) {
- var n = parseValue(v);
- if (n.isZero()) return false;
- if (n.isUnit()) return true;
- if (n.compareAbs(2) === 0) return this.isEven();
- return this.mod(n).isZero();
- };
- NativeBigInt.prototype.isDivisibleBy = SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy;
-
- function isBasicPrime(v) {
- var n = v.abs();
- if (n.isUnit()) return false;
- if (n.equals(2) || n.equals(3) || n.equals(5)) return true;
- if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false;
- if (n.lesser(49)) return true;
- // we don't know if it's prime: let the other functions figure it out
- }
-
- function millerRabinTest(n, a) {
- var nPrev = n.prev(),
- b = nPrev,
- r = 0,
- d, t, i, x;
- while (b.isEven()) b = b.divide(2), r++;
- next: for (i = 0; i < a.length; i++) {
- if (n.lesser(a[i])) continue;
- x = bigInt(a[i]).modPow(b, n);
- if (x.isUnit() || x.equals(nPrev)) continue;
- for (d = r - 1; d != 0; d--) {
- x = x.square().mod(n);
- if (x.isUnit()) return false;
- if (x.equals(nPrev)) continue next;
- }
- return false;
- }
- return true;
- }
-
- // Set "strict" to true to force GRH-supported lower bound of 2*log(N)^2
- BigInteger.prototype.isPrime = function (strict) {
- var isPrime = isBasicPrime(this);
- if (isPrime !== undefined) return isPrime;
- var n = this.abs();
- var bits = n.bitLength();
- if (bits <= 64)
- return millerRabinTest(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]);
- var logN = Math.log(2) * bits.toJSNumber();
- var t = Math.ceil((strict === true) ? (2 * Math.pow(logN, 2)) : logN);
- for (var a = [], i = 0; i < t; i++) {
- a.push(bigInt(i + 2));
- }
- return millerRabinTest(n, a);
- };
- NativeBigInt.prototype.isPrime = SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
-
- BigInteger.prototype.isProbablePrime = function (iterations) {
- var isPrime = isBasicPrime(this);
- if (isPrime !== undefined) return isPrime;
- var n = this.abs();
- var t = iterations === undefined ? 5 : iterations;
- for (var a = [], i = 0; i < t; i++) {
- a.push(bigInt.randBetween(2, n.minus(2)));
- }
- return millerRabinTest(n, a);
- };
- NativeBigInt.prototype.isProbablePrime = SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime;
-
- BigInteger.prototype.modInv = function (n) {
- var t = bigInt.zero, newT = bigInt.one, r = parseValue(n), newR = this.abs(), q, lastT, lastR;
- while (!newR.isZero()) {
- q = r.divide(newR);
- lastT = t;
- lastR = r;
- t = newT;
- r = newR;
- newT = lastT.subtract(q.multiply(newT));
- newR = lastR.subtract(q.multiply(newR));
- }
- if (!r.isUnit()) throw new Error(this.toString() + " and " + n.toString() + " are not co-prime");
- if (t.compare(0) === -1) {
- t = t.add(n);
- }
- if (this.isNegative()) {
- return t.negate();
- }
- return t;
- };
-
- NativeBigInt.prototype.modInv = SmallInteger.prototype.modInv = BigInteger.prototype.modInv;
-
- BigInteger.prototype.next = function () {
- var value = this.value;
- if (this.sign) {
- return subtractSmall(value, 1, this.sign);
- }
- return new BigInteger(addSmall(value, 1), this.sign);
- };
- SmallInteger.prototype.next = function () {
- var value = this.value;
- if (value + 1 < MAX_INT) return new SmallInteger(value + 1);
- return new BigInteger(MAX_INT_ARR, false);
- };
- NativeBigInt.prototype.next = function () {
- return new NativeBigInt(this.value + BigInt(1));
- }
-
- BigInteger.prototype.prev = function () {
- var value = this.value;
- if (this.sign) {
- return new BigInteger(addSmall(value, 1), true);
- }
- return subtractSmall(value, 1, this.sign);
- };
- SmallInteger.prototype.prev = function () {
- var value = this.value;
- if (value - 1 > -MAX_INT) return new SmallInteger(value - 1);
- return new BigInteger(MAX_INT_ARR, true);
- };
- NativeBigInt.prototype.prev = function () {
- return new NativeBigInt(this.value - BigInt(1));
- }
-
- var powersOfTwo = [1];
- while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
- var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
-
- function shift_isSmall(n) {
- return Math.abs(n) <= BASE;
- }
-
- BigInteger.prototype.shiftLeft = function (v) {
- var n = parseValue(v).toJSNumber();
- if (!shift_isSmall(n)) {
- throw new Error(String(n) + " is too large for shifting.");
- }
- if (n < 0) return this.shiftRight(-n);
- var result = this;
- if (result.isZero()) return result;
- while (n >= powers2Length) {
- result = result.multiply(highestPower2);
- n -= powers2Length - 1;
- }
- return result.multiply(powersOfTwo[n]);
- };
- NativeBigInt.prototype.shiftLeft = SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft;
-
- BigInteger.prototype.shiftRight = function (v) {
- var remQuo;
- var n = parseValue(v).toJSNumber();
- if (!shift_isSmall(n)) {
- throw new Error(String(n) + " is too large for shifting.");
- }
- if (n < 0) return this.shiftLeft(-n);
- var result = this;
- while (n >= powers2Length) {
- if (result.isZero() || (result.isNegative() && result.isUnit())) return result;
- remQuo = divModAny(result, highestPower2);
- result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
- n -= powers2Length - 1;
- }
- remQuo = divModAny(result, powersOfTwo[n]);
- return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
- };
- NativeBigInt.prototype.shiftRight = SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight;
-
- function bitwise(x, y, fn) {
- y = parseValue(y);
- var xSign = x.isNegative(), ySign = y.isNegative();
- var xRem = xSign ? x.not() : x,
- yRem = ySign ? y.not() : y;
- var xDigit = 0, yDigit = 0;
- var xDivMod = null, yDivMod = null;
- var result = [];
- while (!xRem.isZero() || !yRem.isZero()) {
- xDivMod = divModAny(xRem, highestPower2);
- xDigit = xDivMod[1].toJSNumber();
- if (xSign) {
- xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
- }
-
- yDivMod = divModAny(yRem, highestPower2);
- yDigit = yDivMod[1].toJSNumber();
- if (ySign) {
- yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
- }
-
- xRem = xDivMod[0];
- yRem = yDivMod[0];
- result.push(fn(xDigit, yDigit));
- }
- var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0);
- for (var i = result.length - 1; i >= 0; i -= 1) {
- sum = sum.multiply(highestPower2).add(bigInt(result[i]));
- }
- return sum;
- }
-
- BigInteger.prototype.not = function () {
- return this.negate().prev();
- };
- NativeBigInt.prototype.not = SmallInteger.prototype.not = BigInteger.prototype.not;
-
- BigInteger.prototype.and = function (n) {
- return bitwise(this, n, function (a, b) { return a & b; });
- };
- NativeBigInt.prototype.and = SmallInteger.prototype.and = BigInteger.prototype.and;
-
- BigInteger.prototype.or = function (n) {
- return bitwise(this, n, function (a, b) { return a | b; });
- };
- NativeBigInt.prototype.or = SmallInteger.prototype.or = BigInteger.prototype.or;
-
- BigInteger.prototype.xor = function (n) {
- return bitwise(this, n, function (a, b) { return a ^ b; });
- };
- NativeBigInt.prototype.xor = SmallInteger.prototype.xor = BigInteger.prototype.xor;
-
- var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I;
- function roughLOB(n) { // get lowestOneBit (rough)
- // SmallInteger: return Min(lowestOneBit(n), 1 << 30)
- // BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
- var v = n.value,
- x = typeof v === "number" ? v | LOBMASK_I :
- typeof v === "bigint" ? v | BigInt(LOBMASK_I) :
- v[0] + v[1] * BASE | LOBMASK_BI;
- return x & -x;
- }
-
- function integerLogarithm(value, base) {
- if (base.compareTo(value) <= 0) {
- var tmp = integerLogarithm(value, base.square(base));
- var p = tmp.p;
- var e = tmp.e;
- var t = p.multiply(base);
- return t.compareTo(value) <= 0 ? { p: t, e: e * 2 + 1 } : { p: p, e: e * 2 };
- }
- return { p: bigInt(1), e: 0 };
- }
-
- BigInteger.prototype.bitLength = function () {
- var n = this;
- if (n.compareTo(bigInt(0)) < 0) {
- n = n.negate().subtract(bigInt(1));
- }
- if (n.compareTo(bigInt(0)) === 0) {
- return bigInt(0);
- }
- return bigInt(integerLogarithm(n, bigInt(2)).e).add(bigInt(1));
- }
- NativeBigInt.prototype.bitLength = SmallInteger.prototype.bitLength = BigInteger.prototype.bitLength;
-
- function max(a, b) {
- a = parseValue(a);
- b = parseValue(b);
- return a.greater(b) ? a : b;
- }
- function min(a, b) {
- a = parseValue(a);
- b = parseValue(b);
- return a.lesser(b) ? a : b;
- }
- function gcd(a, b) {
- a = parseValue(a).abs();
- b = parseValue(b).abs();
- if (a.equals(b)) return a;
- if (a.isZero()) return b;
- if (b.isZero()) return a;
- var c = Integer[1], d, t;
- while (a.isEven() && b.isEven()) {
- d = min(roughLOB(a), roughLOB(b));
- a = a.divide(d);
- b = b.divide(d);
- c = c.multiply(d);
- }
- while (a.isEven()) {
- a = a.divide(roughLOB(a));
- }
- do {
- while (b.isEven()) {
- b = b.divide(roughLOB(b));
- }
- if (a.greater(b)) {
- t = b; b = a; a = t;
- }
- b = b.subtract(a);
- } while (!b.isZero());
- return c.isUnit() ? a : a.multiply(c);
- }
- function lcm(a, b) {
- a = parseValue(a).abs();
- b = parseValue(b).abs();
- return a.divide(gcd(a, b)).multiply(b);
- }
- function randBetween(a, b) {
- a = parseValue(a);
- b = parseValue(b);
- var low = min(a, b), high = max(a, b);
- var range = high.subtract(low).add(1);
- if (range.isSmall) return low.add(Math.floor(Math.random() * range));
- var digits = toBase(range, BASE).value;
- var result = [], restricted = true;
- for (var i = 0; i < digits.length; i++) {
- var top = restricted ? digits[i] : BASE;
- var digit = truncate(Math.random() * top);
- result.push(digit);
- if (digit < top) restricted = false;
- }
- return low.add(Integer.fromArray(result, BASE, false));
- }
-
- var parseBase = function (text, base, alphabet, caseSensitive) {
- alphabet = alphabet || DEFAULT_ALPHABET;
- text = String(text);
- if (!caseSensitive) {
- text = text.toLowerCase();
- alphabet = alphabet.toLowerCase();
- }
- var length = text.length;
- var i;
- var absBase = Math.abs(base);
- var alphabetValues = {};
- for (i = 0; i < alphabet.length; i++) {
- alphabetValues[alphabet[i]] = i;
- }
- for (i = 0; i < length; i++) {
- var c = text[i];
- if (c === "-") continue;
- if (c in alphabetValues) {
- if (alphabetValues[c] >= absBase) {
- if (c === "1" && absBase === 1) continue;
- throw new Error(c + " is not a valid digit in base " + base + ".");
- }
- }
- }
- base = parseValue(base);
- var digits = [];
- var isNegative = text[0] === "-";
- for (i = isNegative ? 1 : 0; i < text.length; i++) {
- var c = text[i];
- if (c in alphabetValues) digits.push(parseValue(alphabetValues[c]));
- else if (c === "<") {
- var start = i;
- do { i++; } while (text[i] !== ">" && i < text.length);
- digits.push(parseValue(text.slice(start + 1, i)));
- }
- else throw new Error(c + " is not a valid character");
- }
- return parseBaseFromArray(digits, base, isNegative);
- };
-
- function parseBaseFromArray(digits, base, isNegative) {
- var val = Integer[0], pow = Integer[1], i;
- for (i = digits.length - 1; i >= 0; i--) {
- val = val.add(digits[i].times(pow));
- pow = pow.times(base);
- }
- return isNegative ? val.negate() : val;
- }
-
- function stringify(digit, alphabet) {
- alphabet = alphabet || DEFAULT_ALPHABET;
- if (digit < alphabet.length) {
- return alphabet[digit];
- }
- return "<" + digit + ">";
- }
-
- function toBase(n, base) {
- base = bigInt(base);
- if (base.isZero()) {
- if (n.isZero()) return { value: [0], isNegative: false };
- throw new Error("Cannot convert nonzero numbers to base 0.");
- }
- if (base.equals(-1)) {
- if (n.isZero()) return { value: [0], isNegative: false };
- if (n.isNegative())
- return {
- value: [].concat.apply([], Array.apply(null, Array(-n.toJSNumber()))
- .map(Array.prototype.valueOf, [1, 0])
- ),
- isNegative: false
- };
-
- var arr = Array.apply(null, Array(n.toJSNumber() - 1))
- .map(Array.prototype.valueOf, [0, 1]);
- arr.unshift([1]);
- return {
- value: [].concat.apply([], arr),
- isNegative: false
- };
- }
-
- var neg = false;
- if (n.isNegative() && base.isPositive()) {
- neg = true;
- n = n.abs();
- }
- if (base.isUnit()) {
- if (n.isZero()) return { value: [0], isNegative: false };
-
- return {
- value: Array.apply(null, Array(n.toJSNumber()))
- .map(Number.prototype.valueOf, 1),
- isNegative: neg
- };
- }
- var out = [];
- var left = n, divmod;
- while (left.isNegative() || left.compareAbs(base) >= 0) {
- divmod = left.divmod(base);
- left = divmod.quotient;
- var digit = divmod.remainder;
- if (digit.isNegative()) {
- digit = base.minus(digit).abs();
- left = left.next();
- }
- out.push(digit.toJSNumber());
- }
- out.push(left.toJSNumber());
- return { value: out.reverse(), isNegative: neg };
- }
-
- function toBaseString(n, base, alphabet) {
- var arr = toBase(n, base);
- return (arr.isNegative ? "-" : "") + arr.value.map(function (x) {
- return stringify(x, alphabet);
- }).join('');
- }
-
- BigInteger.prototype.toArray = function (radix) {
- return toBase(this, radix);
- };
-
- SmallInteger.prototype.toArray = function (radix) {
- return toBase(this, radix);
- };
-
- NativeBigInt.prototype.toArray = function (radix) {
- return toBase(this, radix);
- };
-
- BigInteger.prototype.toString = function (radix, alphabet) {
- if (radix === undefined) radix = 10;
- if (radix !== 10) return toBaseString(this, radix, alphabet);
- var v = this.value, l = v.length, str = String(v[--l]), zeros = "0000000", digit;
- while (--l >= 0) {
- digit = String(v[l]);
- str += zeros.slice(digit.length) + digit;
- }
- var sign = this.sign ? "-" : "";
- return sign + str;
- };
-
- SmallInteger.prototype.toString = function (radix, alphabet) {
- if (radix === undefined) radix = 10;
- if (radix != 10) return toBaseString(this, radix, alphabet);
- return String(this.value);
- };
-
- NativeBigInt.prototype.toString = SmallInteger.prototype.toString;
-
- NativeBigInt.prototype.toJSON = BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function () { return this.toString(); }
-
- BigInteger.prototype.valueOf = function () {
- return parseInt(this.toString(), 10);
- };
- BigInteger.prototype.toJSNumber = BigInteger.prototype.valueOf;
-
- SmallInteger.prototype.valueOf = function () {
- return this.value;
- };
- SmallInteger.prototype.toJSNumber = SmallInteger.prototype.valueOf;
- NativeBigInt.prototype.valueOf = NativeBigInt.prototype.toJSNumber = function () {
- return parseInt(this.toString(), 10);
- }
-
- function parseStringValue(v) {
- if (isPrecise(+v)) {
- var x = +v;
- if (x === truncate(x))
- return supportsNativeBigInt ? new NativeBigInt(BigInt(x)) : new SmallInteger(x);
- throw new Error("Invalid integer: " + v);
- }
- var sign = v[0] === "-";
- if (sign) v = v.slice(1);
- var split = v.split(/e/i);
- if (split.length > 2) throw new Error("Invalid integer: " + split.join("e"));
- if (split.length === 2) {
- var exp = split[1];
- if (exp[0] === "+") exp = exp.slice(1);
- exp = +exp;
- if (exp !== truncate(exp) || !isPrecise(exp)) throw new Error("Invalid integer: " + exp + " is not a valid exponent.");
- var text = split[0];
- var decimalPlace = text.indexOf(".");
- if (decimalPlace >= 0) {
- exp -= text.length - decimalPlace - 1;
- text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1);
- }
- if (exp < 0) throw new Error("Cannot include negative exponent part for integers");
- text += (new Array(exp + 1)).join("0");
- v = text;
- }
- var isValid = /^([0-9][0-9]*)$/.test(v);
- if (!isValid) throw new Error("Invalid integer: " + v);
- if (supportsNativeBigInt) {
- return new NativeBigInt(BigInt(sign ? "-" + v : v));
- }
- var r = [], max = v.length, l = LOG_BASE, min = max - l;
- while (max > 0) {
- r.push(+v.slice(min, max));
- min -= l;
- if (min < 0) min = 0;
- max -= l;
- }
- trim(r);
- return new BigInteger(r, sign);
- }
-
- function parseNumberValue(v) {
- if (supportsNativeBigInt) {
- return new NativeBigInt(BigInt(v));
- }
- if (isPrecise(v)) {
- if (v !== truncate(v)) throw new Error(v + " is not an integer.");
- return new SmallInteger(v);
- }
- return parseStringValue(v.toString());
- }
-
- function parseValue(v) {
- if (typeof v === "number") {
- return parseNumberValue(v);
- }
- if (typeof v === "string") {
- return parseStringValue(v);
- }
- if (typeof v === "bigint") {
- return new NativeBigInt(v);
- }
- return v;
- }
- // Pre-define numbers in range [-999,999]
- for (var i = 0; i < 1000; i++) {
- Integer[i] = parseValue(i);
- if (i > 0) Integer[-i] = parseValue(-i);
- }
- // Backwards compatibility
- Integer.one = Integer[1];
- Integer.zero = Integer[0];
- Integer.minusOne = Integer[-1];
- Integer.max = max;
- Integer.min = min;
- Integer.gcd = gcd;
- Integer.lcm = lcm;
- Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger || x instanceof NativeBigInt; };
- Integer.randBetween = randBetween;
-
- Integer.fromArray = function (digits, base, isNegative) {
- return parseBaseFromArray(digits.map(parseValue), parseValue(base || 10), isNegative);
- };
-
- return Integer;
-})();
-
-// Node.js check
-if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
- module.exports = bigInt;
-}
-
-//amd check
-if (typeof define === "function" && define.amd) {
- define("big-integer", [], function () {
- return bigInt;
- });
-}
+var bigInt = (function (undefined) {
+ "use strict";
+
+ var BASE = 1e7,
+ LOG_BASE = 7,
+ MAX_INT = 9007199254740992,
+ MAX_INT_ARR = smallToArray(MAX_INT),
+ DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+ var supportsNativeBigInt = typeof BigInt === "function";
+
+ function Integer(v, radix, alphabet, caseSensitive) {
+ if (typeof v === "undefined") return Integer[0];
+ if (typeof radix !== "undefined") return +radix === 10 && !alphabet ? parseValue(v) : parseBase(v, radix, alphabet, caseSensitive);
+ return parseValue(v);
+ }
+
+ function BigInteger(value, sign) {
+ this.value = value;
+ this.sign = sign;
+ this.isSmall = false;
+ }
+ BigInteger.prototype = Object.create(Integer.prototype);
+
+ function SmallInteger(value) {
+ this.value = value;
+ this.sign = value < 0;
+ this.isSmall = true;
+ }
+ SmallInteger.prototype = Object.create(Integer.prototype);
+
+ function NativeBigInt(value) {
+ this.value = value;
+ }
+ NativeBigInt.prototype = Object.create(Integer.prototype);
+
+ function isPrecise(n) {
+ return -MAX_INT < n && n < MAX_INT;
+ }
+
+ function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
+ if (n < 1e7)
+ return [n];
+ if (n < 1e14)
+ return [n % 1e7, Math.floor(n / 1e7)];
+ return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)];
+ }
+
+ function arrayToSmall(arr) { // If BASE changes this function may need to change
+ trim(arr);
+ var length = arr.length;
+ if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) {
+ switch (length) {
+ case 0: return 0;
+ case 1: return arr[0];
+ case 2: return arr[0] + arr[1] * BASE;
+ default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE;
+ }
+ }
+ return arr;
+ }
+
+ function trim(v) {
+ var i = v.length;
+ while (v[--i] === 0);
+ v.length = i + 1;
+ }
+
+ function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
+ var x = new Array(length);
+ var i = -1;
+ while (++i < length) {
+ x[i] = 0;
+ }
+ return x;
+ }
+
+ function truncate(n) {
+ if (n > 0) return Math.floor(n);
+ return Math.ceil(n);
+ }
+
+ function add(a, b) { // assumes a and b are arrays with a.length >= b.length
+ var l_a = a.length,
+ l_b = b.length,
+ r = new Array(l_a),
+ carry = 0,
+ base = BASE,
+ sum, i;
+ for (i = 0; i < l_b; i++) {
+ sum = a[i] + b[i] + carry;
+ carry = sum >= base ? 1 : 0;
+ r[i] = sum - carry * base;
+ }
+ while (i < l_a) {
+ sum = a[i] + carry;
+ carry = sum === base ? 1 : 0;
+ r[i++] = sum - carry * base;
+ }
+ if (carry > 0) r.push(carry);
+ return r;
+ }
+
+ function addAny(a, b) {
+ if (a.length >= b.length) return add(a, b);
+ return add(b, a);
+ }
+
+ function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
+ var l = a.length,
+ r = new Array(l),
+ base = BASE,
+ sum, i;
+ for (i = 0; i < l; i++) {
+ sum = a[i] - base + carry;
+ carry = Math.floor(sum / base);
+ r[i] = sum - carry * base;
+ carry += 1;
+ }
+ while (carry > 0) {
+ r[i++] = carry % base;
+ carry = Math.floor(carry / base);
+ }
+ return r;
+ }
+
+ BigInteger.prototype.add = function (v) {
+ var n = parseValue(v);
+ if (this.sign !== n.sign) {
+ return this.subtract(n.negate());
+ }
+ var a = this.value, b = n.value;
+ if (n.isSmall) {
+ return new BigInteger(addSmall(a, Math.abs(b)), this.sign);
+ }
+ return new BigInteger(addAny(a, b), this.sign);
+ };
+ BigInteger.prototype.plus = BigInteger.prototype.add;
+
+ SmallInteger.prototype.add = function (v) {
+ var n = parseValue(v);
+ var a = this.value;
+ if (a < 0 !== n.sign) {
+ return this.subtract(n.negate());
+ }
+ var b = n.value;
+ if (n.isSmall) {
+ if (isPrecise(a + b)) return new SmallInteger(a + b);
+ b = smallToArray(Math.abs(b));
+ }
+ return new BigInteger(addSmall(b, Math.abs(a)), a < 0);
+ };
+ SmallInteger.prototype.plus = SmallInteger.prototype.add;
+
+ NativeBigInt.prototype.add = function (v) {
+ return new NativeBigInt(this.value + parseValue(v).value);
+ }
+ NativeBigInt.prototype.plus = NativeBigInt.prototype.add;
+
+ function subtract(a, b) { // assumes a and b are arrays with a >= b
+ var a_l = a.length,
+ b_l = b.length,
+ r = new Array(a_l),
+ borrow = 0,
+ base = BASE,
+ i, difference;
+ for (i = 0; i < b_l; i++) {
+ difference = a[i] - borrow - b[i];
+ if (difference < 0) {
+ difference += base;
+ borrow = 1;
+ } else borrow = 0;
+ r[i] = difference;
+ }
+ for (i = b_l; i < a_l; i++) {
+ difference = a[i] - borrow;
+ if (difference < 0) difference += base;
+ else {
+ r[i++] = difference;
+ break;
+ }
+ r[i] = difference;
+ }
+ for (; i < a_l; i++) {
+ r[i] = a[i];
+ }
+ trim(r);
+ return r;
+ }
+
+ function subtractAny(a, b, sign) {
+ var value;
+ if (compareAbs(a, b) >= 0) {
+ value = subtract(a, b);
+ } else {
+ value = subtract(b, a);
+ sign = !sign;
+ }
+ value = arrayToSmall(value);
+ if (typeof value === "number") {
+ if (sign) value = -value;
+ return new SmallInteger(value);
+ }
+ return new BigInteger(value, sign);
+ }
+
+ function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
+ var l = a.length,
+ r = new Array(l),
+ carry = -b,
+ base = BASE,
+ i, difference;
+ for (i = 0; i < l; i++) {
+ difference = a[i] + carry;
+ carry = Math.floor(difference / base);
+ difference %= base;
+ r[i] = difference < 0 ? difference + base : difference;
+ }
+ r = arrayToSmall(r);
+ if (typeof r === "number") {
+ if (sign) r = -r;
+ return new SmallInteger(r);
+ } return new BigInteger(r, sign);
+ }
+
+ BigInteger.prototype.subtract = function (v) {
+ var n = parseValue(v);
+ if (this.sign !== n.sign) {
+ return this.add(n.negate());
+ }
+ var a = this.value, b = n.value;
+ if (n.isSmall)
+ return subtractSmall(a, Math.abs(b), this.sign);
+ return subtractAny(a, b, this.sign);
+ };
+ BigInteger.prototype.minus = BigInteger.prototype.subtract;
+
+ SmallInteger.prototype.subtract = function (v) {
+ var n = parseValue(v);
+ var a = this.value;
+ if (a < 0 !== n.sign) {
+ return this.add(n.negate());
+ }
+ var b = n.value;
+ if (n.isSmall) {
+ return new SmallInteger(a - b);
+ }
+ return subtractSmall(b, Math.abs(a), a >= 0);
+ };
+ SmallInteger.prototype.minus = SmallInteger.prototype.subtract;
+
+ NativeBigInt.prototype.subtract = function (v) {
+ return new NativeBigInt(this.value - parseValue(v).value);
+ }
+ NativeBigInt.prototype.minus = NativeBigInt.prototype.subtract;
+
+ BigInteger.prototype.negate = function () {
+ return new BigInteger(this.value, !this.sign);
+ };
+ SmallInteger.prototype.negate = function () {
+ var sign = this.sign;
+ var small = new SmallInteger(-this.value);
+ small.sign = !sign;
+ return small;
+ };
+ NativeBigInt.prototype.negate = function () {
+ return new NativeBigInt(-this.value);
+ }
+
+ BigInteger.prototype.abs = function () {
+ return new BigInteger(this.value, false);
+ };
+ SmallInteger.prototype.abs = function () {
+ return new SmallInteger(Math.abs(this.value));
+ };
+ NativeBigInt.prototype.abs = function () {
+ return new NativeBigInt(this.value >= 0 ? this.value : -this.value);
+ }
+
+
+ function multiplyLong(a, b) {
+ var a_l = a.length,
+ b_l = b.length,
+ l = a_l + b_l,
+ r = createArray(l),
+ base = BASE,
+ product, carry, i, a_i, b_j;
+ for (i = 0; i < a_l; ++i) {
+ a_i = a[i];
+ for (var j = 0; j < b_l; ++j) {
+ b_j = b[j];
+ product = a_i * b_j + r[i + j];
+ carry = Math.floor(product / base);
+ r[i + j] = product - carry * base;
+ r[i + j + 1] += carry;
+ }
+ }
+ trim(r);
+ return r;
+ }
+
+ function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
+ var l = a.length,
+ r = new Array(l),
+ base = BASE,
+ carry = 0,
+ product, i;
+ for (i = 0; i < l; i++) {
+ product = a[i] * b + carry;
+ carry = Math.floor(product / base);
+ r[i] = product - carry * base;
+ }
+ while (carry > 0) {
+ r[i++] = carry % base;
+ carry = Math.floor(carry / base);
+ }
+ return r;
+ }
+
+ function shiftLeft(x, n) {
+ var r = [];
+ while (n-- > 0) r.push(0);
+ return r.concat(x);
+ }
+
+ function multiplyKaratsuba(x, y) {
+ var n = Math.max(x.length, y.length);
+
+ if (n <= 30) return multiplyLong(x, y);
+ n = Math.ceil(n / 2);
+
+ var b = x.slice(n),
+ a = x.slice(0, n),
+ d = y.slice(n),
+ c = y.slice(0, n);
+
+ var ac = multiplyKaratsuba(a, c),
+ bd = multiplyKaratsuba(b, d),
+ abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d));
+
+ var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n));
+ trim(product);
+ return product;
+ }
+
+ // The following function is derived from a surface fit of a graph plotting the performance difference
+ // between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
+ function useKaratsuba(l1, l2) {
+ return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0;
+ }
+
+ BigInteger.prototype.multiply = function (v) {
+ var n = parseValue(v),
+ a = this.value, b = n.value,
+ sign = this.sign !== n.sign,
+ abs;
+ if (n.isSmall) {
+ if (b === 0) return Integer[0];
+ if (b === 1) return this;
+ if (b === -1) return this.negate();
+ abs = Math.abs(b);
+ if (abs < BASE) {
+ return new BigInteger(multiplySmall(a, abs), sign);
+ }
+ b = smallToArray(abs);
+ }
+ if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
+ return new BigInteger(multiplyKaratsuba(a, b), sign);
+ return new BigInteger(multiplyLong(a, b), sign);
+ };
+
+ BigInteger.prototype.times = BigInteger.prototype.multiply;
+
+ function multiplySmallAndArray(a, b, sign) { // a >= 0
+ if (a < BASE) {
+ return new BigInteger(multiplySmall(b, a), sign);
+ }
+ return new BigInteger(multiplyLong(b, smallToArray(a)), sign);
+ }
+ SmallInteger.prototype._multiplyBySmall = function (a) {
+ if (isPrecise(a.value * this.value)) {
+ return new SmallInteger(a.value * this.value);
+ }
+ return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign);
+ };
+ BigInteger.prototype._multiplyBySmall = function (a) {
+ if (a.value === 0) return Integer[0];
+ if (a.value === 1) return this;
+ if (a.value === -1) return this.negate();
+ return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign);
+ };
+ SmallInteger.prototype.multiply = function (v) {
+ return parseValue(v)._multiplyBySmall(this);
+ };
+ SmallInteger.prototype.times = SmallInteger.prototype.multiply;
+
+ NativeBigInt.prototype.multiply = function (v) {
+ return new NativeBigInt(this.value * parseValue(v).value);
+ }
+ NativeBigInt.prototype.times = NativeBigInt.prototype.multiply;
+
+ function square(a) {
+ //console.assert(2 * BASE * BASE < MAX_INT);
+ var l = a.length,
+ r = createArray(l + l),
+ base = BASE,
+ product, carry, i, a_i, a_j;
+ for (i = 0; i < l; i++) {
+ a_i = a[i];
+ carry = 0 - a_i * a_i;
+ for (var j = i; j < l; j++) {
+ a_j = a[j];
+ product = 2 * (a_i * a_j) + r[i + j] + carry;
+ carry = Math.floor(product / base);
+ r[i + j] = product - carry * base;
+ }
+ r[i + l] = carry;
+ }
+ trim(r);
+ return r;
+ }
+
+ BigInteger.prototype.square = function () {
+ return new BigInteger(square(this.value), false);
+ };
+
+ SmallInteger.prototype.square = function () {
+ var value = this.value * this.value;
+ if (isPrecise(value)) return new SmallInteger(value);
+ return new BigInteger(square(smallToArray(Math.abs(this.value))), false);
+ };
+
+ NativeBigInt.prototype.square = function (v) {
+ return new NativeBigInt(this.value * this.value);
+ }
+
+ function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
+ var a_l = a.length,
+ b_l = b.length,
+ base = BASE,
+ result = createArray(b.length),
+ divisorMostSignificantDigit = b[b_l - 1],
+ // normalization
+ lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)),
+ remainder = multiplySmall(a, lambda),
+ divisor = multiplySmall(b, lambda),
+ quotientDigit, shift, carry, borrow, i, l, q;
+ if (remainder.length <= a_l) remainder.push(0);
+ divisor.push(0);
+ divisorMostSignificantDigit = divisor[b_l - 1];
+ for (shift = a_l - b_l; shift >= 0; shift--) {
+ quotientDigit = base - 1;
+ if (remainder[shift + b_l] !== divisorMostSignificantDigit) {
+ quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit);
+ }
+ // quotientDigit <= base - 1
+ carry = 0;
+ borrow = 0;
+ l = divisor.length;
+ for (i = 0; i < l; i++) {
+ carry += quotientDigit * divisor[i];
+ q = Math.floor(carry / base);
+ borrow += remainder[shift + i] - (carry - q * base);
+ carry = q;
+ if (borrow < 0) {
+ remainder[shift + i] = borrow + base;
+ borrow = -1;
+ } else {
+ remainder[shift + i] = borrow;
+ borrow = 0;
+ }
+ }
+ while (borrow !== 0) {
+ quotientDigit -= 1;
+ carry = 0;
+ for (i = 0; i < l; i++) {
+ carry += remainder[shift + i] - base + divisor[i];
+ if (carry < 0) {
+ remainder[shift + i] = carry + base;
+ carry = 0;
+ } else {
+ remainder[shift + i] = carry;
+ carry = 1;
+ }
+ }
+ borrow += carry;
+ }
+ result[shift] = quotientDigit;
+ }
+ // denormalization
+ remainder = divModSmall(remainder, lambda)[0];
+ return [arrayToSmall(result), arrayToSmall(remainder)];
+ }
+
+ function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
+ // Performs faster than divMod1 on larger input sizes.
+ var a_l = a.length,
+ b_l = b.length,
+ result = [],
+ part = [],
+ base = BASE,
+ guess, xlen, highx, highy, check;
+ while (a_l) {
+ part.unshift(a[--a_l]);
+ trim(part);
+ if (compareAbs(part, b) < 0) {
+ result.push(0);
+ continue;
+ }
+ xlen = part.length;
+ highx = part[xlen - 1] * base + part[xlen - 2];
+ highy = b[b_l - 1] * base + b[b_l - 2];
+ if (xlen > b_l) {
+ highx = (highx + 1) * base;
+ }
+ guess = Math.ceil(highx / highy);
+ do {
+ check = multiplySmall(b, guess);
+ if (compareAbs(check, part) <= 0) break;
+ guess--;
+ } while (guess);
+ result.push(guess);
+ part = subtract(part, check);
+ }
+ result.reverse();
+ return [arrayToSmall(result), arrayToSmall(part)];
+ }
+
+ function divModSmall(value, lambda) {
+ var length = value.length,
+ quotient = createArray(length),
+ base = BASE,
+ i, q, remainder, divisor;
+ remainder = 0;
+ for (i = length - 1; i >= 0; --i) {
+ divisor = remainder * base + value[i];
+ q = truncate(divisor / lambda);
+ remainder = divisor - q * lambda;
+ quotient[i] = q | 0;
+ }
+ return [quotient, remainder | 0];
+ }
+
+ function divModAny(self, v) {
+ var value, n = parseValue(v);
+ if (supportsNativeBigInt) {
+ return [new NativeBigInt(self.value / n.value), new NativeBigInt(self.value % n.value)];
+ }
+ var a = self.value, b = n.value;
+ var quotient;
+ if (b === 0) throw new Error("Cannot divide by zero");
+ if (self.isSmall) {
+ if (n.isSmall) {
+ return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)];
+ }
+ return [Integer[0], self];
+ }
+ if (n.isSmall) {
+ if (b === 1) return [self, Integer[0]];
+ if (b == -1) return [self.negate(), Integer[0]];
+ var abs = Math.abs(b);
+ if (abs < BASE) {
+ value = divModSmall(a, abs);
+ quotient = arrayToSmall(value[0]);
+ var remainder = value[1];
+ if (self.sign) remainder = -remainder;
+ if (typeof quotient === "number") {
+ if (self.sign !== n.sign) quotient = -quotient;
+ return [new SmallInteger(quotient), new SmallInteger(remainder)];
+ }
+ return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)];
+ }
+ b = smallToArray(abs);
+ }
+ var comparison = compareAbs(a, b);
+ if (comparison === -1) return [Integer[0], self];
+ if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]];
+
+ // divMod1 is faster on smaller input sizes
+ if (a.length + b.length <= 200)
+ value = divMod1(a, b);
+ else value = divMod2(a, b);
+
+ quotient = value[0];
+ var qSign = self.sign !== n.sign,
+ mod = value[1],
+ mSign = self.sign;
+ if (typeof quotient === "number") {
+ if (qSign) quotient = -quotient;
+ quotient = new SmallInteger(quotient);
+ } else quotient = new BigInteger(quotient, qSign);
+ if (typeof mod === "number") {
+ if (mSign) mod = -mod;
+ mod = new SmallInteger(mod);
+ } else mod = new BigInteger(mod, mSign);
+ return [quotient, mod];
+ }
+
+ BigInteger.prototype.divmod = function (v) {
+ var result = divModAny(this, v);
+ return {
+ quotient: result[0],
+ remainder: result[1]
+ };
+ };
+ NativeBigInt.prototype.divmod = SmallInteger.prototype.divmod = BigInteger.prototype.divmod;
+
+
+ BigInteger.prototype.divide = function (v) {
+ return divModAny(this, v)[0];
+ };
+ NativeBigInt.prototype.over = NativeBigInt.prototype.divide = function (v) {
+ return new NativeBigInt(this.value / parseValue(v).value);
+ };
+ SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
+
+ BigInteger.prototype.mod = function (v) {
+ return divModAny(this, v)[1];
+ };
+ NativeBigInt.prototype.mod = NativeBigInt.prototype.remainder = function (v) {
+ return new NativeBigInt(this.value % parseValue(v).value);
+ };
+ SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
+
+ BigInteger.prototype.pow = function (v) {
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value,
+ value, x, y;
+ if (b === 0) return Integer[1];
+ if (a === 0) return Integer[0];
+ if (a === 1) return Integer[1];
+ if (a === -1) return n.isEven() ? Integer[1] : Integer[-1];
+ if (n.sign) {
+ return Integer[0];
+ }
+ if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large.");
+ if (this.isSmall) {
+ if (isPrecise(value = Math.pow(a, b)))
+ return new SmallInteger(truncate(value));
+ }
+ x = this;
+ y = Integer[1];
+ while (true) {
+ if (b & 1 === 1) {
+ y = y.times(x);
+ --b;
+ }
+ if (b === 0) break;
+ b /= 2;
+ x = x.square();
+ }
+ return y;
+ };
+ SmallInteger.prototype.pow = BigInteger.prototype.pow;
+
+ NativeBigInt.prototype.pow = function (v) {
+ var n = parseValue(v);
+ var a = this.value, b = n.value;
+ var _0 = BigInt(0), _1 = BigInt(1), _2 = BigInt(2);
+ if (b === _0) return Integer[1];
+ if (a === _0) return Integer[0];
+ if (a === _1) return Integer[1];
+ if (a === BigInt(-1)) return n.isEven() ? Integer[1] : Integer[-1];
+ if (n.isNegative()) return new NativeBigInt(_0);
+ var x = this;
+ var y = Integer[1];
+ while (true) {
+ if ((b & _1) === _1) {
+ y = y.times(x);
+ --b;
+ }
+ if (b === _0) break;
+ b /= _2;
+ x = x.square();
+ }
+ return y;
+ }
+
+ BigInteger.prototype.modPow = function (exp, mod) {
+ exp = parseValue(exp);
+ mod = parseValue(mod);
+ if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
+ var r = Integer[1],
+ base = this.mod(mod);
+ while (exp.isPositive()) {
+ if (base.isZero()) return Integer[0];
+ if (exp.isOdd()) r = r.multiply(base).mod(mod);
+ exp = exp.divide(2);
+ base = base.square().mod(mod);
+ }
+ return r;
+ };
+ NativeBigInt.prototype.modPow = SmallInteger.prototype.modPow = BigInteger.prototype.modPow;
+
+ function compareAbs(a, b) {
+ if (a.length !== b.length) {
+ return a.length > b.length ? 1 : -1;
+ }
+ for (var i = a.length - 1; i >= 0; i--) {
+ if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
+ }
+ return 0;
+ }
+
+ BigInteger.prototype.compareAbs = function (v) {
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value;
+ if (n.isSmall) return 1;
+ return compareAbs(a, b);
+ };
+ SmallInteger.prototype.compareAbs = function (v) {
+ var n = parseValue(v),
+ a = Math.abs(this.value),
+ b = n.value;
+ if (n.isSmall) {
+ b = Math.abs(b);
+ return a === b ? 0 : a > b ? 1 : -1;
+ }
+ return -1;
+ };
+ NativeBigInt.prototype.compareAbs = function (v) {
+ var a = this.value;
+ var b = parseValue(v).value;
+ a = a >= 0 ? a : -a;
+ b = b >= 0 ? b : -b;
+ return a === b ? 0 : a > b ? 1 : -1;
+ }
+
+ BigInteger.prototype.compare = function (v) {
+ // See discussion about comparison with Infinity:
+ // https://github.com/peterolson/BigInteger.js/issues/61
+ if (v === Infinity) {
+ return -1;
+ }
+ if (v === -Infinity) {
+ return 1;
+ }
+
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value;
+ if (this.sign !== n.sign) {
+ return n.sign ? 1 : -1;
+ }
+ if (n.isSmall) {
+ return this.sign ? -1 : 1;
+ }
+ return compareAbs(a, b) * (this.sign ? -1 : 1);
+ };
+ BigInteger.prototype.compareTo = BigInteger.prototype.compare;
+
+ SmallInteger.prototype.compare = function (v) {
+ if (v === Infinity) {
+ return -1;
+ }
+ if (v === -Infinity) {
+ return 1;
+ }
+
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value;
+ if (n.isSmall) {
+ return a == b ? 0 : a > b ? 1 : -1;
+ }
+ if (a < 0 !== n.sign) {
+ return a < 0 ? -1 : 1;
+ }
+ return a < 0 ? 1 : -1;
+ };
+ SmallInteger.prototype.compareTo = SmallInteger.prototype.compare;
+
+ NativeBigInt.prototype.compare = function (v) {
+ if (v === Infinity) {
+ return -1;
+ }
+ if (v === -Infinity) {
+ return 1;
+ }
+ var a = this.value;
+ var b = parseValue(v).value;
+ return a === b ? 0 : a > b ? 1 : -1;
+ }
+ NativeBigInt.prototype.compareTo = NativeBigInt.prototype.compare;
+
+ BigInteger.prototype.equals = function (v) {
+ return this.compare(v) === 0;
+ };
+ NativeBigInt.prototype.eq = NativeBigInt.prototype.equals = SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals;
+
+ BigInteger.prototype.notEquals = function (v) {
+ return this.compare(v) !== 0;
+ };
+ NativeBigInt.prototype.neq = NativeBigInt.prototype.notEquals = SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals;
+
+ BigInteger.prototype.greater = function (v) {
+ return this.compare(v) > 0;
+ };
+ NativeBigInt.prototype.gt = NativeBigInt.prototype.greater = SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater;
+
+ BigInteger.prototype.lesser = function (v) {
+ return this.compare(v) < 0;
+ };
+ NativeBigInt.prototype.lt = NativeBigInt.prototype.lesser = SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser;
+
+ BigInteger.prototype.greaterOrEquals = function (v) {
+ return this.compare(v) >= 0;
+ };
+ NativeBigInt.prototype.geq = NativeBigInt.prototype.greaterOrEquals = SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals;
+
+ BigInteger.prototype.lesserOrEquals = function (v) {
+ return this.compare(v) <= 0;
+ };
+ NativeBigInt.prototype.leq = NativeBigInt.prototype.lesserOrEquals = SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals;
+
+ BigInteger.prototype.isEven = function () {
+ return (this.value[0] & 1) === 0;
+ };
+ SmallInteger.prototype.isEven = function () {
+ return (this.value & 1) === 0;
+ };
+ NativeBigInt.prototype.isEven = function () {
+ return (this.value & BigInt(1)) === BigInt(0);
+ }
+
+ BigInteger.prototype.isOdd = function () {
+ return (this.value[0] & 1) === 1;
+ };
+ SmallInteger.prototype.isOdd = function () {
+ return (this.value & 1) === 1;
+ };
+ NativeBigInt.prototype.isOdd = function () {
+ return (this.value & BigInt(1)) === BigInt(1);
+ }
+
+ BigInteger.prototype.isPositive = function () {
+ return !this.sign;
+ };
+ SmallInteger.prototype.isPositive = function () {
+ return this.value > 0;
+ };
+ NativeBigInt.prototype.isPositive = SmallInteger.prototype.isPositive;
+
+ BigInteger.prototype.isNegative = function () {
+ return this.sign;
+ };
+ SmallInteger.prototype.isNegative = function () {
+ return this.value < 0;
+ };
+ NativeBigInt.prototype.isNegative = SmallInteger.prototype.isNegative;
+
+ BigInteger.prototype.isUnit = function () {
+ return false;
+ };
+ SmallInteger.prototype.isUnit = function () {
+ return Math.abs(this.value) === 1;
+ };
+ NativeBigInt.prototype.isUnit = function () {
+ return this.abs().value === BigInt(1);
+ }
+
+ BigInteger.prototype.isZero = function () {
+ return false;
+ };
+ SmallInteger.prototype.isZero = function () {
+ return this.value === 0;
+ };
+ NativeBigInt.prototype.isZero = function () {
+ return this.value === BigInt(0);
+ }
+
+ BigInteger.prototype.isDivisibleBy = function (v) {
+ var n = parseValue(v);
+ if (n.isZero()) return false;
+ if (n.isUnit()) return true;
+ if (n.compareAbs(2) === 0) return this.isEven();
+ return this.mod(n).isZero();
+ };
+ NativeBigInt.prototype.isDivisibleBy = SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy;
+
+ function isBasicPrime(v) {
+ var n = v.abs();
+ if (n.isUnit()) return false;
+ if (n.equals(2) || n.equals(3) || n.equals(5)) return true;
+ if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false;
+ if (n.lesser(49)) return true;
+ // we don't know if it's prime: let the other functions figure it out
+ }
+
+ function millerRabinTest(n, a) {
+ var nPrev = n.prev(),
+ b = nPrev,
+ r = 0,
+ d, t, i, x;
+ while (b.isEven()) b = b.divide(2), r++;
+ next: for (i = 0; i < a.length; i++) {
+ if (n.lesser(a[i])) continue;
+ x = bigInt(a[i]).modPow(b, n);
+ if (x.isUnit() || x.equals(nPrev)) continue;
+ for (d = r - 1; d != 0; d--) {
+ x = x.square().mod(n);
+ if (x.isUnit()) return false;
+ if (x.equals(nPrev)) continue next;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ // Set "strict" to true to force GRH-supported lower bound of 2*log(N)^2
+ BigInteger.prototype.isPrime = function (strict) {
+ var isPrime = isBasicPrime(this);
+ if (isPrime !== undefined) return isPrime;
+ var n = this.abs();
+ var bits = n.bitLength();
+ if (bits <= 64)
+ return millerRabinTest(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]);
+ var logN = Math.log(2) * bits.toJSNumber();
+ var t = Math.ceil((strict === true) ? (2 * Math.pow(logN, 2)) : logN);
+ for (var a = [], i = 0; i < t; i++) {
+ a.push(bigInt(i + 2));
+ }
+ return millerRabinTest(n, a);
+ };
+ NativeBigInt.prototype.isPrime = SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
+
+ BigInteger.prototype.isProbablePrime = function (iterations) {
+ var isPrime = isBasicPrime(this);
+ if (isPrime !== undefined) return isPrime;
+ var n = this.abs();
+ var t = iterations === undefined ? 5 : iterations;
+ for (var a = [], i = 0; i < t; i++) {
+ a.push(bigInt.randBetween(2, n.minus(2)));
+ }
+ return millerRabinTest(n, a);
+ };
+ NativeBigInt.prototype.isProbablePrime = SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime;
+
+ BigInteger.prototype.modInv = function (n) {
+ var t = bigInt.zero, newT = bigInt.one, r = parseValue(n), newR = this.abs(), q, lastT, lastR;
+ while (!newR.isZero()) {
+ q = r.divide(newR);
+ lastT = t;
+ lastR = r;
+ t = newT;
+ r = newR;
+ newT = lastT.subtract(q.multiply(newT));
+ newR = lastR.subtract(q.multiply(newR));
+ }
+ if (!r.isUnit()) throw new Error(this.toString() + " and " + n.toString() + " are not co-prime");
+ if (t.compare(0) === -1) {
+ t = t.add(n);
+ }
+ if (this.isNegative()) {
+ return t.negate();
+ }
+ return t;
+ };
+
+ NativeBigInt.prototype.modInv = SmallInteger.prototype.modInv = BigInteger.prototype.modInv;
+
+ BigInteger.prototype.next = function () {
+ var value = this.value;
+ if (this.sign) {
+ return subtractSmall(value, 1, this.sign);
+ }
+ return new BigInteger(addSmall(value, 1), this.sign);
+ };
+ SmallInteger.prototype.next = function () {
+ var value = this.value;
+ if (value + 1 < MAX_INT) return new SmallInteger(value + 1);
+ return new BigInteger(MAX_INT_ARR, false);
+ };
+ NativeBigInt.prototype.next = function () {
+ return new NativeBigInt(this.value + BigInt(1));
+ }
+
+ BigInteger.prototype.prev = function () {
+ var value = this.value;
+ if (this.sign) {
+ return new BigInteger(addSmall(value, 1), true);
+ }
+ return subtractSmall(value, 1, this.sign);
+ };
+ SmallInteger.prototype.prev = function () {
+ var value = this.value;
+ if (value - 1 > -MAX_INT) return new SmallInteger(value - 1);
+ return new BigInteger(MAX_INT_ARR, true);
+ };
+ NativeBigInt.prototype.prev = function () {
+ return new NativeBigInt(this.value - BigInt(1));
+ }
+
+ var powersOfTwo = [1];
+ while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
+ var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
+
+ function shift_isSmall(n) {
+ return Math.abs(n) <= BASE;
+ }
+
+ BigInteger.prototype.shiftLeft = function (v) {
+ var n = parseValue(v).toJSNumber();
+ if (!shift_isSmall(n)) {
+ throw new Error(String(n) + " is too large for shifting.");
+ }
+ if (n < 0) return this.shiftRight(-n);
+ var result = this;
+ if (result.isZero()) return result;
+ while (n >= powers2Length) {
+ result = result.multiply(highestPower2);
+ n -= powers2Length - 1;
+ }
+ return result.multiply(powersOfTwo[n]);
+ };
+ NativeBigInt.prototype.shiftLeft = SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft;
+
+ BigInteger.prototype.shiftRight = function (v) {
+ var remQuo;
+ var n = parseValue(v).toJSNumber();
+ if (!shift_isSmall(n)) {
+ throw new Error(String(n) + " is too large for shifting.");
+ }
+ if (n < 0) return this.shiftLeft(-n);
+ var result = this;
+ while (n >= powers2Length) {
+ if (result.isZero() || (result.isNegative() && result.isUnit())) return result;
+ remQuo = divModAny(result, highestPower2);
+ result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
+ n -= powers2Length - 1;
+ }
+ remQuo = divModAny(result, powersOfTwo[n]);
+ return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
+ };
+ NativeBigInt.prototype.shiftRight = SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight;
+
+ function bitwise(x, y, fn) {
+ y = parseValue(y);
+ var xSign = x.isNegative(), ySign = y.isNegative();
+ var xRem = xSign ? x.not() : x,
+ yRem = ySign ? y.not() : y;
+ var xDigit = 0, yDigit = 0;
+ var xDivMod = null, yDivMod = null;
+ var result = [];
+ while (!xRem.isZero() || !yRem.isZero()) {
+ xDivMod = divModAny(xRem, highestPower2);
+ xDigit = xDivMod[1].toJSNumber();
+ if (xSign) {
+ xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
+ }
+
+ yDivMod = divModAny(yRem, highestPower2);
+ yDigit = yDivMod[1].toJSNumber();
+ if (ySign) {
+ yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
+ }
+
+ xRem = xDivMod[0];
+ yRem = yDivMod[0];
+ result.push(fn(xDigit, yDigit));
+ }
+ var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0);
+ for (var i = result.length - 1; i >= 0; i -= 1) {
+ sum = sum.multiply(highestPower2).add(bigInt(result[i]));
+ }
+ return sum;
+ }
+
+ BigInteger.prototype.not = function () {
+ return this.negate().prev();
+ };
+ NativeBigInt.prototype.not = SmallInteger.prototype.not = BigInteger.prototype.not;
+
+ BigInteger.prototype.and = function (n) {
+ return bitwise(this, n, function (a, b) { return a & b; });
+ };
+ NativeBigInt.prototype.and = SmallInteger.prototype.and = BigInteger.prototype.and;
+
+ BigInteger.prototype.or = function (n) {
+ return bitwise(this, n, function (a, b) { return a | b; });
+ };
+ NativeBigInt.prototype.or = SmallInteger.prototype.or = BigInteger.prototype.or;
+
+ BigInteger.prototype.xor = function (n) {
+ return bitwise(this, n, function (a, b) { return a ^ b; });
+ };
+ NativeBigInt.prototype.xor = SmallInteger.prototype.xor = BigInteger.prototype.xor;
+
+ var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I;
+ function roughLOB(n) { // get lowestOneBit (rough)
+ // SmallInteger: return Min(lowestOneBit(n), 1 << 30)
+ // BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
+ var v = n.value,
+ x = typeof v === "number" ? v | LOBMASK_I :
+ typeof v === "bigint" ? v | BigInt(LOBMASK_I) :
+ v[0] + v[1] * BASE | LOBMASK_BI;
+ return x & -x;
+ }
+
+ function integerLogarithm(value, base) {
+ if (base.compareTo(value) <= 0) {
+ var tmp = integerLogarithm(value, base.square(base));
+ var p = tmp.p;
+ var e = tmp.e;
+ var t = p.multiply(base);
+ return t.compareTo(value) <= 0 ? { p: t, e: e * 2 + 1 } : { p: p, e: e * 2 };
+ }
+ return { p: bigInt(1), e: 0 };
+ }
+
+ BigInteger.prototype.bitLength = function () {
+ var n = this;
+ if (n.compareTo(bigInt(0)) < 0) {
+ n = n.negate().subtract(bigInt(1));
+ }
+ if (n.compareTo(bigInt(0)) === 0) {
+ return bigInt(0);
+ }
+ return bigInt(integerLogarithm(n, bigInt(2)).e).add(bigInt(1));
+ }
+ NativeBigInt.prototype.bitLength = SmallInteger.prototype.bitLength = BigInteger.prototype.bitLength;
+
+ function max(a, b) {
+ a = parseValue(a);
+ b = parseValue(b);
+ return a.greater(b) ? a : b;
+ }
+ function min(a, b) {
+ a = parseValue(a);
+ b = parseValue(b);
+ return a.lesser(b) ? a : b;
+ }
+ function gcd(a, b) {
+ a = parseValue(a).abs();
+ b = parseValue(b).abs();
+ if (a.equals(b)) return a;
+ if (a.isZero()) return b;
+ if (b.isZero()) return a;
+ var c = Integer[1], d, t;
+ while (a.isEven() && b.isEven()) {
+ d = min(roughLOB(a), roughLOB(b));
+ a = a.divide(d);
+ b = b.divide(d);
+ c = c.multiply(d);
+ }
+ while (a.isEven()) {
+ a = a.divide(roughLOB(a));
+ }
+ do {
+ while (b.isEven()) {
+ b = b.divide(roughLOB(b));
+ }
+ if (a.greater(b)) {
+ t = b; b = a; a = t;
+ }
+ b = b.subtract(a);
+ } while (!b.isZero());
+ return c.isUnit() ? a : a.multiply(c);
+ }
+ function lcm(a, b) {
+ a = parseValue(a).abs();
+ b = parseValue(b).abs();
+ return a.divide(gcd(a, b)).multiply(b);
+ }
+ function randBetween(a, b) {
+ a = parseValue(a);
+ b = parseValue(b);
+ var low = min(a, b), high = max(a, b);
+ var range = high.subtract(low).add(1);
+ if (range.isSmall) return low.add(Math.floor(Math.random() * range));
+ var digits = toBase(range, BASE).value;
+ var result = [], restricted = true;
+ for (var i = 0; i < digits.length; i++) {
+ var top = restricted ? digits[i] : BASE;
+ var digit = truncate(Math.random() * top);
+ result.push(digit);
+ if (digit < top) restricted = false;
+ }
+ return low.add(Integer.fromArray(result, BASE, false));
+ }
+
+ var parseBase = function (text, base, alphabet, caseSensitive) {
+ alphabet = alphabet || DEFAULT_ALPHABET;
+ text = String(text);
+ if (!caseSensitive) {
+ text = text.toLowerCase();
+ alphabet = alphabet.toLowerCase();
+ }
+ var length = text.length;
+ var i;
+ var absBase = Math.abs(base);
+ var alphabetValues = {};
+ for (i = 0; i < alphabet.length; i++) {
+ alphabetValues[alphabet[i]] = i;
+ }
+ for (i = 0; i < length; i++) {
+ var c = text[i];
+ if (c === "-") continue;
+ if (c in alphabetValues) {
+ if (alphabetValues[c] >= absBase) {
+ if (c === "1" && absBase === 1) continue;
+ throw new Error(c + " is not a valid digit in base " + base + ".");
+ }
+ }
+ }
+ base = parseValue(base);
+ var digits = [];
+ var isNegative = text[0] === "-";
+ for (i = isNegative ? 1 : 0; i < text.length; i++) {
+ var c = text[i];
+ if (c in alphabetValues) digits.push(parseValue(alphabetValues[c]));
+ else if (c === "<") {
+ var start = i;
+ do { i++; } while (text[i] !== ">" && i < text.length);
+ digits.push(parseValue(text.slice(start + 1, i)));
+ }
+ else throw new Error(c + " is not a valid character");
+ }
+ return parseBaseFromArray(digits, base, isNegative);
+ };
+
+ function parseBaseFromArray(digits, base, isNegative) {
+ var val = Integer[0], pow = Integer[1], i;
+ for (i = digits.length - 1; i >= 0; i--) {
+ val = val.add(digits[i].times(pow));
+ pow = pow.times(base);
+ }
+ return isNegative ? val.negate() : val;
+ }
+
+ function stringify(digit, alphabet) {
+ alphabet = alphabet || DEFAULT_ALPHABET;
+ if (digit < alphabet.length) {
+ return alphabet[digit];
+ }
+ return "<" + digit + ">";
+ }
+
+ function toBase(n, base) {
+ base = bigInt(base);
+ if (base.isZero()) {
+ if (n.isZero()) return { value: [0], isNegative: false };
+ throw new Error("Cannot convert nonzero numbers to base 0.");
+ }
+ if (base.equals(-1)) {
+ if (n.isZero()) return { value: [0], isNegative: false };
+ if (n.isNegative())
+ return {
+ value: [].concat.apply([], Array.apply(null, Array(-n.toJSNumber()))
+ .map(Array.prototype.valueOf, [1, 0])
+ ),
+ isNegative: false
+ };
+
+ var arr = Array.apply(null, Array(n.toJSNumber() - 1))
+ .map(Array.prototype.valueOf, [0, 1]);
+ arr.unshift([1]);
+ return {
+ value: [].concat.apply([], arr),
+ isNegative: false
+ };
+ }
+
+ var neg = false;
+ if (n.isNegative() && base.isPositive()) {
+ neg = true;
+ n = n.abs();
+ }
+ if (base.isUnit()) {
+ if (n.isZero()) return { value: [0], isNegative: false };
+
+ return {
+ value: Array.apply(null, Array(n.toJSNumber()))
+ .map(Number.prototype.valueOf, 1),
+ isNegative: neg
+ };
+ }
+ var out = [];
+ var left = n, divmod;
+ while (left.isNegative() || left.compareAbs(base) >= 0) {
+ divmod = left.divmod(base);
+ left = divmod.quotient;
+ var digit = divmod.remainder;
+ if (digit.isNegative()) {
+ digit = base.minus(digit).abs();
+ left = left.next();
+ }
+ out.push(digit.toJSNumber());
+ }
+ out.push(left.toJSNumber());
+ return { value: out.reverse(), isNegative: neg };
+ }
+
+ function toBaseString(n, base, alphabet) {
+ var arr = toBase(n, base);
+ return (arr.isNegative ? "-" : "") + arr.value.map(function (x) {
+ return stringify(x, alphabet);
+ }).join('');
+ }
+
+ BigInteger.prototype.toArray = function (radix) {
+ return toBase(this, radix);
+ };
+
+ SmallInteger.prototype.toArray = function (radix) {
+ return toBase(this, radix);
+ };
+
+ NativeBigInt.prototype.toArray = function (radix) {
+ return toBase(this, radix);
+ };
+
+ BigInteger.prototype.toString = function (radix, alphabet) {
+ if (radix === undefined) radix = 10;
+ if (radix !== 10) return toBaseString(this, radix, alphabet);
+ var v = this.value, l = v.length, str = String(v[--l]), zeros = "0000000", digit;
+ while (--l >= 0) {
+ digit = String(v[l]);
+ str += zeros.slice(digit.length) + digit;
+ }
+ var sign = this.sign ? "-" : "";
+ return sign + str;
+ };
+
+ SmallInteger.prototype.toString = function (radix, alphabet) {
+ if (radix === undefined) radix = 10;
+ if (radix != 10) return toBaseString(this, radix, alphabet);
+ return String(this.value);
+ };
+
+ NativeBigInt.prototype.toString = SmallInteger.prototype.toString;
+
+ NativeBigInt.prototype.toJSON = BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function () { return this.toString(); }
+
+ BigInteger.prototype.valueOf = function () {
+ return parseInt(this.toString(), 10);
+ };
+ BigInteger.prototype.toJSNumber = BigInteger.prototype.valueOf;
+
+ SmallInteger.prototype.valueOf = function () {
+ return this.value;
+ };
+ SmallInteger.prototype.toJSNumber = SmallInteger.prototype.valueOf;
+ NativeBigInt.prototype.valueOf = NativeBigInt.prototype.toJSNumber = function () {
+ return parseInt(this.toString(), 10);
+ }
+
+ function parseStringValue(v) {
+ if (isPrecise(+v)) {
+ var x = +v;
+ if (x === truncate(x))
+ return supportsNativeBigInt ? new NativeBigInt(BigInt(x)) : new SmallInteger(x);
+ throw new Error("Invalid integer: " + v);
+ }
+ var sign = v[0] === "-";
+ if (sign) v = v.slice(1);
+ var split = v.split(/e/i);
+ if (split.length > 2) throw new Error("Invalid integer: " + split.join("e"));
+ if (split.length === 2) {
+ var exp = split[1];
+ if (exp[0] === "+") exp = exp.slice(1);
+ exp = +exp;
+ if (exp !== truncate(exp) || !isPrecise(exp)) throw new Error("Invalid integer: " + exp + " is not a valid exponent.");
+ var text = split[0];
+ var decimalPlace = text.indexOf(".");
+ if (decimalPlace >= 0) {
+ exp -= text.length - decimalPlace - 1;
+ text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1);
+ }
+ if (exp < 0) throw new Error("Cannot include negative exponent part for integers");
+ text += (new Array(exp + 1)).join("0");
+ v = text;
+ }
+ var isValid = /^([0-9][0-9]*)$/.test(v);
+ if (!isValid) throw new Error("Invalid integer: " + v);
+ if (supportsNativeBigInt) {
+ return new NativeBigInt(BigInt(sign ? "-" + v : v));
+ }
+ var r = [], max = v.length, l = LOG_BASE, min = max - l;
+ while (max > 0) {
+ r.push(+v.slice(min, max));
+ min -= l;
+ if (min < 0) min = 0;
+ max -= l;
+ }
+ trim(r);
+ return new BigInteger(r, sign);
+ }
+
+ function parseNumberValue(v) {
+ if (supportsNativeBigInt) {
+ return new NativeBigInt(BigInt(v));
+ }
+ if (isPrecise(v)) {
+ if (v !== truncate(v)) throw new Error(v + " is not an integer.");
+ return new SmallInteger(v);
+ }
+ return parseStringValue(v.toString());
+ }
+
+ function parseValue(v) {
+ if (typeof v === "number") {
+ return parseNumberValue(v);
+ }
+ if (typeof v === "string") {
+ return parseStringValue(v);
+ }
+ if (typeof v === "bigint") {
+ return new NativeBigInt(v);
+ }
+ return v;
+ }
+ // Pre-define numbers in range [-999,999]
+ for (var i = 0; i < 1000; i++) {
+ Integer[i] = parseValue(i);
+ if (i > 0) Integer[-i] = parseValue(-i);
+ }
+ // Backwards compatibility
+ Integer.one = Integer[1];
+ Integer.zero = Integer[0];
+ Integer.minusOne = Integer[-1];
+ Integer.max = max;
+ Integer.min = min;
+ Integer.gcd = gcd;
+ Integer.lcm = lcm;
+ Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger || x instanceof NativeBigInt; };
+ Integer.randBetween = randBetween;
+
+ Integer.fromArray = function (digits, base, isNegative) {
+ return parseBaseFromArray(digits.map(parseValue), parseValue(base || 10), isNegative);
+ };
+
+ return Integer;
+})();
+
+// Node.js check
+if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
+ module.exports = bigInt;
+}
+
+//amd check
+if (typeof define === "function" && define.amd) {
+ define("big-integer", [], function () {
+ return bigInt;
+ });
+}
},{}],9:[function(require,module,exports){
(function (Buffer){
@@ -4931,6 +4942,976 @@ process.chdir = function (dir) {
process.umask = function() { return 0; };
},{}],13:[function(require,module,exports){
+(function (Buffer){
+/*
+ Copyright 2018 0kims association.
+
+ This file is part of snarkjs.
+
+ snarkjs is a free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ snarkjs is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ snarkjs. If not, see .
+*/
+
+/* global BigInt */
+const bigInt = require("big-integer");
+
+let wBigInt;
+
+if (typeof(BigInt) != "undefined") {
+ wBigInt = BigInt;
+ wBigInt.one = wBigInt(1);
+ wBigInt.zero = wBigInt(0);
+
+ // Affine
+ wBigInt.genAffine = (q) => {
+ const nq = -q;
+ return (a) => {
+ let aux = a;
+ if (aux < 0) {
+ if (aux <= nq) {
+ aux = aux % q;
+ }
+ if (aux < wBigInt.zero) {
+ aux = aux + q;
+ }
+ } else {
+ if (aux >= q) {
+ aux = aux % q;
+ }
+ }
+ return aux.valueOf();
+ };
+ };
+
+
+ // Inverse
+ wBigInt.genInverse = (q) => {
+ return (a) => {
+ let t = wBigInt.zero;
+ let r = q;
+ let newt = wBigInt.one;
+ let newr = wBigInt.affine(a, q);
+ while (newr!=wBigInt.zero) {
+ let q = r/newr;
+ [t, newt] = [newt, t-q*newt];
+ [r, newr] = [newr, r-q*newr];
+ }
+ if (t {
+ if (q) {
+ return (a,b) => (a+b) % q;
+ } else {
+ return (a,b) => a+b;
+ }
+ };
+
+ // Sub
+ wBigInt.genSub = (q) => {
+ if (q) {
+ return (a,b) => (a-b) % q;
+ } else {
+ return (a,b) => a-b;
+ }
+ };
+
+
+ // Neg
+ wBigInt.genNeg = (q) => {
+ if (q) {
+ return (a) => (-a) % q;
+ } else {
+ return (a) => -a;
+ }
+ };
+
+ // Mul
+ wBigInt.genMul = (q) => {
+ if (q) {
+ return (a,b) => (a*b) % q;
+ } else {
+ return (a,b) => a*b;
+ }
+ };
+
+ // Shr
+ wBigInt.genShr = () => {
+ return (a,b) => a >> wBigInt(b);
+ };
+
+ // Shl
+ wBigInt.genShl = (q) => {
+ if (q) {
+ return (a,b) => (a << wBigInt(b)) % q;
+ } else {
+ return (a,b) => a << wBigInt(b);
+ }
+ };
+
+ // Equals
+ wBigInt.genEquals = (q) => {
+ if (q) {
+ return (a,b) => (a.affine(q) == b.affine(q));
+ } else {
+ return (a,b) => a == b;
+ }
+ };
+
+ // Square
+ wBigInt.genSquare = (q) => {
+ if (q) {
+ return (a) => (a*a) %q;
+ } else {
+ return (a) => a*a;
+ }
+ };
+
+
+ // Double
+ wBigInt.genDouble = (q) => {
+ if (q) {
+ return (a) => (a+a) %q;
+ } else {
+ return (a) => a+a;
+ }
+ };
+
+ // IsZero
+ wBigInt.genIsZero = (q) => {
+ if (q) {
+ return (a) => (a.affine(q) == wBigInt.zero);
+ } else {
+ return (a) => a == wBigInt.zero;
+ }
+ };
+
+
+ // Other minor functions
+ wBigInt.prototype.isOdd = function() {
+ return (this & wBigInt.one) == wBigInt(1);
+ };
+
+ wBigInt.prototype.isNegative = function() {
+ return this < wBigInt.zero;
+ };
+
+ wBigInt.prototype.and = function(m) {
+ return this & m;
+ };
+
+ wBigInt.prototype.div = function(c) {
+ return this / c;
+ };
+
+ wBigInt.prototype.mod = function(c) {
+ return this % c;
+ };
+
+ wBigInt.prototype.modPow = function(e, m) {
+ let acc = wBigInt.one;
+ let exp = this;
+ let rem = e;
+ while (rem) {
+ if (rem & wBigInt.one) {
+ acc = (acc * exp) %m;
+ }
+ exp = (exp * exp) % m;
+ rem = rem >> wBigInt.one;
+ }
+ return acc;
+ };
+
+ wBigInt.prototype.greaterOrEquals = function(b) {
+ return this >= b;
+ };
+
+ wBigInt.prototype.greater = function(b) {
+ return this > b;
+ };
+ wBigInt.prototype.gt = wBigInt.prototype.greater;
+
+ wBigInt.prototype.lesserOrEquals = function(b) {
+ return this <= b;
+ };
+
+ wBigInt.prototype.lesser = function(b) {
+ return this < b;
+ };
+ wBigInt.prototype.lt = wBigInt.prototype.lesser;
+
+ wBigInt.prototype.equals = function(b) {
+ return this == b;
+ };
+ wBigInt.prototype.eq = wBigInt.prototype.equals;
+
+ wBigInt.prototype.neq = function(b) {
+ return this != b;
+ };
+
+} else {
+
+ var oldProto = bigInt.prototype;
+ wBigInt = function(a) {
+ if ((typeof a == "string") && (a.slice(0,2) == "0x")) {
+ return bigInt(a.slice(2), 16);
+ } else {
+ return bigInt(a);
+ }
+ };
+ wBigInt.one = bigInt.one;
+ wBigInt.zero = bigInt.zero;
+ wBigInt.prototype = oldProto;
+
+ wBigInt.prototype.div = function(c) {
+ return this.divide(c);
+ };
+
+ // Affine
+ wBigInt.genAffine = (q) => {
+ const nq = wBigInt.zero.minus(q);
+ return (a) => {
+ let aux = a;
+ if (aux.isNegative()) {
+ if (aux.lesserOrEquals(nq)) {
+ aux = aux.mod(q);
+ }
+ if (aux.isNegative()) {
+ aux = aux.add(q);
+ }
+ } else {
+ if (aux.greaterOrEquals(q)) {
+ aux = aux.mod(q);
+ }
+ }
+ return aux;
+ };
+ };
+
+
+ // Inverse
+ wBigInt.genInverse = (q) => {
+ return (a) => a.affine(q).modInv(q);
+ };
+
+ // Add
+ wBigInt.genAdd = (q) => {
+ if (q) {
+ return (a,b) => {
+ const r = a.add(b);
+ return r.greaterOrEquals(q) ? r.minus(q) : r;
+ };
+ } else {
+ return (a,b) => a.add(b);
+ }
+ };
+
+ // Sub
+ wBigInt.genSub = (q) => {
+ if (q) {
+ return (a,b) => a.greaterOrEquals(b) ? a.minus(b) : a.minus(b).add(q);
+ } else {
+ return (a,b) => a.minus(b);
+ }
+ };
+
+ wBigInt.genNeg = (q) => {
+ if (q) {
+ return (a) => a.isZero() ? a : q.minus(a);
+ } else {
+ return (a) => wBigInt.zero.minus(a);
+ }
+ };
+
+ // Mul
+ wBigInt.genMul = (q) => {
+ if (q) {
+ return (a,b) => a.times(b).mod(q);
+ } else {
+ return (a,b) => a.times(b);
+ }
+ };
+
+ // Shr
+ wBigInt.genShr = () => {
+ return (a,b) => a.shiftRight(wBigInt(b).value);
+ };
+
+ // Shr
+ wBigInt.genShl = (q) => {
+ if (q) {
+ return (a,b) => a.shiftLeft(wBigInt(b).value).mod(q);
+ } else {
+ return (a,b) => a.shiftLeft(wBigInt(b).value);
+ }
+ };
+
+ // Square
+ wBigInt.genSquare = (q) => {
+ if (q) {
+ return (a) => a.square().mod(q);
+ } else {
+ return (a) => a.square();
+ }
+ };
+
+ // Double
+ wBigInt.genDouble = (q) => {
+ if (q) {
+ return (a) => a.add(a).mod(q);
+ } else {
+ return (a) => a.add(a);
+ }
+ };
+
+ // Equals
+ wBigInt.genEquals = (q) => {
+ if (q) {
+ return (a,b) => a.affine(q).equals(b.affine(q));
+ } else {
+ return (a,b) => a.equals(b);
+ }
+ };
+
+ // IsZero
+ wBigInt.genIsZero = (q) => {
+ if (q) {
+ return (a) => (a.affine(q).isZero());
+ } else {
+ return (a) => a.isZero();
+ }
+ };
+}
+
+
+
+wBigInt.affine = function(a, q) {
+ return wBigInt.genAffine(q)(a);
+};
+
+wBigInt.prototype.affine = function (q) {
+ return wBigInt.affine(this, q);
+};
+
+wBigInt.inverse = function(a, q) {
+ return wBigInt.genInverse(q)(a);
+};
+
+wBigInt.prototype.inverse = function (q) {
+ return wBigInt.genInverse(q)(this);
+};
+
+wBigInt.add = function(a, b, q) {
+ return wBigInt.genAdd(q)(a,b);
+};
+
+wBigInt.prototype.add = function (a, q) {
+ return wBigInt.genAdd(q)(this, a);
+};
+
+wBigInt.sub = function(a, b, q) {
+ return wBigInt.genSub(q)(a,b);
+};
+
+wBigInt.prototype.sub = function (a, q) {
+ return wBigInt.genSub(q)(this, a);
+};
+
+wBigInt.neg = function(a, q) {
+ return wBigInt.genNeg(q)(a);
+};
+
+wBigInt.prototype.neg = function (q) {
+ return wBigInt.genNeg(q)(this);
+};
+
+wBigInt.mul = function(a, b, q) {
+ return wBigInt.genMul(q)(a,b);
+};
+
+wBigInt.prototype.mul = function (a, q) {
+ return wBigInt.genMul(q)(this, a);
+};
+
+wBigInt.shr = function(a, b, q) {
+ return wBigInt.genShr(q)(a,b);
+};
+
+wBigInt.prototype.shr = function (a, q) {
+ return wBigInt.genShr(q)(this, a);
+};
+
+wBigInt.shl = function(a, b, q) {
+ return wBigInt.genShl(q)(a,b);
+};
+
+wBigInt.prototype.shl = function (a, q) {
+ return wBigInt.genShl(q)(this, a);
+};
+
+wBigInt.equals = function(a, b, q) {
+ return wBigInt.genEquals(q)(a,b);
+};
+
+wBigInt.prototype.equals = function (a, q) {
+ return wBigInt.genEquals(q)(this, a);
+};
+
+wBigInt.square = function(a, q) {
+ return wBigInt.genSquare(q)(a);
+};
+
+wBigInt.prototype.square = function (q) {
+ return wBigInt.genSquare(q)(this);
+};
+
+wBigInt.double = function(a, q) {
+ return wBigInt.genDouble(q)(a);
+};
+
+wBigInt.prototype.double = function (q) {
+ return wBigInt.genDouble(q)(this);
+};
+
+wBigInt.isZero = function(a, q) {
+ return wBigInt.genIsZero(q)(a);
+};
+
+wBigInt.prototype.isZero = function (q) {
+ return wBigInt.genIsZero(q)(this);
+};
+
+wBigInt.leBuff2int = function(buff) {
+ let res = wBigInt.zero;
+ for (let i=0; i.
+*/
+
+const bigInt = require("./bigint");
+
+module.exports = calculateWitness;
+
+function calculateWitness(circuit, inputSignals, log) {
+ log = log || (() => {});
+ const ctx = new RTCtx(circuit, log);
+
+ function iterateSelector(values, sels, cb) {
+ if (!Array.isArray(values)) {
+ return cb(sels, values);
+ }
+ for (let i=0; i " + ctx.witness[i].toString());
+ }
+ return ctx.witness.slice(0, circuit.nVars);
+// return ctx.witness;
+}
+
+class RTCtx {
+ constructor(circuit, log) {
+ this.log = log || function() {};
+ this.scopes = [];
+ this.circuit = circuit;
+ this.witness = new Array(circuit.nSignals);
+ this.notInitSignals = {};
+ for (let c in this.circuit.components) {
+ this.notInitSignals[c] = this.circuit.components[c].inputSignals;
+ }
+ }
+
+ _sels2str(sels) {
+ let res = "";
+ for (let i=0; i {
+ if (this.notInitSignals[c] == 0) this.triggerComponent(c);
+ });
+ return this.witness[sId];
+ }
+
+ setVar(name, sels, value) {
+ function setVarArray(a, sels2, value) {
+ if (sels2.length == 1) {
+ a[sels2[0]] = value;
+ } else {
+ if (typeof(a[sels2[0]]) == "undefined") a[sels2[0]] = [];
+ setVarArray(a[sels2[0]], sels2.slice(1), value);
+ }
+ }
+ const scope = this.scopes[this.scopes.length-1];
+ if (sels.length == 0) {
+ scope[name] = value;
+ } else {
+ if (typeof(scope[name]) == "undefined") scope[name] = [];
+ setVarArray(scope[name], sels, value);
+ }
+ return value;
+ }
+
+ getVar(name, sels) {
+ function select(a, sels2) {
+ return (sels2.length == 0) ? a : select(a[sels2[0]], sels2.slice(1));
+ }
+ for (let i=this.scopes.length-1; i>=0; i--) {
+ if (typeof(this.scopes[i][name]) != "undefined") return select(this.scopes[i][name], sels);
+ }
+ throw new Error("Variable not defined: " + name);
+ }
+
+ getSignal(name, sels) {
+ let fullName = name=="one" ? "one" : this.currentComponent + "." + name;
+ fullName += this._sels2str(sels);
+ return this.getSignalFullName(fullName);
+ }
+
+
+ getPin(componentName, componentSels, signalName, signalSels) {
+ let fullName = componentName=="one" ? "one" : this.currentComponent + "." + componentName;
+ fullName += this._sels2str(componentSels) +
+ "."+
+ signalName+
+ this._sels2str(signalSels);
+ return this.getSignalFullName(fullName);
+ }
+
+ getSignalFullName(fullName) {
+ const sId = this.circuit.getSignalIdx(fullName);
+ if (typeof(this.witness[sId]) == "undefined") {
+ throw new Error("Signal not initialized: "+fullName);
+ }
+ this.log("get --->" + fullName + " = " + this.witness[sId].toString() );
+ return this.witness[sId];
+ }
+
+ assert(a,b) {
+ const ba = bigInt(a);
+ const bb = bigInt(b);
+ if (!ba.equals(bb)) {
+ throw new Error("Constraint doesn't match: " + ba.toString() + " != " + bb.toString());
+ }
+ }
+}
+
+},{"./bigint":13}],15:[function(require,module,exports){
+/*
+ Copyright 2018 0kims association.
+
+ This file is part of snarkjs.
+
+ snarkjs is a free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ snarkjs is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ snarkjs. If not, see .
+*/
+
+const bigInt = require("./bigint.js");
+
+const __P__ = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
+const __MASK__ = bigInt("28948022309329048855892746252171976963317496166410141009864396001978282409983"); // 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+const calculateWitness = require("./calculateWitness.js");
+
+module.exports = class Circuit {
+ constructor(circuitDef) {
+ this.nPubInputs = circuitDef.nPubInputs;
+ this.nPrvInputs = circuitDef.nPrvInputs;
+ this.nInputs = circuitDef.nInputs;
+ this.nOutputs = circuitDef.nOutputs;
+ this.nVars = circuitDef.nVars;
+ this.nSignals = circuitDef.nSignals;
+ this.nConstants = circuitDef.nConstants;
+
+ this.nConstraints = circuitDef.constraints.length;
+
+ this.signalName2Idx = circuitDef.signalName2Idx;
+ this.components = circuitDef.components;
+ this.componentName2Idx = circuitDef.componentName2Idx;
+ this.signals = circuitDef.signals;
+ this.constraints = circuitDef.constraints;
+
+ this.templates = {};
+ for (let t in circuitDef.templates) {
+ this.templates[t] = eval(" const __f= " +circuitDef.templates[t] + "\n__f");
+ }
+
+ this.functions = {};
+ for (let f in circuitDef.functions) {
+ this.functions[f] = {
+ params: circuitDef.functions[f].params,
+ func: eval(" const __f= " +circuitDef.functions[f].func + "\n__f;")
+ };
+ }
+ }
+
+ calculateWitness(input, log) {
+ return calculateWitness(this, input, log);
+ }
+
+ checkWitness(w) {
+ const evalLC = (lc, w) => {
+ let acc = bigInt(0);
+ for (let k in lc) {
+ acc= acc.add(bigInt(w[k]).mul(bigInt(lc[k]))).mod(__P__);
+ }
+ return acc;
+ }
+
+ const checkConstraint = (ct, w) => {
+ const a=evalLC(ct[0],w);
+ const b=evalLC(ct[1],w);
+ const c=evalLC(ct[2],w);
+ const res = (a.mul(b).sub(c)).affine(__P__);
+ if (!res.isZero()) return false;
+ return true;
+ }
+
+
+ for (let i=0; i {
+ let S = "";
+ for (let k in lc) {
+ let name = this.signals[k].names[0];
+ if (name == "one") name = "";
+ let v = bigInt(lc[k]);
+ let vs;
+ if (!v.lesserOrEquals(__P__.shr(bigInt(1)))) {
+ v = __P__.sub(v);
+ vs = "-"+v.toString();
+ } else {
+ if (S!="") {
+ vs = "+"+v.toString();
+ } else {
+ vs = "";
+ }
+ if (vs!="1") {
+ vs = vs + v.toString();;
+ }
+ }
+
+ S= S + " " + vs + name;
+ }
+ return S;
+ };
+ const S = `[ ${lc2str(c[0])} ] * [ ${lc2str(c[1])} ] - [ ${lc2str(c[2])} ] = 0`;
+ console.log(S);
+ }
+
+ printConstraints() {
+ for (let i=0; i=this.nOutputs) throw new Error("Accessing an invalid output: "+i);
+ return i+1;
+ }
+
+ // returns the index of the i'th input
+ inputIdx(i) {
+ if (i>=this.nInputs) throw new Error("Accessing an invalid input: "+i);
+ return this.nOutputs + 1 + i;
+ }
+
+ // returns the index of the i'th public input
+ pubInputIdx(i) {
+ if (i>=this.nPubInputs) throw new Error("Accessing an invalid pubInput: "+i);
+ return this.inputIdx(i);
+ }
+
+ // returns the index of the i'th private input
+ prvInputIdx(i) {
+ if (i>=this.nPrvInputs) throw new Error("Accessing an invalid prvInput: "+i);
+ return this.inputIdx(this.nPubInputs + i);
+ }
+
+ // returns the index of the i'th variable
+ varIdx(i) {
+ if (i>=this.nVars) throw new Error("Accessing an invalid variable: "+i);
+ return i;
+ }
+
+ // returns the index of the i'th constant
+ constantIdx(i) {
+ if (i>=this.nConstants) throw new Error("Accessing an invalid constant: "+i);
+ return this.nVars + i;
+ }
+
+ // returns the index of the i'th signal
+ signalIdx(i) {
+ if (i>=this.nSignls) throw new Error("Accessing an invalid signal: "+i);
+ return i;
+ }
+
+ signalNames(i) {
+ return this.signals[ this.getSignalIdx(i) ].names.join(", ");
+ }
+
+ a(constraint, signalIdx) {
+ return bigInt(this.constraints[constraint][0][signalIdx] || 0 );
+ }
+
+ b(constraint, signalIdx) {
+ return bigInt(this.constraints[constraint][1][signalIdx] || 0);
+ }
+
+ c(constraint, signalIdx) {
+ return bigInt(this.constraints[constraint][2][signalIdx] || 0);
+ }
+};
+
+},{"./bigint.js":13,"./calculateWitness.js":14}],16:[function(require,module,exports){
+/*
+ Copyright 2018 0kims association.
+
+ This file is part of snarkjs.
+
+ snarkjs is a free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ snarkjs is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ snarkjs. If not, see .
+*/
+
+const bigInt = require("./bigint.js");
+
+module.exports.stringifyBigInts = stringifyBigInts;
+module.exports.unstringifyBigInts = unstringifyBigInts;
+
+function stringifyBigInts(o) {
+ if ((typeof(o) == "bigint") || (o instanceof bigInt)) {
+ return o.toString(10);
+ } else if (Array.isArray(o)) {
+ return o.map(stringifyBigInts);
+ } else if (typeof o == "object") {
+ const res = {};
+ for (let k in o) {
+ res[k] = stringifyBigInts(o[k]);
+ }
+ return res;
+ } else {
+ return o;
+ }
+}
+
+function unstringifyBigInts(o) {
+ if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
+ return bigInt(o);
+ } else if (Array.isArray(o)) {
+ return o.map(unstringifyBigInts);
+ } else if (typeof o == "object") {
+ const res = {};
+ for (let k in o) {
+ res[k] = unstringifyBigInts(o[k]);
+ }
+ return res;
+ } else {
+ return o;
+ }
+}
+
+},{"./bigint.js":13}],17:[function(require,module,exports){
(function (process){
/*
Copyright 2019 0KIMS association.
@@ -5542,4 +6523,175 @@ class Groth16 {
module.exports = build;
}).call(this,require('_process'))
-},{"../build/groth16_wasm.js":1,"_process":12,"assert":3,"big-integer":8,"crypto":undefined,"worker_threads":undefined}]},{},[2]);
+},{"../build/groth16_wasm.js":1,"_process":12,"assert":3,"big-integer":8,"crypto":undefined,"worker_threads":undefined}],18:[function(require,module,exports){
+/*
+ Copyright 2019 0KIMS association.
+
+ This file is part of websnark (Web Assembly zkSnark Prover).
+
+ websnark is a free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ websnark is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with websnark. If not, see .
+*/
+
+const bigInt = require("big-integer");
+const Circuit = require("snarkjs/src/circuit");
+const bigInt2 = require("snarkjs/src/bigint");
+const hexifyBigInts = require("../tools/stringifybigint").hexifyBigInts;
+const unstringifyBigInts = require("../tools/stringifybigint").unstringifyBigInts;
+const stringifyBigInts2 = require("snarkjs/src/stringifybigint").stringifyBigInts;
+const unstringifyBigInts2 = require("snarkjs/src/stringifybigint").unstringifyBigInts;
+
+function bigInt2BytesLE(_a, len) {
+ const b = Array(len);
+ let v = bigInt(_a);
+ for (let i=0; i.
+*/
+
+const bigInt = require("big-integer");
+
+module.exports.stringifyBigInts = stringifyBigInts;
+module.exports.unstringifyBigInts = unstringifyBigInts;
+module.exports.hexifyBigInts = hexifyBigInts;
+
+function stringifyBigInts(o) {
+ if ((typeof(o) == "bigint") || (o instanceof bigInt)) {
+ return o.toString(10);
+ } else if (Array.isArray(o)) {
+ return o.map(stringifyBigInts);
+ } else if (typeof o == "object") {
+ const res = {};
+ for (let k in o) {
+ res[k] = stringifyBigInts(o[k]);
+ }
+ return res;
+ } else {
+ return o;
+ }
+}
+
+function unstringifyBigInts(o) {
+ if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
+ return bigInt(o);
+ } else if (Array.isArray(o)) {
+ return o.map(unstringifyBigInts);
+ } else if (typeof o == "object" && !(o instanceof bigInt)) {
+ const res = {};
+ for (let k in o) {
+ res[k] = unstringifyBigInts(o[k]);
+ }
+ return res;
+ } else {
+ return o;
+ }
+}
+
+function hexifyBigInts(o) {
+ if (typeof (o) === "bigInt" || (o instanceof bigInt)) {
+ let str = o.toString(16);
+ while (str.length < 64) str = "0" + str;
+ str = "0x" + str;
+ return str;
+ } else if (Array.isArray(o)) {
+ return o.map(hexifyBigInts);
+ } else if (typeof o == "object") {
+ const res = {};
+ for (let k in o) {
+ res[k] = hexifyBigInts(o[k]);
+ }
+ return res;
+ } else {
+ return o;
+ }
+}
+
+},{"big-integer":8}]},{},[2]);
diff --git a/main.js b/main.js
index 042a1d7..6239270 100644
--- a/main.js
+++ b/main.js
@@ -19,16 +19,17 @@
/* globals window */
-const buildGroth16 = require("./src/groth16.js");
+const buildGroth16 = require("./src/groth16");
+const utils = require("./src/utils");
-buildGroth16().then( (groth16) => {
+buildGroth16().then((groth16) => {
window.groth16 = groth16;
- window.genZKSnarkProof = function(witness, provingKey, cb) {
-
- const p = groth16.proof(witness, provingKey);
+ window.zkSnarkProofToSolidityInput = utils.toSolidityInput;
+ window.genZKSnarkProofAndWitness = function (input, circuitJson, provingKey, cb) {
+ const p = utils.genWitnessAndProve(groth16, input, circuitJson, provingKey);
if (cb) {
- p.then( (proof) => {
+ p.then((proof) => {
cb(null, proof);
}, (err) => {
cb(err);
@@ -37,6 +38,17 @@ buildGroth16().then( (groth16) => {
return p;
}
};
-});
-
+ window.genZKSnarkProof = function (witness, provingKey, cb) {
+ const p = groth16.proof(witness, provingKey);
+ if (cb) {
+ p.then((proof) => {
+ cb(null, proof);
+ }, (err) => {
+ cb(err);
+ });
+ } else {
+ return p;
+ }
+ };
+});
\ No newline at end of file
diff --git a/src/utils.js b/src/utils.js
index b5701ba..bd1338e 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -18,8 +18,14 @@
*/
const bigInt = require("big-integer");
+const Circuit = require("snarkjs/src/circuit");
+const bigInt2 = require("snarkjs/src/bigint");
+const hexifyBigInts = require("../tools/stringifybigint").hexifyBigInts;
+const unstringifyBigInts = require("../tools/stringifybigint").unstringifyBigInts;
+const stringifyBigInts2 = require("snarkjs/src/stringifybigint").stringifyBigInts;
+const unstringifyBigInts2 = require("snarkjs/src/stringifybigint").unstringifyBigInts;
-exports.bigInt2BytesLE = function bigInt2BytesLE(_a, len) {
+function bigInt2BytesLE(_a, len) {
const b = Array(len);
let v = bigInt(_a);
for (let i=0; i