mirror of
https://github.com/Instadapp/Swap-Aggregator-Subgraph.git
synced 2024-07-29 21:57:12 +00:00
559 lines
21 KiB
JavaScript
Executable File
559 lines
21 KiB
JavaScript
Executable File
var __extends = (this && this.__extends) || (function () {
|
|
var extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
|
return function (d, b) {
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
})();
|
|
import { bigint_asm } from './bigint.asm';
|
|
import { string_to_bytes } from '../other/utils';
|
|
import { IllegalArgumentError } from '../other/errors';
|
|
import { BigNumber_extGCD, Number_extGCD } from './extgcd';
|
|
import { getRandomValues } from '../other/get-random-values';
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
export var _bigint_stdlib = { Uint32Array: Uint32Array, Math: Math };
|
|
export var _bigint_heap = new Uint32Array(0x100000);
|
|
export var _bigint_asm;
|
|
function _half_imul(a, b) {
|
|
return (a * b) | 0;
|
|
}
|
|
if (_bigint_stdlib.Math.imul === undefined) {
|
|
_bigint_stdlib.Math.imul = _half_imul;
|
|
_bigint_asm = bigint_asm(_bigint_stdlib, null, _bigint_heap.buffer);
|
|
delete _bigint_stdlib.Math.imul;
|
|
}
|
|
else {
|
|
_bigint_asm = bigint_asm(_bigint_stdlib, null, _bigint_heap.buffer);
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
var _BigNumber_ZERO_limbs = new Uint32Array(0);
|
|
var BigNumber = /** @class */ (function () {
|
|
function BigNumber(num) {
|
|
var limbs = _BigNumber_ZERO_limbs;
|
|
var bitlen = 0;
|
|
var sign = 0;
|
|
if (num === undefined) {
|
|
// do nothing
|
|
}
|
|
else {
|
|
for (var i = 0; !num[i]; i++)
|
|
;
|
|
bitlen = (num.length - i) * 8;
|
|
if (!bitlen)
|
|
return BigNumber.ZERO;
|
|
limbs = new Uint32Array((bitlen + 31) >> 5);
|
|
for (var j = num.length - 4; j >= i; j -= 4) {
|
|
limbs[(num.length - 4 - j) >> 2] = (num[j] << 24) | (num[j + 1] << 16) | (num[j + 2] << 8) | num[j + 3];
|
|
}
|
|
if (i - j === 3) {
|
|
limbs[limbs.length - 1] = num[i];
|
|
}
|
|
else if (i - j === 2) {
|
|
limbs[limbs.length - 1] = (num[i] << 8) | num[i + 1];
|
|
}
|
|
else if (i - j === 1) {
|
|
limbs[limbs.length - 1] = (num[i] << 16) | (num[i + 1] << 8) | num[i + 2];
|
|
}
|
|
sign = 1;
|
|
}
|
|
this.limbs = limbs;
|
|
this.bitLength = bitlen;
|
|
this.sign = sign;
|
|
}
|
|
BigNumber.fromString = function (str) {
|
|
var bytes = string_to_bytes(str);
|
|
return new BigNumber(bytes);
|
|
};
|
|
BigNumber.fromNumber = function (num) {
|
|
var limbs = _BigNumber_ZERO_limbs;
|
|
var bitlen = 0;
|
|
var sign = 0;
|
|
var absnum = Math.abs(num);
|
|
if (absnum > 0xffffffff) {
|
|
limbs = new Uint32Array(2);
|
|
limbs[0] = absnum | 0;
|
|
limbs[1] = (absnum / 0x100000000) | 0;
|
|
bitlen = 52;
|
|
}
|
|
else if (absnum > 0) {
|
|
limbs = new Uint32Array(1);
|
|
limbs[0] = absnum;
|
|
bitlen = 32;
|
|
}
|
|
else {
|
|
limbs = _BigNumber_ZERO_limbs;
|
|
bitlen = 0;
|
|
}
|
|
sign = num < 0 ? -1 : 1;
|
|
return BigNumber.fromConfig({ limbs: limbs, bitLength: bitlen, sign: sign });
|
|
};
|
|
BigNumber.fromArrayBuffer = function (buffer) {
|
|
return new BigNumber(new Uint8Array(buffer));
|
|
};
|
|
BigNumber.fromConfig = function (obj) {
|
|
var bn = new BigNumber();
|
|
bn.limbs = new Uint32Array(obj.limbs);
|
|
bn.bitLength = obj.bitLength;
|
|
bn.sign = obj.sign;
|
|
return bn;
|
|
};
|
|
BigNumber.prototype.toString = function (radix) {
|
|
radix = radix || 16;
|
|
var limbs = this.limbs;
|
|
var bitlen = this.bitLength;
|
|
var str = '';
|
|
if (radix === 16) {
|
|
// FIXME clamp last limb to (bitlen % 32)
|
|
for (var i = ((bitlen + 31) >> 5) - 1; i >= 0; i--) {
|
|
var h = limbs[i].toString(16);
|
|
str += '00000000'.substr(h.length);
|
|
str += h;
|
|
}
|
|
str = str.replace(/^0+/, '');
|
|
if (!str.length)
|
|
str = '0';
|
|
}
|
|
else {
|
|
throw new IllegalArgumentError('bad radix');
|
|
}
|
|
if (this.sign < 0)
|
|
str = '-' + str;
|
|
return str;
|
|
};
|
|
BigNumber.prototype.toBytes = function () {
|
|
var bitlen = this.bitLength;
|
|
var limbs = this.limbs;
|
|
if (bitlen === 0)
|
|
return new Uint8Array(0);
|
|
var bytelen = (bitlen + 7) >> 3;
|
|
var bytes = new Uint8Array(bytelen);
|
|
for (var i = 0; i < bytelen; i++) {
|
|
var j = bytelen - i - 1;
|
|
bytes[i] = limbs[j >> 2] >> ((j & 3) << 3);
|
|
}
|
|
return bytes;
|
|
};
|
|
/**
|
|
* Downgrade to Number
|
|
*/
|
|
BigNumber.prototype.valueOf = function () {
|
|
var limbs = this.limbs;
|
|
var bits = this.bitLength;
|
|
var sign = this.sign;
|
|
if (!sign)
|
|
return 0;
|
|
if (bits <= 32)
|
|
return sign * (limbs[0] >>> 0);
|
|
if (bits <= 52)
|
|
return sign * (0x100000000 * (limbs[1] >>> 0) + (limbs[0] >>> 0));
|
|
// normalization
|
|
var i, l, e = 0;
|
|
for (i = limbs.length - 1; i >= 0; i--) {
|
|
if ((l = limbs[i]) === 0)
|
|
continue;
|
|
while (((l << e) & 0x80000000) === 0)
|
|
e++;
|
|
break;
|
|
}
|
|
if (i === 0)
|
|
return sign * (limbs[0] >>> 0);
|
|
return (sign *
|
|
(0x100000 * (((limbs[i] << e) | (e ? limbs[i - 1] >>> (32 - e) : 0)) >>> 0) +
|
|
(((limbs[i - 1] << e) | (e && i > 1 ? limbs[i - 2] >>> (32 - e) : 0)) >>> 12)) *
|
|
Math.pow(2, 32 * i - e - 52));
|
|
};
|
|
BigNumber.prototype.clamp = function (b) {
|
|
var limbs = this.limbs;
|
|
var bitlen = this.bitLength;
|
|
// FIXME check b is number and in a valid range
|
|
if (b >= bitlen)
|
|
return this;
|
|
var clamped = new BigNumber();
|
|
var n = (b + 31) >> 5;
|
|
var k = b % 32;
|
|
clamped.limbs = new Uint32Array(limbs.subarray(0, n));
|
|
clamped.bitLength = b;
|
|
clamped.sign = this.sign;
|
|
if (k)
|
|
clamped.limbs[n - 1] &= -1 >>> (32 - k);
|
|
return clamped;
|
|
};
|
|
BigNumber.prototype.slice = function (f, b) {
|
|
var limbs = this.limbs;
|
|
var bitlen = this.bitLength;
|
|
if (f < 0)
|
|
throw new RangeError('TODO');
|
|
if (f >= bitlen)
|
|
return BigNumber.ZERO;
|
|
if (b === undefined || b > bitlen - f)
|
|
b = bitlen - f;
|
|
var sliced = new BigNumber();
|
|
var n = f >> 5;
|
|
var m = (f + b + 31) >> 5;
|
|
var l = (b + 31) >> 5;
|
|
var t = f % 32;
|
|
var k = b % 32;
|
|
var slimbs = new Uint32Array(l);
|
|
if (t) {
|
|
for (var i = 0; i < m - n - 1; i++) {
|
|
slimbs[i] = (limbs[n + i] >>> t) | (limbs[n + i + 1] << (32 - t));
|
|
}
|
|
slimbs[i] = limbs[n + i] >>> t;
|
|
}
|
|
else {
|
|
slimbs.set(limbs.subarray(n, m));
|
|
}
|
|
if (k) {
|
|
slimbs[l - 1] &= -1 >>> (32 - k);
|
|
}
|
|
sliced.limbs = slimbs;
|
|
sliced.bitLength = b;
|
|
sliced.sign = this.sign;
|
|
return sliced;
|
|
};
|
|
BigNumber.prototype.negate = function () {
|
|
var negative = new BigNumber();
|
|
negative.limbs = this.limbs;
|
|
negative.bitLength = this.bitLength;
|
|
negative.sign = -1 * this.sign;
|
|
return negative;
|
|
};
|
|
BigNumber.prototype.compare = function (that) {
|
|
var alimbs = this.limbs, alimbcnt = alimbs.length, blimbs = that.limbs, blimbcnt = blimbs.length, z = 0;
|
|
if (this.sign < that.sign)
|
|
return -1;
|
|
if (this.sign > that.sign)
|
|
return 1;
|
|
_bigint_heap.set(alimbs, 0);
|
|
_bigint_heap.set(blimbs, alimbcnt);
|
|
z = _bigint_asm.cmp(0, alimbcnt << 2, alimbcnt << 2, blimbcnt << 2);
|
|
return z * this.sign;
|
|
};
|
|
BigNumber.prototype.add = function (that) {
|
|
if (!this.sign)
|
|
return that;
|
|
if (!that.sign)
|
|
return this;
|
|
var abitlen = this.bitLength, alimbs = this.limbs, alimbcnt = alimbs.length, asign = this.sign, bbitlen = that.bitLength, blimbs = that.limbs, blimbcnt = blimbs.length, bsign = that.sign, rbitlen, rlimbcnt, rsign, rof, result = new BigNumber();
|
|
rbitlen = (abitlen > bbitlen ? abitlen : bbitlen) + (asign * bsign > 0 ? 1 : 0);
|
|
rlimbcnt = (rbitlen + 31) >> 5;
|
|
_bigint_asm.sreset();
|
|
var pA = _bigint_asm.salloc(alimbcnt << 2), pB = _bigint_asm.salloc(blimbcnt << 2), pR = _bigint_asm.salloc(rlimbcnt << 2);
|
|
_bigint_asm.z(pR - pA + (rlimbcnt << 2), 0, pA);
|
|
_bigint_heap.set(alimbs, pA >> 2);
|
|
_bigint_heap.set(blimbs, pB >> 2);
|
|
if (asign * bsign > 0) {
|
|
_bigint_asm.add(pA, alimbcnt << 2, pB, blimbcnt << 2, pR, rlimbcnt << 2);
|
|
rsign = asign;
|
|
}
|
|
else if (asign > bsign) {
|
|
rof = _bigint_asm.sub(pA, alimbcnt << 2, pB, blimbcnt << 2, pR, rlimbcnt << 2);
|
|
rsign = rof ? bsign : asign;
|
|
}
|
|
else {
|
|
rof = _bigint_asm.sub(pB, blimbcnt << 2, pA, alimbcnt << 2, pR, rlimbcnt << 2);
|
|
rsign = rof ? asign : bsign;
|
|
}
|
|
if (rof)
|
|
_bigint_asm.neg(pR, rlimbcnt << 2, pR, rlimbcnt << 2);
|
|
if (_bigint_asm.tst(pR, rlimbcnt << 2) === 0)
|
|
return BigNumber.ZERO;
|
|
result.limbs = new Uint32Array(_bigint_heap.subarray(pR >> 2, (pR >> 2) + rlimbcnt));
|
|
result.bitLength = rbitlen;
|
|
result.sign = rsign;
|
|
return result;
|
|
};
|
|
BigNumber.prototype.subtract = function (that) {
|
|
return this.add(that.negate());
|
|
};
|
|
BigNumber.prototype.square = function () {
|
|
if (!this.sign)
|
|
return BigNumber.ZERO;
|
|
var abitlen = this.bitLength, alimbs = this.limbs, alimbcnt = alimbs.length, rbitlen, rlimbcnt, result = new BigNumber();
|
|
rbitlen = abitlen << 1;
|
|
rlimbcnt = (rbitlen + 31) >> 5;
|
|
_bigint_asm.sreset();
|
|
var pA = _bigint_asm.salloc(alimbcnt << 2), pR = _bigint_asm.salloc(rlimbcnt << 2);
|
|
_bigint_asm.z(pR - pA + (rlimbcnt << 2), 0, pA);
|
|
_bigint_heap.set(alimbs, pA >> 2);
|
|
_bigint_asm.sqr(pA, alimbcnt << 2, pR);
|
|
result.limbs = new Uint32Array(_bigint_heap.subarray(pR >> 2, (pR >> 2) + rlimbcnt));
|
|
result.bitLength = rbitlen;
|
|
result.sign = 1;
|
|
return result;
|
|
};
|
|
BigNumber.prototype.divide = function (that) {
|
|
var abitlen = this.bitLength, alimbs = this.limbs, alimbcnt = alimbs.length, bbitlen = that.bitLength, blimbs = that.limbs, blimbcnt = blimbs.length, qlimbcnt, rlimbcnt, quotient = BigNumber.ZERO, remainder = BigNumber.ZERO;
|
|
_bigint_asm.sreset();
|
|
var pA = _bigint_asm.salloc(alimbcnt << 2), pB = _bigint_asm.salloc(blimbcnt << 2), pQ = _bigint_asm.salloc(alimbcnt << 2);
|
|
_bigint_asm.z(pQ - pA + (alimbcnt << 2), 0, pA);
|
|
_bigint_heap.set(alimbs, pA >> 2);
|
|
_bigint_heap.set(blimbs, pB >> 2);
|
|
_bigint_asm.div(pA, alimbcnt << 2, pB, blimbcnt << 2, pQ);
|
|
qlimbcnt = _bigint_asm.tst(pQ, alimbcnt << 2) >> 2;
|
|
if (qlimbcnt) {
|
|
quotient = new BigNumber();
|
|
quotient.limbs = new Uint32Array(_bigint_heap.subarray(pQ >> 2, (pQ >> 2) + qlimbcnt));
|
|
quotient.bitLength = abitlen < qlimbcnt << 5 ? abitlen : qlimbcnt << 5;
|
|
quotient.sign = this.sign * that.sign;
|
|
}
|
|
rlimbcnt = _bigint_asm.tst(pA, blimbcnt << 2) >> 2;
|
|
if (rlimbcnt) {
|
|
remainder = new BigNumber();
|
|
remainder.limbs = new Uint32Array(_bigint_heap.subarray(pA >> 2, (pA >> 2) + rlimbcnt));
|
|
remainder.bitLength = bbitlen < rlimbcnt << 5 ? bbitlen : rlimbcnt << 5;
|
|
remainder.sign = this.sign;
|
|
}
|
|
return {
|
|
quotient: quotient,
|
|
remainder: remainder,
|
|
};
|
|
};
|
|
BigNumber.prototype.multiply = function (that) {
|
|
if (!this.sign || !that.sign)
|
|
return BigNumber.ZERO;
|
|
var abitlen = this.bitLength, alimbs = this.limbs, alimbcnt = alimbs.length, bbitlen = that.bitLength, blimbs = that.limbs, blimbcnt = blimbs.length, rbitlen, rlimbcnt, result = new BigNumber();
|
|
rbitlen = abitlen + bbitlen;
|
|
rlimbcnt = (rbitlen + 31) >> 5;
|
|
_bigint_asm.sreset();
|
|
var pA = _bigint_asm.salloc(alimbcnt << 2), pB = _bigint_asm.salloc(blimbcnt << 2), pR = _bigint_asm.salloc(rlimbcnt << 2);
|
|
_bigint_asm.z(pR - pA + (rlimbcnt << 2), 0, pA);
|
|
_bigint_heap.set(alimbs, pA >> 2);
|
|
_bigint_heap.set(blimbs, pB >> 2);
|
|
_bigint_asm.mul(pA, alimbcnt << 2, pB, blimbcnt << 2, pR, rlimbcnt << 2);
|
|
result.limbs = new Uint32Array(_bigint_heap.subarray(pR >> 2, (pR >> 2) + rlimbcnt));
|
|
result.sign = this.sign * that.sign;
|
|
result.bitLength = rbitlen;
|
|
return result;
|
|
};
|
|
BigNumber.prototype.isMillerRabinProbablePrime = function (rounds) {
|
|
var t = BigNumber.fromConfig(this), s = 0;
|
|
t.limbs[0] -= 1;
|
|
while (t.limbs[s >> 5] === 0)
|
|
s += 32;
|
|
while (((t.limbs[s >> 5] >> (s & 31)) & 1) === 0)
|
|
s++;
|
|
t = t.slice(s);
|
|
var m = new Modulus(this), m1 = this.subtract(BigNumber.ONE), a = BigNumber.fromConfig(this), l = this.limbs.length - 1;
|
|
while (a.limbs[l] === 0)
|
|
l--;
|
|
while (--rounds >= 0) {
|
|
getRandomValues(a.limbs);
|
|
if (a.limbs[0] < 2)
|
|
a.limbs[0] += 2;
|
|
while (a.compare(m1) >= 0)
|
|
a.limbs[l] >>>= 1;
|
|
var x = m.power(a, t);
|
|
if (x.compare(BigNumber.ONE) === 0)
|
|
continue;
|
|
if (x.compare(m1) === 0)
|
|
continue;
|
|
var c = s;
|
|
while (--c > 0) {
|
|
x = x.square().divide(m).remainder;
|
|
if (x.compare(BigNumber.ONE) === 0)
|
|
return false;
|
|
if (x.compare(m1) === 0)
|
|
break;
|
|
}
|
|
if (c === 0)
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
BigNumber.prototype.isProbablePrime = function (paranoia) {
|
|
if (paranoia === void 0) { paranoia = 80; }
|
|
var limbs = this.limbs;
|
|
var i = 0;
|
|
// Oddity test
|
|
// (50% false positive probability)
|
|
if ((limbs[0] & 1) === 0)
|
|
return false;
|
|
if (paranoia <= 1)
|
|
return true;
|
|
// Magic divisors (3, 5, 17) test
|
|
// (~25% false positive probability)
|
|
var s3 = 0, s5 = 0, s17 = 0;
|
|
for (i = 0; i < limbs.length; i++) {
|
|
var l3 = limbs[i];
|
|
while (l3) {
|
|
s3 += l3 & 3;
|
|
l3 >>>= 2;
|
|
}
|
|
var l5 = limbs[i];
|
|
while (l5) {
|
|
s5 += l5 & 3;
|
|
l5 >>>= 2;
|
|
s5 -= l5 & 3;
|
|
l5 >>>= 2;
|
|
}
|
|
var l17 = limbs[i];
|
|
while (l17) {
|
|
s17 += l17 & 15;
|
|
l17 >>>= 4;
|
|
s17 -= l17 & 15;
|
|
l17 >>>= 4;
|
|
}
|
|
}
|
|
if (!(s3 % 3) || !(s5 % 5) || !(s17 % 17))
|
|
return false;
|
|
if (paranoia <= 2)
|
|
return true;
|
|
// Miller-Rabin test
|
|
// (≤ 4^(-k) false positive probability)
|
|
return this.isMillerRabinProbablePrime(paranoia >>> 1);
|
|
};
|
|
BigNumber.extGCD = BigNumber_extGCD;
|
|
BigNumber.ZERO = BigNumber.fromNumber(0);
|
|
BigNumber.ONE = BigNumber.fromNumber(1);
|
|
return BigNumber;
|
|
}());
|
|
export { BigNumber };
|
|
var Modulus = /** @class */ (function (_super) {
|
|
__extends(Modulus, _super);
|
|
function Modulus(number) {
|
|
var _this = _super.call(this) || this;
|
|
_this.limbs = number.limbs;
|
|
_this.bitLength = number.bitLength;
|
|
_this.sign = number.sign;
|
|
if (_this.valueOf() < 1)
|
|
throw new RangeError();
|
|
if (_this.bitLength <= 32)
|
|
return _this;
|
|
var comodulus;
|
|
if (_this.limbs[0] & 1) {
|
|
var bitlen = ((_this.bitLength + 31) & -32) + 1;
|
|
var limbs = new Uint32Array((bitlen + 31) >> 5);
|
|
limbs[limbs.length - 1] = 1;
|
|
comodulus = new BigNumber();
|
|
comodulus.sign = 1;
|
|
comodulus.bitLength = bitlen;
|
|
comodulus.limbs = limbs;
|
|
var k = Number_extGCD(0x100000000, _this.limbs[0]).y;
|
|
_this.coefficient = k < 0 ? -k : 0x100000000 - k;
|
|
}
|
|
else {
|
|
return _this;
|
|
}
|
|
_this.comodulus = comodulus;
|
|
_this.comodulusRemainder = comodulus.divide(_this).remainder;
|
|
_this.comodulusRemainderSquare = comodulus.square().divide(_this).remainder;
|
|
return _this;
|
|
}
|
|
/**
|
|
* Modular reduction
|
|
*/
|
|
Modulus.prototype.reduce = function (a) {
|
|
if (a.bitLength <= 32 && this.bitLength <= 32)
|
|
return BigNumber.fromNumber(a.valueOf() % this.valueOf());
|
|
if (a.compare(this) < 0)
|
|
return a;
|
|
return a.divide(this).remainder;
|
|
};
|
|
/**
|
|
* Modular inverse
|
|
*/
|
|
Modulus.prototype.inverse = function (a) {
|
|
a = this.reduce(a);
|
|
var r = BigNumber_extGCD(this, a);
|
|
if (r.gcd.valueOf() !== 1)
|
|
throw new Error('GCD is not 1');
|
|
if (r.y.sign < 0)
|
|
return r.y.add(this).clamp(this.bitLength);
|
|
return r.y;
|
|
};
|
|
/**
|
|
* Modular exponentiation
|
|
*/
|
|
Modulus.prototype.power = function (g, e) {
|
|
// count exponent set bits
|
|
var c = 0;
|
|
for (var i = 0; i < e.limbs.length; i++) {
|
|
var t = e.limbs[i];
|
|
while (t) {
|
|
if (t & 1)
|
|
c++;
|
|
t >>>= 1;
|
|
}
|
|
}
|
|
// window size parameter
|
|
var k = 8;
|
|
if (e.bitLength <= 4536)
|
|
k = 7;
|
|
if (e.bitLength <= 1736)
|
|
k = 6;
|
|
if (e.bitLength <= 630)
|
|
k = 5;
|
|
if (e.bitLength <= 210)
|
|
k = 4;
|
|
if (e.bitLength <= 60)
|
|
k = 3;
|
|
if (e.bitLength <= 12)
|
|
k = 2;
|
|
if (c <= 1 << (k - 1))
|
|
k = 1;
|
|
// montgomerize base
|
|
g = Modulus._Montgomery_reduce(this.reduce(g).multiply(this.comodulusRemainderSquare), this);
|
|
// precompute odd powers
|
|
var g2 = Modulus._Montgomery_reduce(g.square(), this), gn = new Array(1 << (k - 1));
|
|
gn[0] = g;
|
|
gn[1] = Modulus._Montgomery_reduce(g.multiply(g2), this);
|
|
for (var i = 2; i < 1 << (k - 1); i++) {
|
|
gn[i] = Modulus._Montgomery_reduce(gn[i - 1].multiply(g2), this);
|
|
}
|
|
// perform exponentiation
|
|
var u = this.comodulusRemainder;
|
|
var r = u;
|
|
for (var i = e.limbs.length - 1; i >= 0; i--) {
|
|
var t = e.limbs[i];
|
|
for (var j = 32; j > 0;) {
|
|
if (t & 0x80000000) {
|
|
var n = t >>> (32 - k), l = k;
|
|
while ((n & 1) === 0) {
|
|
n >>>= 1;
|
|
l--;
|
|
}
|
|
var m = gn[n >>> 1];
|
|
while (n) {
|
|
n >>>= 1;
|
|
if (r !== u)
|
|
r = Modulus._Montgomery_reduce(r.square(), this);
|
|
}
|
|
r = r !== u ? Modulus._Montgomery_reduce(r.multiply(m), this) : m;
|
|
(t <<= l), (j -= l);
|
|
}
|
|
else {
|
|
if (r !== u)
|
|
r = Modulus._Montgomery_reduce(r.square(), this);
|
|
(t <<= 1), j--;
|
|
}
|
|
}
|
|
}
|
|
// de-montgomerize result
|
|
return Modulus._Montgomery_reduce(r, this);
|
|
};
|
|
Modulus._Montgomery_reduce = function (a, n) {
|
|
var alimbs = a.limbs;
|
|
var alimbcnt = alimbs.length;
|
|
var nlimbs = n.limbs;
|
|
var nlimbcnt = nlimbs.length;
|
|
var y = n.coefficient;
|
|
_bigint_asm.sreset();
|
|
var pA = _bigint_asm.salloc(alimbcnt << 2), pN = _bigint_asm.salloc(nlimbcnt << 2), pR = _bigint_asm.salloc(nlimbcnt << 2);
|
|
_bigint_asm.z(pR - pA + (nlimbcnt << 2), 0, pA);
|
|
_bigint_heap.set(alimbs, pA >> 2);
|
|
_bigint_heap.set(nlimbs, pN >> 2);
|
|
_bigint_asm.mredc(pA, alimbcnt << 2, pN, nlimbcnt << 2, y, pR);
|
|
var result = new BigNumber();
|
|
result.limbs = new Uint32Array(_bigint_heap.subarray(pR >> 2, (pR >> 2) + nlimbcnt));
|
|
result.bitLength = n.bitLength;
|
|
result.sign = 1;
|
|
return result;
|
|
};
|
|
return Modulus;
|
|
}(BigNumber));
|
|
export { Modulus };
|