|
|
@ -1,9 +1,9 @@ |
|
|
|
(function (exports) { |
|
|
|
'use strict'; |
|
|
|
"use strict"; |
|
|
|
|
|
|
|
// Utils
|
|
|
|
function assert(val, msg) { |
|
|
|
if (!val) throw new Error(msg || 'Assertion failed'); |
|
|
|
if (!val) throw new Error(msg || "Assertion failed"); |
|
|
|
} |
|
|
|
|
|
|
|
// Could use `inherits` module, but don't want to move from single file
|
|
|
@ -31,12 +31,12 @@ |
|
|
|
this.red = null; |
|
|
|
|
|
|
|
if (number !== null) { |
|
|
|
if (base === 'le' || base === 'be') { |
|
|
|
if (base === "le" || base === "be") { |
|
|
|
endian = base; |
|
|
|
base = 10; |
|
|
|
} |
|
|
|
|
|
|
|
this._init(number || 0, base || 10, endian || 'be'); |
|
|
|
this._init(number || 0, base || 10, endian || "be"); |
|
|
|
} |
|
|
|
} |
|
|
|
exports.BN = BN; |
|
|
@ -46,21 +46,24 @@ |
|
|
|
|
|
|
|
var Buffer; |
|
|
|
try { |
|
|
|
if (typeof window !== 'undefined' && typeof window.Buffer !== 'undefined') { |
|
|
|
if (typeof window !== "undefined" && typeof window.Buffer !== "undefined") { |
|
|
|
Buffer = window.Buffer; |
|
|
|
} else { |
|
|
|
Buffer = require('buffer').Buffer; |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
Buffer = require("buffer").Buffer; |
|
|
|
} |
|
|
|
} catch (e) {} |
|
|
|
|
|
|
|
BN.isBN = function isBN(num) { |
|
|
|
if (num instanceof BN) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
return num !== null && typeof num === 'object' && |
|
|
|
num.constructor.wordSize === BN.wordSize && Array.isArray(num.words); |
|
|
|
return ( |
|
|
|
num !== null && |
|
|
|
typeof num === "object" && |
|
|
|
num.constructor.wordSize === BN.wordSize && |
|
|
|
Array.isArray(num.words) |
|
|
|
); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.max = function max(left, right) { |
|
|
@ -74,22 +77,22 @@ |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype._init = function init(number, base, endian) { |
|
|
|
if (typeof number === 'number') { |
|
|
|
if (typeof number === "number") { |
|
|
|
return this._initNumber(number, base, endian); |
|
|
|
} |
|
|
|
|
|
|
|
if (typeof number === 'object') { |
|
|
|
if (typeof number === "object") { |
|
|
|
return this._initArray(number, base, endian); |
|
|
|
} |
|
|
|
|
|
|
|
if (base === 'hex') { |
|
|
|
if (base === "hex") { |
|
|
|
base = 16; |
|
|
|
} |
|
|
|
assert(base === (base | 0) && base >= 2 && base <= 36); |
|
|
|
|
|
|
|
number = number.toString().replace(/\s+/g, ''); |
|
|
|
number = number.toString().replace(/\s+/g, ""); |
|
|
|
var start = 0; |
|
|
|
if (number[0] === '-') { |
|
|
|
if (number[0] === "-") { |
|
|
|
start++; |
|
|
|
this.negative = 1; |
|
|
|
} |
|
|
@ -99,7 +102,7 @@ |
|
|
|
this._parseHex(number, start, endian); |
|
|
|
} else { |
|
|
|
this._parseBase(number, base, start); |
|
|
|
if (endian === 'le') { |
|
|
|
if (endian === "le") { |
|
|
|
this._initArray(this.toArray(), base, endian); |
|
|
|
} |
|
|
|
} |
|
|
@ -115,22 +118,15 @@ |
|
|
|
this.words = [number & 0x3ffffff]; |
|
|
|
this.length = 1; |
|
|
|
} else if (number < 0x10000000000000) { |
|
|
|
this.words = [ |
|
|
|
number & 0x3ffffff, |
|
|
|
(number / 0x4000000) & 0x3ffffff |
|
|
|
]; |
|
|
|
this.words = [number & 0x3ffffff, (number / 0x4000000) & 0x3ffffff]; |
|
|
|
this.length = 2; |
|
|
|
} else { |
|
|
|
assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
|
|
|
|
this.words = [ |
|
|
|
number & 0x3ffffff, |
|
|
|
(number / 0x4000000) & 0x3ffffff, |
|
|
|
1 |
|
|
|
]; |
|
|
|
this.words = [number & 0x3ffffff, (number / 0x4000000) & 0x3ffffff, 1]; |
|
|
|
this.length = 3; |
|
|
|
} |
|
|
|
|
|
|
|
if (endian !== 'le') return; |
|
|
|
if (endian !== "le") return; |
|
|
|
|
|
|
|
// Reverse the bytes
|
|
|
|
this._initArray(this.toArray(), base, endian); |
|
|
@ -138,7 +134,7 @@ |
|
|
|
|
|
|
|
BN.prototype._initArray = function _initArray(number, base, endian) { |
|
|
|
// Perhaps a Uint8Array
|
|
|
|
assert(typeof number.length === 'number'); |
|
|
|
assert(typeof number.length === "number"); |
|
|
|
if (number.length <= 0) { |
|
|
|
this.words = [0]; |
|
|
|
this.length = 1; |
|
|
@ -153,7 +149,7 @@ |
|
|
|
|
|
|
|
var j, w; |
|
|
|
var off = 0; |
|
|
|
if (endian === 'be') { |
|
|
|
if (endian === "be") { |
|
|
|
for (i = number.length - 1, j = 0; i >= 0; i -= 3) { |
|
|
|
w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16); |
|
|
|
this.words[j] |= (w << off) & 0x3ffffff; |
|
|
@ -164,7 +160,7 @@ |
|
|
|
j++; |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (endian === 'le') { |
|
|
|
} else if (endian === "le") { |
|
|
|
for (i = 0, j = 0; i < number.length; i += 3) { |
|
|
|
w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16); |
|
|
|
this.words[j] |= (w << off) & 0x3ffffff; |
|
|
@ -191,7 +187,7 @@ |
|
|
|
} else if (c >= 97 && c <= 102) { |
|
|
|
return c - 87; |
|
|
|
} else { |
|
|
|
assert(false, 'Invalid character in ' + string); |
|
|
|
assert(false, "Invalid character in " + string); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -216,7 +212,7 @@ |
|
|
|
var j = 0; |
|
|
|
|
|
|
|
var w; |
|
|
|
if (endian === 'be') { |
|
|
|
if (endian === "be") { |
|
|
|
for (i = number.length - 1; i >= start; i -= 2) { |
|
|
|
w = parseHexByte(number, start, i) << off; |
|
|
|
this.words[j] |= w & 0x3ffffff; |
|
|
@ -230,7 +226,11 @@ |
|
|
|
} |
|
|
|
} else { |
|
|
|
var parseLength = number.length - start; |
|
|
|
for (i = parseLength % 2 === 0 ? start + 1 : start; i < number.length; i += 2) { |
|
|
|
for ( |
|
|
|
i = parseLength % 2 === 0 ? start + 1 : start; |
|
|
|
i < number.length; |
|
|
|
i += 2 |
|
|
|
) { |
|
|
|
w = parseHexByte(number, start, i) << off; |
|
|
|
this.words[j] |= w & 0x3ffffff; |
|
|
|
if (off >= 18) { |
|
|
@ -267,7 +267,7 @@ |
|
|
|
} else { |
|
|
|
b = c; |
|
|
|
} |
|
|
|
assert(c >= 0 && b < mul, 'Invalid character'); |
|
|
|
assert(c >= 0 && b < mul, "Invalid character"); |
|
|
|
r += b; |
|
|
|
} |
|
|
|
return r; |
|
|
@ -372,9 +372,9 @@ |
|
|
|
|
|
|
|
// Check Symbol.for because not everywhere where Symbol defined
|
|
|
|
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#Browser_compatibility
|
|
|
|
if (typeof Symbol !== 'undefined' && typeof Symbol.for === 'function') { |
|
|
|
if (typeof Symbol !== "undefined" && typeof Symbol.for === "function") { |
|
|
|
try { |
|
|
|
BN.prototype[Symbol.for('nodejs.util.inspect.custom')] = inspect; |
|
|
|
BN.prototype[Symbol.for("nodejs.util.inspect.custom")] = inspect; |
|
|
|
} catch (e) { |
|
|
|
BN.prototype.inspect = inspect; |
|
|
|
} |
|
|
@ -383,7 +383,7 @@ |
|
|
|
} |
|
|
|
|
|
|
|
function inspect() { |
|
|
|
return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>'; |
|
|
|
return (this.red ? "<BN-R: " : "<BN: ") + this.toString(16) + ">"; |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
@ -417,50 +417,45 @@ |
|
|
|
*/ |
|
|
|
|
|
|
|
var zeros = [ |
|
|
|
'', |
|
|
|
'0', |
|
|
|
'00', |
|
|
|
'000', |
|
|
|
'0000', |
|
|
|
'00000', |
|
|
|
'000000', |
|
|
|
'0000000', |
|
|
|
'00000000', |
|
|
|
'000000000', |
|
|
|
'0000000000', |
|
|
|
'00000000000', |
|
|
|
'000000000000', |
|
|
|
'0000000000000', |
|
|
|
'00000000000000', |
|
|
|
'000000000000000', |
|
|
|
'0000000000000000', |
|
|
|
'00000000000000000', |
|
|
|
'000000000000000000', |
|
|
|
'0000000000000000000', |
|
|
|
'00000000000000000000', |
|
|
|
'000000000000000000000', |
|
|
|
'0000000000000000000000', |
|
|
|
'00000000000000000000000', |
|
|
|
'000000000000000000000000', |
|
|
|
'0000000000000000000000000' |
|
|
|
"", |
|
|
|
"0", |
|
|
|
"00", |
|
|
|
"000", |
|
|
|
"0000", |
|
|
|
"00000", |
|
|
|
"000000", |
|
|
|
"0000000", |
|
|
|
"00000000", |
|
|
|
"000000000", |
|
|
|
"0000000000", |
|
|
|
"00000000000", |
|
|
|
"000000000000", |
|
|
|
"0000000000000", |
|
|
|
"00000000000000", |
|
|
|
"000000000000000", |
|
|
|
"0000000000000000", |
|
|
|
"00000000000000000", |
|
|
|
"000000000000000000", |
|
|
|
"0000000000000000000", |
|
|
|
"00000000000000000000", |
|
|
|
"000000000000000000000", |
|
|
|
"0000000000000000000000", |
|
|
|
"00000000000000000000000", |
|
|
|
"000000000000000000000000", |
|
|
|
"0000000000000000000000000", |
|
|
|
]; |
|
|
|
|
|
|
|
var groupSizes = [ |
|
|
|
0, 0, |
|
|
|
25, 16, 12, 11, 10, 9, 8, |
|
|
|
8, 7, 7, 7, 7, 6, 6, |
|
|
|
6, 6, 6, 6, 6, 5, 5, |
|
|
|
5, 5, 5, 5, 5, 5, 5, |
|
|
|
5, 5, 5, 5, 5, 5, 5 |
|
|
|
0, 0, 25, 16, 12, 11, 10, 9, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, |
|
|
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, |
|
|
|
]; |
|
|
|
|
|
|
|
var groupBases = [ |
|
|
|
0, 0, |
|
|
|
33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216, |
|
|
|
0, 0, 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216, |
|
|
|
43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625, |
|
|
|
16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, |
|
|
|
6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149, |
|
|
|
24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176 |
|
|
|
16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, 6436343, |
|
|
|
7962624, 9765625, 11881376, 14348907, 17210368, 20511149, 24300000, |
|
|
|
28629151, 33554432, 39135393, 45435424, 52521875, 60466176, |
|
|
|
]; |
|
|
|
|
|
|
|
BN.prototype.toString = function toString(base, padding) { |
|
|
@ -468,8 +463,8 @@ |
|
|
|
padding = padding | 0 || 1; |
|
|
|
|
|
|
|
var out; |
|
|
|
if (base === 16 || base === 'hex') { |
|
|
|
out = ''; |
|
|
|
if (base === 16 || base === "hex") { |
|
|
|
out = ""; |
|
|
|
var off = 0; |
|
|
|
var carry = 0; |
|
|
|
for (var i = 0; i < this.length; i++) { |
|
|
@ -491,10 +486,10 @@ |
|
|
|
out = carry.toString(16) + out; |
|
|
|
} |
|
|
|
while (out.length % padding !== 0) { |
|
|
|
out = '0' + out; |
|
|
|
out = "0" + out; |
|
|
|
} |
|
|
|
if (this.negative !== 0) { |
|
|
|
out = '-' + out; |
|
|
|
out = "-" + out; |
|
|
|
} |
|
|
|
return out; |
|
|
|
} |
|
|
@ -504,7 +499,7 @@ |
|
|
|
var groupSize = groupSizes[base]; |
|
|
|
// var groupBase = Math.pow(base, groupSize);
|
|
|
|
var groupBase = groupBases[base]; |
|
|
|
out = ''; |
|
|
|
out = ""; |
|
|
|
var c = this.clone(); |
|
|
|
c.negative = 0; |
|
|
|
while (!c.isZero()) { |
|
|
@ -518,18 +513,18 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
if (this.isZero()) { |
|
|
|
out = '0' + out; |
|
|
|
out = "0" + out; |
|
|
|
} |
|
|
|
while (out.length % padding !== 0) { |
|
|
|
out = '0' + out; |
|
|
|
out = "0" + out; |
|
|
|
} |
|
|
|
if (this.negative !== 0) { |
|
|
|
out = '-' + out; |
|
|
|
out = "-" + out; |
|
|
|
} |
|
|
|
return out; |
|
|
|
} |
|
|
|
|
|
|
|
assert(false, 'Base should be between 2 and 36'); |
|
|
|
assert(false, "Base should be between 2 and 36"); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.toNumber = function toNumber() { |
|
|
@ -538,11 +533,11 @@ |
|
|
|
ret += this.words[1] * 0x4000000; |
|
|
|
} else if (this.length === 3 && this.words[2] === 0x01) { |
|
|
|
// NOTE: at this stage it is known that the top bit is set
|
|
|
|
ret += 0x10000000000000 + (this.words[1] * 0x4000000); |
|
|
|
ret += 0x10000000000000 + this.words[1] * 0x4000000; |
|
|
|
} else if (this.length > 2) { |
|
|
|
assert(false, 'Number can only safely store up to 53 bits'); |
|
|
|
assert(false, "Number can only safely store up to 53 bits"); |
|
|
|
} |
|
|
|
return (this.negative !== 0) ? -ret : ret; |
|
|
|
return this.negative !== 0 ? -ret : ret; |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.toJSON = function toJSON() { |
|
|
@ -571,12 +566,12 @@ |
|
|
|
|
|
|
|
var byteLength = this.byteLength(); |
|
|
|
var reqLength = length || Math.max(1, byteLength); |
|
|
|
assert(byteLength <= reqLength, 'byte array longer than desired length'); |
|
|
|
assert(reqLength > 0, 'Requested array length <= 0'); |
|
|
|
assert(byteLength <= reqLength, "byte array longer than desired length"); |
|
|
|
assert(reqLength > 0, "Requested array length <= 0"); |
|
|
|
|
|
|
|
var res = allocate(ArrayType, reqLength); |
|
|
|
var postfix = endian === 'le' ? 'LE' : 'BE'; |
|
|
|
this['_toArrayLike' + postfix](res, byteLength); |
|
|
|
var postfix = endian === "le" ? "LE" : "BE"; |
|
|
|
this["_toArrayLike" + postfix](res, byteLength); |
|
|
|
return res; |
|
|
|
}; |
|
|
|
|
|
|
@ -886,7 +881,7 @@ |
|
|
|
|
|
|
|
// Not ``this`` with ``width`` bitwidth
|
|
|
|
BN.prototype.inotn = function inotn(width) { |
|
|
|
assert(typeof width === 'number' && width >= 0); |
|
|
|
assert(typeof width === "number" && width >= 0); |
|
|
|
|
|
|
|
var bytesNeeded = Math.ceil(width / 26) | 0; |
|
|
|
var bitsLeft = width % 26; |
|
|
@ -918,7 +913,7 @@ |
|
|
|
|
|
|
|
// Set `bit` of `this`
|
|
|
|
BN.prototype.setn = function setn(bit, val) { |
|
|
|
assert(typeof bit === 'number' && bit >= 0); |
|
|
|
assert(typeof bit === "number" && bit >= 0); |
|
|
|
|
|
|
|
var off = (bit / 26) | 0; |
|
|
|
var wbit = bit % 26; |
|
|
@ -1812,8 +1807,8 @@ |
|
|
|
for (var s = 1; s < N; s <<= 1) { |
|
|
|
var l = s << 1; |
|
|
|
|
|
|
|
var rtwdf = Math.cos(2 * Math.PI / l); |
|
|
|
var itwdf = Math.sin(2 * Math.PI / l); |
|
|
|
var rtwdf = Math.cos((2 * Math.PI) / l); |
|
|
|
var itwdf = Math.sin((2 * Math.PI) / l); |
|
|
|
|
|
|
|
for (var p = 0; p < N; p += l) { |
|
|
|
var rtwdf_ = rtwdf; |
|
|
@ -1853,11 +1848,11 @@ |
|
|
|
var N = Math.max(m, n) | 1; |
|
|
|
var odd = N & 1; |
|
|
|
var i = 0; |
|
|
|
for (N = N / 2 | 0; N; N = N >>> 1) { |
|
|
|
for (N = (N / 2) | 0; N; N = N >>> 1) { |
|
|
|
i++; |
|
|
|
} |
|
|
|
|
|
|
|
return 1 << i + 1 + odd; |
|
|
|
return 1 << (i + 1 + odd); |
|
|
|
}; |
|
|
|
|
|
|
|
FFTM.prototype.conjugate = function conjugate(rws, iws, N) { |
|
|
@ -1879,7 +1874,8 @@ |
|
|
|
FFTM.prototype.normalize13b = function normalize13b(ws, N) { |
|
|
|
var carry = 0; |
|
|
|
for (var i = 0; i < N / 2; i++) { |
|
|
|
var w = Math.round(ws[2 * i + 1] / N) * 0x2000 + |
|
|
|
var w = |
|
|
|
Math.round(ws[2 * i + 1] / N) * 0x2000 + |
|
|
|
Math.round(ws[2 * i] / N) + |
|
|
|
carry; |
|
|
|
|
|
|
@ -1888,7 +1884,7 @@ |
|
|
|
if (w < 0x4000000) { |
|
|
|
carry = 0; |
|
|
|
} else { |
|
|
|
carry = w / 0x4000000 | 0; |
|
|
|
carry = (w / 0x4000000) | 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -1900,8 +1896,10 @@ |
|
|
|
for (var i = 0; i < len; i++) { |
|
|
|
carry = carry + (ws[i] | 0); |
|
|
|
|
|
|
|
rws[2 * i] = carry & 0x1fff; carry = carry >>> 13; |
|
|
|
rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13; |
|
|
|
rws[2 * i] = carry & 0x1fff; |
|
|
|
carry = carry >>> 13; |
|
|
|
rws[2 * i + 1] = carry & 0x1fff; |
|
|
|
carry = carry >>> 13; |
|
|
|
} |
|
|
|
|
|
|
|
// Pad with zeroes
|
|
|
@ -1985,7 +1983,7 @@ |
|
|
|
var isNegNum = num < 0; |
|
|
|
if (isNegNum) num = -num; |
|
|
|
|
|
|
|
assert(typeof num === 'number'); |
|
|
|
assert(typeof num === "number"); |
|
|
|
assert(num < 0x4000000); |
|
|
|
|
|
|
|
// Carry
|
|
|
@ -2046,7 +2044,7 @@ |
|
|
|
|
|
|
|
// Shift-left in-place
|
|
|
|
BN.prototype.iushln = function iushln(bits) { |
|
|
|
assert(typeof bits === 'number' && bits >= 0); |
|
|
|
assert(typeof bits === "number" && bits >= 0); |
|
|
|
var r = bits % 26; |
|
|
|
var s = (bits - r) / 26; |
|
|
|
var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); |
|
|
@ -2093,7 +2091,7 @@ |
|
|
|
// NOTE: `hint` is a lowest bit before trailing zeroes
|
|
|
|
// NOTE: if `extended` is present - it will be filled with destroyed bits
|
|
|
|
BN.prototype.iushrn = function iushrn(bits, hint, extended) { |
|
|
|
assert(typeof bits === 'number' && bits >= 0); |
|
|
|
assert(typeof bits === "number" && bits >= 0); |
|
|
|
var h; |
|
|
|
if (hint) { |
|
|
|
h = (hint - (hint % 26)) / 26; |
|
|
@ -2175,7 +2173,7 @@ |
|
|
|
|
|
|
|
// Test if n bit is set
|
|
|
|
BN.prototype.testn = function testn(bit) { |
|
|
|
assert(typeof bit === 'number' && bit >= 0); |
|
|
|
assert(typeof bit === "number" && bit >= 0); |
|
|
|
var r = bit % 26; |
|
|
|
var s = (bit - r) / 26; |
|
|
|
var q = 1 << r; |
|
|
@ -2191,11 +2189,11 @@ |
|
|
|
|
|
|
|
// Return only lowers bits of number (in-place)
|
|
|
|
BN.prototype.imaskn = function imaskn(bits) { |
|
|
|
assert(typeof bits === 'number' && bits >= 0); |
|
|
|
assert(typeof bits === "number" && bits >= 0); |
|
|
|
var r = bits % 26; |
|
|
|
var s = (bits - r) / 26; |
|
|
|
|
|
|
|
assert(this.negative === 0, 'imaskn works only with positive numbers'); |
|
|
|
assert(this.negative === 0, "imaskn works only with positive numbers"); |
|
|
|
|
|
|
|
if (this.length <= s) { |
|
|
|
return this; |
|
|
@ -2221,7 +2219,7 @@ |
|
|
|
|
|
|
|
// Add plain number `num` to `this`
|
|
|
|
BN.prototype.iaddn = function iaddn(num) { |
|
|
|
assert(typeof num === 'number'); |
|
|
|
assert(typeof num === "number"); |
|
|
|
assert(num < 0x4000000); |
|
|
|
if (num < 0) return this.isubn(-num); |
|
|
|
|
|
|
@ -2262,7 +2260,7 @@ |
|
|
|
|
|
|
|
// Subtract plain number `num` from `this`
|
|
|
|
BN.prototype.isubn = function isubn(num) { |
|
|
|
assert(typeof num === 'number'); |
|
|
|
assert(typeof num === "number"); |
|
|
|
assert(num < 0x4000000); |
|
|
|
if (num < 0) return this.iaddn(-num); |
|
|
|
|
|
|
@ -2363,7 +2361,7 @@ |
|
|
|
var m = a.length - b.length; |
|
|
|
var q; |
|
|
|
|
|
|
|
if (mode !== 'mod') { |
|
|
|
if (mode !== "mod") { |
|
|
|
q = new BN(null); |
|
|
|
q.length = m + 1; |
|
|
|
q.words = new Array(q.length); |
|
|
@ -2381,7 +2379,8 @@ |
|
|
|
} |
|
|
|
|
|
|
|
for (var j = m - 1; j >= 0; j--) { |
|
|
|
var qj = (a.words[b.length + j] | 0) * 0x4000000 + |
|
|
|
var qj = |
|
|
|
(a.words[b.length + j] | 0) * 0x4000000 + |
|
|
|
(a.words[b.length + j - 1] | 0); |
|
|
|
|
|
|
|
// NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
|
|
|
@ -2407,13 +2406,13 @@ |
|
|
|
a._strip(); |
|
|
|
|
|
|
|
// Denormalize
|
|
|
|
if (mode !== 'div' && shift !== 0) { |
|
|
|
if (mode !== "div" && shift !== 0) { |
|
|
|
a.iushrn(shift); |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
div: q || null, |
|
|
|
mod: a |
|
|
|
mod: a, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
@ -2427,7 +2426,7 @@ |
|
|
|
if (this.isZero()) { |
|
|
|
return { |
|
|
|
div: new BN(0), |
|
|
|
mod: new BN(0) |
|
|
|
mod: new BN(0), |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
@ -2435,11 +2434,11 @@ |
|
|
|
if (this.negative !== 0 && num.negative === 0) { |
|
|
|
res = this.neg().divmod(num, mode); |
|
|
|
|
|
|
|
if (mode !== 'mod') { |
|
|
|
if (mode !== "mod") { |
|
|
|
div = res.div.neg(); |
|
|
|
} |
|
|
|
|
|
|
|
if (mode !== 'div') { |
|
|
|
if (mode !== "div") { |
|
|
|
mod = res.mod.neg(); |
|
|
|
if (positive && mod.negative !== 0) { |
|
|
|
mod.iadd(num); |
|
|
@ -2448,27 +2447,27 @@ |
|
|
|
|
|
|
|
return { |
|
|
|
div: div, |
|
|
|
mod: mod |
|
|
|
mod: mod, |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
if (this.negative === 0 && num.negative !== 0) { |
|
|
|
res = this.divmod(num.neg(), mode); |
|
|
|
|
|
|
|
if (mode !== 'mod') { |
|
|
|
if (mode !== "mod") { |
|
|
|
div = res.div.neg(); |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
div: div, |
|
|
|
mod: res.mod |
|
|
|
mod: res.mod, |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
if ((this.negative & num.negative) !== 0) { |
|
|
|
res = this.neg().divmod(num.neg(), mode); |
|
|
|
|
|
|
|
if (mode !== 'div') { |
|
|
|
if (mode !== "div") { |
|
|
|
mod = res.mod.neg(); |
|
|
|
if (positive && mod.negative !== 0) { |
|
|
|
mod.isub(num); |
|
|
@ -2477,7 +2476,7 @@ |
|
|
|
|
|
|
|
return { |
|
|
|
div: res.div, |
|
|
|
mod: mod |
|
|
|
mod: mod, |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
@ -2487,29 +2486,29 @@ |
|
|
|
if (num.length > this.length || this.cmp(num) < 0) { |
|
|
|
return { |
|
|
|
div: new BN(0), |
|
|
|
mod: this |
|
|
|
mod: this, |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
// Very short reduction
|
|
|
|
if (num.length === 1) { |
|
|
|
if (mode === 'div') { |
|
|
|
if (mode === "div") { |
|
|
|
return { |
|
|
|
div: this.divn(num.words[0]), |
|
|
|
mod: null |
|
|
|
mod: null, |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
if (mode === 'mod') { |
|
|
|
if (mode === "mod") { |
|
|
|
return { |
|
|
|
div: null, |
|
|
|
mod: new BN(this.modrn(num.words[0])) |
|
|
|
mod: new BN(this.modrn(num.words[0])), |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
div: this.divn(num.words[0]), |
|
|
|
mod: new BN(this.modrn(num.words[0])) |
|
|
|
mod: new BN(this.modrn(num.words[0])), |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
@ -2518,16 +2517,16 @@ |
|
|
|
|
|
|
|
// Find `this` / `num`
|
|
|
|
BN.prototype.div = function div(num) { |
|
|
|
return this.divmod(num, 'div', false).div; |
|
|
|
return this.divmod(num, "div", false).div; |
|
|
|
}; |
|
|
|
|
|
|
|
// Find `this` % `num`
|
|
|
|
BN.prototype.mod = function mod(num) { |
|
|
|
return this.divmod(num, 'mod', false).mod; |
|
|
|
return this.divmod(num, "mod", false).mod; |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.umod = function umod(num) { |
|
|
|
return this.divmod(num, 'mod', true).mod; |
|
|
|
return this.divmod(num, "mod", true).mod; |
|
|
|
}; |
|
|
|
|
|
|
|
// Find Round(`this` / `num`)
|
|
|
@ -2667,7 +2666,7 @@ |
|
|
|
return { |
|
|
|
a: C, |
|
|
|
b: D, |
|
|
|
gcd: y.iushln(g) |
|
|
|
gcd: y.iushln(g), |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
@ -2799,7 +2798,7 @@ |
|
|
|
|
|
|
|
// Increment at the bit position in-line
|
|
|
|
BN.prototype.bincn = function bincn(bit) { |
|
|
|
assert(typeof bit === 'number'); |
|
|
|
assert(typeof bit === "number"); |
|
|
|
var r = bit % 26; |
|
|
|
var s = (bit - r) / 26; |
|
|
|
var q = 1 << r; |
|
|
@ -2847,7 +2846,7 @@ |
|
|
|
num = -num; |
|
|
|
} |
|
|
|
|
|
|
|
assert(num <= 0x3ffffff, 'Number is too big'); |
|
|
|
assert(num <= 0x3ffffff, "Number is too big"); |
|
|
|
|
|
|
|
var w = this.words[0] | 0; |
|
|
|
res = w === num ? 0 : w < num ? -1 : 1; |
|
|
@ -2940,13 +2939,13 @@ |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.toRed = function toRed(ctx) { |
|
|
|
assert(!this.red, 'Already a number in reduction context'); |
|
|
|
assert(this.negative === 0, 'red works only with positives'); |
|
|
|
assert(!this.red, "Already a number in reduction context"); |
|
|
|
assert(this.negative === 0, "red works only with positives"); |
|
|
|
return ctx.convertTo(this)._forceRed(ctx); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.fromRed = function fromRed() { |
|
|
|
assert(this.red, 'fromRed works only with numbers in reduction context'); |
|
|
|
assert(this.red, "fromRed works only with numbers in reduction context"); |
|
|
|
return this.red.convertFrom(this); |
|
|
|
}; |
|
|
|
|
|
|
@ -2956,81 +2955,81 @@ |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.forceRed = function forceRed(ctx) { |
|
|
|
assert(!this.red, 'Already a number in reduction context'); |
|
|
|
assert(!this.red, "Already a number in reduction context"); |
|
|
|
return this._forceRed(ctx); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.redAdd = function redAdd(num) { |
|
|
|
assert(this.red, 'redAdd works only with red numbers'); |
|
|
|
assert(this.red, "redAdd works only with red numbers"); |
|
|
|
return this.red.add(this, num); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.redIAdd = function redIAdd(num) { |
|
|
|
assert(this.red, 'redIAdd works only with red numbers'); |
|
|
|
assert(this.red, "redIAdd works only with red numbers"); |
|
|
|
return this.red.iadd(this, num); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.redSub = function redSub(num) { |
|
|
|
assert(this.red, 'redSub works only with red numbers'); |
|
|
|
assert(this.red, "redSub works only with red numbers"); |
|
|
|
return this.red.sub(this, num); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.redISub = function redISub(num) { |
|
|
|
assert(this.red, 'redISub works only with red numbers'); |
|
|
|
assert(this.red, "redISub works only with red numbers"); |
|
|
|
return this.red.isub(this, num); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.redShl = function redShl(num) { |
|
|
|
assert(this.red, 'redShl works only with red numbers'); |
|
|
|
assert(this.red, "redShl works only with red numbers"); |
|
|
|
return this.red.shl(this, num); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.redMul = function redMul(num) { |
|
|
|
assert(this.red, 'redMul works only with red numbers'); |
|
|
|
assert(this.red, "redMul works only with red numbers"); |
|
|
|
this.red._verify2(this, num); |
|
|
|
return this.red.mul(this, num); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.redIMul = function redIMul(num) { |
|
|
|
assert(this.red, 'redMul works only with red numbers'); |
|
|
|
assert(this.red, "redMul works only with red numbers"); |
|
|
|
this.red._verify2(this, num); |
|
|
|
return this.red.imul(this, num); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.redSqr = function redSqr() { |
|
|
|
assert(this.red, 'redSqr works only with red numbers'); |
|
|
|
assert(this.red, "redSqr works only with red numbers"); |
|
|
|
this.red._verify1(this); |
|
|
|
return this.red.sqr(this); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.redISqr = function redISqr() { |
|
|
|
assert(this.red, 'redISqr works only with red numbers'); |
|
|
|
assert(this.red, "redISqr works only with red numbers"); |
|
|
|
this.red._verify1(this); |
|
|
|
return this.red.isqr(this); |
|
|
|
}; |
|
|
|
|
|
|
|
// Square root over p
|
|
|
|
BN.prototype.redSqrt = function redSqrt() { |
|
|
|
assert(this.red, 'redSqrt works only with red numbers'); |
|
|
|
assert(this.red, "redSqrt works only with red numbers"); |
|
|
|
this.red._verify1(this); |
|
|
|
return this.red.sqrt(this); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.redInvm = function redInvm() { |
|
|
|
assert(this.red, 'redInvm works only with red numbers'); |
|
|
|
assert(this.red, "redInvm works only with red numbers"); |
|
|
|
this.red._verify1(this); |
|
|
|
return this.red.invm(this); |
|
|
|
}; |
|
|
|
|
|
|
|
// Return negative clone of `this` % `red modulo`
|
|
|
|
BN.prototype.redNeg = function redNeg() { |
|
|
|
assert(this.red, 'redNeg works only with red numbers'); |
|
|
|
assert(this.red, "redNeg works only with red numbers"); |
|
|
|
this.red._verify1(this); |
|
|
|
return this.red.neg(this); |
|
|
|
}; |
|
|
|
|
|
|
|
BN.prototype.redPow = function redPow(num) { |
|
|
|
assert(this.red && !num.red, 'redPow(normalNum)'); |
|
|
|
assert(this.red && !num.red, "redPow(normalNum)"); |
|
|
|
this.red._verify1(this); |
|
|
|
return this.red.pow(this, num); |
|
|
|
}; |
|
|
@ -3040,7 +3039,7 @@ |
|
|
|
k256: null, |
|
|
|
p224: null, |
|
|
|
p192: null, |
|
|
|
p25519: null |
|
|
|
p25519: null, |
|
|
|
}; |
|
|
|
|
|
|
|
// Pseudo-Mersenne prime
|
|
|
@ -3103,8 +3102,9 @@ |
|
|
|
function K256() { |
|
|
|
MPrime.call( |
|
|
|
this, |
|
|
|
'k256', |
|
|
|
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f'); |
|
|
|
"k256", |
|
|
|
"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f", |
|
|
|
); |
|
|
|
} |
|
|
|
inherits(K256, MPrime); |
|
|
|
|
|
|
@ -3170,16 +3170,18 @@ |
|
|
|
function P224() { |
|
|
|
MPrime.call( |
|
|
|
this, |
|
|
|
'p224', |
|
|
|
'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001'); |
|
|
|
"p224", |
|
|
|
"ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001", |
|
|
|
); |
|
|
|
} |
|
|
|
inherits(P224, MPrime); |
|
|
|
|
|
|
|
function P192() { |
|
|
|
MPrime.call( |
|
|
|
this, |
|
|
|
'p192', |
|
|
|
'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff'); |
|
|
|
"p192", |
|
|
|
"ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff", |
|
|
|
); |
|
|
|
} |
|
|
|
inherits(P192, MPrime); |
|
|
|
|
|
|
@ -3187,8 +3189,9 @@ |
|
|
|
// 2 ^ 255 - 19
|
|
|
|
MPrime.call( |
|
|
|
this, |
|
|
|
'25519', |
|
|
|
'7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed'); |
|
|
|
"25519", |
|
|
|
"7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed", |
|
|
|
); |
|
|
|
} |
|
|
|
inherits(P25519, MPrime); |
|
|
|
|
|
|
@ -3215,16 +3218,16 @@ |
|
|
|
if (primes[name]) return primes[name]; |
|
|
|
|
|
|
|
var prime; |
|
|
|
if (name === 'k256') { |
|
|
|
if (name === "k256") { |
|
|
|
prime = new K256(); |
|
|
|
} else if (name === 'p224') { |
|
|
|
} else if (name === "p224") { |
|
|
|
prime = new P224(); |
|
|
|
} else if (name === 'p192') { |
|
|
|
} else if (name === "p192") { |
|
|
|
prime = new P192(); |
|
|
|
} else if (name === 'p25519') { |
|
|
|
} else if (name === "p25519") { |
|
|
|
prime = new P25519(); |
|
|
|
} else { |
|
|
|
throw new Error('Unknown prime ' + name); |
|
|
|
throw new Error("Unknown prime " + name); |
|
|
|
} |
|
|
|
primes[name] = prime; |
|
|
|
|
|
|
@ -3235,26 +3238,25 @@ |
|
|
|
// Base reduction engine
|
|
|
|
//
|
|
|
|
function Red(m) { |
|
|
|
if (typeof m === 'string') { |
|
|
|
if (typeof m === "string") { |
|
|
|
var prime = BN._prime(m); |
|
|
|
this.m = prime.p; |
|
|
|
this.prime = prime; |
|
|
|
} else { |
|
|
|
assert(m.gtn(1), 'modulus must be greater than 1'); |
|
|
|
assert(m.gtn(1), "modulus must be greater than 1"); |
|
|
|
this.m = m; |
|
|
|
this.prime = null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Red.prototype._verify1 = function _verify1(a) { |
|
|
|
assert(a.negative === 0, 'red works only with positives'); |
|
|
|
assert(a.red, 'red works only with red numbers'); |
|
|
|
assert(a.negative === 0, "red works only with positives"); |
|
|
|
assert(a.red, "red works only with red numbers"); |
|
|
|
}; |
|
|
|
|
|
|
|
Red.prototype._verify2 = function _verify2(a, b) { |
|
|
|
assert((a.negative | b.negative) === 0, 'red works only with positives'); |
|
|
|
assert(a.red && a.red === b.red, |
|
|
|
'red works only with red numbers'); |
|
|
|
assert((a.negative | b.negative) === 0, "red works only with positives"); |
|
|
|
assert(a.red && a.red === b.red, "red works only with red numbers"); |
|
|
|
}; |
|
|
|
|
|
|
|
Red.prototype.imod = function imod(a) { |
|
|
|