@scrypt-inc/bsv
Version:
A pure and powerful JavaScript Bitcoin SV (BSV) library.
1,393 lines (1,376 loc) • 793 kB
JavaScript
var $fxX3C$elliptic = require("elliptic");
var $fxX3C$hashjs = require("hash.js");
var $fxX3C$crypto = require("crypto");
var $fxX3C$bs58 = require("bs58");
var $fxX3C$assert = require("assert");
var $fxX3C$inherits = require("inherits");
var $fxX3C$aesjs = require("aes-js");
var $fxX3C$unorm = require("unorm");
var $fxX3C$bnjs = require("bn.js");
var $parcel$global =
typeof globalThis !== 'undefined'
? globalThis
: typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: {};
var $parcel$modules = {};
var $parcel$inits = {};
var parcelRequire = $parcel$global["parcelRequire76f9"];
if (parcelRequire == null) {
parcelRequire = function(id) {
if (id in $parcel$modules) {
return $parcel$modules[id].exports;
}
if (id in $parcel$inits) {
var init = $parcel$inits[id];
delete $parcel$inits[id];
var module = {id: id, exports: {}};
$parcel$modules[id] = module;
init.call(module.exports, module, module.exports);
return module.exports;
}
var err = new Error("Cannot find module '" + id + "'");
err.code = 'MODULE_NOT_FOUND';
throw err;
};
parcelRequire.register = function register(id, init) {
$parcel$inits[id] = init;
};
$parcel$global["parcelRequire76f9"] = parcelRequire;
}
var parcelRegister = parcelRequire.register;
parcelRegister("e1FbD", function(module, exports) {
module.exports = JSON.parse('{"name":"@scrypt-inc/bsv","version":"1.0.5","description":"A pure and powerful JavaScript Bitcoin SV (BSV) library.","author":"sCrypt.Inc","source":"./index.js","main":"dist/main.js","browser":"dist/browser.js","types":"./index.d.ts","scripts":{"lint":"standard --fix","build":"parcel build --no-cache","dev":"mocha -g \'BIP32\' ","test":"standard && mocha","coverage":"nyc --reporter=text npm run test","prepublishOnly":"yarn build","release":"npm publish --access public"},"targets":{"types":false},"keywords":["bitcoin","bsv","scrypt","transaction","address","p2p","ecies","cryptocurrency","blockchain","payment","bip21","bip32","bip37","bip69","bip70","multisig"],"repository":{"type":"git","url":"git+https://github.com/sCrypt-Inc/bsv"},"dependencies":{"aes-js":"^3.1.2","assert":"^2.1.0","bn.js":"=4.11.9","bs58":"=4.0.1","buffer":"^6.0.3","clone-deep":"^4.0.1","elliptic":"^6.6.1","hash.js":"^1.1.7","inherits":"2.0.3","unorm":"1.4.1"},"devDependencies":{"brfs":"2.0.1","chai":"4.2.0","mocha":"^8.4.0","nyc":"^14.1.1","parcel":"latest","sinon":"7.2.3","standard":"12.0.1"},"license":"MIT","standard":{"globals":["afterEach","beforeEach","describe","it"],"ignore":["dist/**","esmTest/**"]}}');
});
parcelRegister("lM2TS", function(module, exports) {
"use strict";
var $fHjyd = parcelRequire("fHjyd");
var $e34gf = parcelRequire("e34gf");
var $iUxHD = parcelRequire("iUxHD");
var $fda0549de5595c4b$var$reversebuf = function(buf) {
var buf2 = Buffer.alloc(buf.length);
for(var i = 0; i < buf.length; i++)buf2[i] = buf[buf.length - 1 - i];
return buf2;
};
$fHjyd.Zero = new $fHjyd(0);
$fHjyd.One = new $fHjyd(1);
$fHjyd.Minus1 = new $fHjyd(-1);
/**
* Convert a number into a big number.
*
* @param {number} n Any positive or negative integer.
*/ $fHjyd.fromNumber = function(n) {
$e34gf.checkArgument($iUxHD.isNumber(n));
return new $fHjyd(n);
};
/**
* Convert a string number into a big number.
*
* @param {string} str Any positive or negative integer formatted as a string.
* @param {number} base The base of the number, defaults to 10.
*/ $fHjyd.fromString = function(str, base) {
$e34gf.checkArgument($iUxHD.isString(str));
return new $fHjyd(str, base);
};
/**
* Convert a buffer (such as a 256 bit binary private key) into a big number.
* Sometimes these numbers can be formatted either as 'big endian' or 'little
* endian', and so there is an opts parameter that lets you specify which
* endianness is specified.
*
* @param {Buffer} buf A buffer number, such as a 256 bit hash or key.
* @param {Object} opts With a property 'endian' that can be either 'big' or 'little'. Defaults big endian (most significant digit first).
*/ $fHjyd.fromBuffer = function(buf, opts) {
if (typeof opts !== "undefined" && opts.endian === "little") buf = $fda0549de5595c4b$var$reversebuf(buf);
var hex = buf.toString("hex");
var bn = new $fHjyd(hex, 16);
return bn;
};
/**
* Instantiate a BigNumber from a "signed magnitude buffer". (a buffer where the
* most significant bit represents the sign (0 = positive, 1 = negative)
*
* @param {Buffer} buf A buffer number, such as a 256 bit hash or key.
* @param {Object} opts With a property 'endian' that can be either 'big' or 'little'. Defaults big endian (most significant digit first).
*/ $fHjyd.fromSM = function(buf, opts) {
var ret;
if (buf.length === 0) return $fHjyd.fromBuffer(Buffer.from([
0
]));
var endian = "big";
if (opts) endian = opts.endian;
if (endian === "little") buf = $fda0549de5595c4b$var$reversebuf(buf);
if (buf[0] & 0x80) {
buf[0] = buf[0] & 0x7f;
ret = $fHjyd.fromBuffer(buf);
ret.neg().copy(ret);
} else ret = $fHjyd.fromBuffer(buf);
return ret;
};
/**
* Convert a big number into a number.
*/ $fHjyd.prototype.toNumber = function() {
return parseInt(this.toString(10), 10);
};
/**
* Convert a big number into a buffer. This is somewhat ambiguous, so there is
* an opts parameter that let's you specify the endianness or the size.
* opts.endian can be either 'big' or 'little' and opts.size can be any
* sufficiently large number of bytes. If you always want to create a 32 byte
* big endian number, then specify opts = { endian: 'big', size: 32 }
*
* @param {Object} opts Defaults to { endian: 'big', size: 32 }
*/ $fHjyd.prototype.toBuffer = function(opts) {
var buf, hex;
if (opts && opts.size) {
hex = this.toString(16, 2);
var natlen = hex.length / 2;
buf = Buffer.from(hex, "hex");
if (natlen === opts.size) ;
else if (natlen > opts.size) buf = $fHjyd.trim(buf, natlen);
else if (natlen < opts.size) buf = $fHjyd.pad(buf, natlen, opts.size);
} else {
hex = this.toString(16, 2);
buf = Buffer.from(hex, "hex");
}
if (typeof opts !== "undefined" && opts.endian === "little") buf = $fda0549de5595c4b$var$reversebuf(buf);
return buf;
};
/**
* For big numbers that are either positive or negative, you can convert to
* "sign magnitude" format whereby the first bit specifies whether the number is
* positive or negative.
*/ $fHjyd.prototype.toSMBigEndian = function() {
var buf;
if (this.cmp($fHjyd.Zero) === -1) {
buf = this.neg().toBuffer();
if (buf[0] & 0x80) buf = Buffer.concat([
Buffer.from([
0x80
]),
buf
]);
else buf[0] = buf[0] | 0x80;
} else {
buf = this.toBuffer();
if (buf[0] & 0x80) buf = Buffer.concat([
Buffer.from([
0x00
]),
buf
]);
}
if (buf.length === 1 & buf[0] === 0) buf = Buffer.from([]);
return buf;
};
/**
* For big numbers that are either positive or negative, you can convert to
* "sign magnitude" format whereby the first bit specifies whether the number is
* positive or negative.
*
* @param {Object} opts Defaults to { endian: 'big' }
*/ $fHjyd.prototype.toSM = function(opts) {
var endian = opts ? opts.endian : "big";
var buf = this.toSMBigEndian();
if (endian === "little") buf = $fda0549de5595c4b$var$reversebuf(buf);
return buf;
};
/**
* Create a BN from a "ScriptNum": This is analogous to the constructor for
* CScriptNum in bitcoind. Many ops in bitcoind's script interpreter use
* CScriptNum, which is not really a proper bignum. Instead, an error is thrown
* if trying to input a number bigger than 4 bytes. We copy that behavior here.
* A third argument, `size`, is provided to extend the hard limit of 4 bytes, as
* some usages require more than 4 bytes.
*
* @param {Buffer} buf A buffer of a number.
* @param {boolean} fRequireMinimal Whether to require minimal size encoding.
* @param {number} size The maximum size.
*/ $fHjyd.fromScriptNumBuffer = function(buf, fRequireMinimal, size) {
var nMaxNumSize = size || Number.MAX_SAFE_INTEGER;
$e34gf.checkArgument(buf.length <= nMaxNumSize, new Error("script number overflow"));
if (fRequireMinimal && buf.length > 0) // Check that the number is encoded with the minimum possible
// number of bytes.
//
// If the most-significant-byte - excluding the sign bit - is zero
// then we're not minimal. Note how this test also rejects the
// negative-zero encoding, 0x80.
{
if ((buf[buf.length - 1] & 0x7f) === 0) {
// One exception: if there's more than one byte and the most
// significant bit of the second-most-significant-byte is set
// it would conflict with the sign bit. An example of this case
// is +-255, which encode to 0xff00 and 0xff80 respectively.
// (big-endian).
if (buf.length <= 1 || (buf[buf.length - 2] & 0x80) === 0) throw new Error("non-minimally encoded script number");
}
}
return $fHjyd.fromSM(buf, {
endian: "little"
});
};
/**
* The corollary to the above, with the notable exception that we do not throw
* an error if the output is larger than four bytes. (Which can happen if
* performing a numerical operation that results in an overflow to more than 4
* bytes).
*/ $fHjyd.prototype.toScriptNumBuffer = function() {
return this.toSM({
endian: "little"
});
};
/**
* Trims a buffer if it starts with zeros.
*
* @param {Buffer} buf A buffer formatted number.
* @param {number} natlen The natural length of the number.
*/ $fHjyd.trim = function(buf, natlen) {
return buf.slice(natlen - buf.length, buf.length);
};
/**
* Adds extra zeros to the start of a number.
*
* @param {Buffer} buf A buffer formatted number.
* @param {number} natlen The natural length of the number.
* @param {number} size How big to pad the number in bytes.
*/ $fHjyd.pad = function(buf, natlen, size) {
var rbuf = Buffer.alloc(size);
for(var i = 0; i < buf.length; i++)rbuf[rbuf.length - 1 - i] = buf[buf.length - 1 - i];
for(i = 0; i < size - natlen; i++)rbuf[i] = 0;
return rbuf;
};
/**
* Convert a big number into a hex string. This is somewhat ambiguous, so there
* is an opts parameter that let's you specify the endianness or the size.
* opts.endian can be either 'big' or 'little' and opts.size can be any
* sufficiently large number of bytes. If you always want to create a 32 byte
* big endian number, then specify opts = { endian: 'big', size: 32 }
*
* @param {Object} opts Defaults to { endian: 'big', size: 32 }
*/ $fHjyd.prototype.toHex = function(...args) {
return this.toBuffer(...args).toString("hex");
};
/**
* Convert a hex string (such as a 256 bit binary private key) into a big
* number. Sometimes these numbers can be formatted either as 'big endian' or
* 'little endian', and so there is an opts parameter that lets you specify
* which endianness is specified.
*
* @param {Buffer} buf A buffer number, such as a 256 bit hash or key.
* @param {Object} opts With a property 'endian' that can be either 'big' or 'little'. Defaults big endian (most significant digit first).
*/ $fHjyd.fromHex = function(hex, ...args) {
return $fHjyd.fromBuffer(Buffer.from(hex, "hex"), ...args);
};
module.exports = $fHjyd;
});
parcelRegister("fHjyd", function(module, exports) {
(function(module1, exports) {
"use strict";
// Utils
function assert(val, msg) {
if (!val) throw new Error(msg || "Assertion failed");
}
// Could use `inherits` module, but don't want to move from single file
// architecture yet.
function inherits(ctor, superCtor) {
ctor.super_ = superCtor;
var TempCtor = function() {};
TempCtor.prototype = superCtor.prototype;
ctor.prototype = new TempCtor();
ctor.prototype.constructor = ctor;
}
// BN
function BN(number, base, endian) {
if (BN.isBN(number)) return number;
this.negative = 0;
this.words = null;
this.length = 0;
// Reduction context
this.red = null;
if (number !== null) {
if (base === "le" || base === "be") {
endian = base;
base = 10;
}
this._init(number || 0, base || 10, endian || "be");
}
}
if (typeof module1 === "object") module1.exports = BN;
else exports.BN = BN;
BN.BN = BN;
BN.wordSize = 26;
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);
};
BN.max = function max(left, right) {
if (left.cmp(right) > 0) return left;
return right;
};
BN.min = function min(left, right) {
if (left.cmp(right) < 0) return left;
return right;
};
BN.prototype._init = function init(number, base, endian) {
if (typeof number === "number") return this._initNumber(number, base, endian);
if (typeof number === "object") return this._initArray(number, base, endian);
if (base === "hex") base = 16;
assert(base === (base | 0) && base >= 2 && base <= 36);
number = number.toString().replace(/\s+/g, "");
var start = 0;
if (number[0] === "-") start++;
if (base === 16) this._parseHex(number, start);
else this._parseBase(number, base, start);
if (number[0] === "-") this.negative = 1;
this.strip();
if (endian !== "le") return;
this._initArray(this.toArray(), base, endian);
};
BN.prototype._initNumber = function _initNumber(number, base, endian) {
if (number < 0) {
this.negative = 1;
number = -number;
}
if (number < 0x4000000) {
this.words = [
number & 0x3ffffff
];
this.length = 1;
} else if (number < 0x10000000000000) {
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.length = 3;
}
if (endian !== "le") return;
// Reverse the bytes
this._initArray(this.toArray(), base, endian);
};
BN.prototype._initArray = function _initArray(number, base, endian) {
// Perhaps a Uint8Array
assert(typeof number.length === "number");
if (number.length <= 0) {
this.words = [
0
];
this.length = 1;
return this;
}
this.length = Math.ceil(number.length / 3);
this.words = new Array(this.length);
for(var i = 0; i < this.length; i++)this.words[i] = 0;
var j, w;
var off = 0;
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;
this.words[j + 1] = w >>> 26 - off & 0x3ffffff;
off += 24;
if (off >= 26) {
off -= 26;
j++;
}
}
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;
this.words[j + 1] = w >>> 26 - off & 0x3ffffff;
off += 24;
if (off >= 26) {
off -= 26;
j++;
}
}
return this.strip();
};
function parseHex(str, start, end) {
var r = 0;
var len = Math.min(str.length, end);
for(var i = start; i < len; i++){
var c = str.charCodeAt(i) - 48;
r <<= 4;
// 'a' - 'f'
if (c >= 49 && c <= 54) r |= c - 49 + 0xa;
else if (c >= 17 && c <= 22) r |= c - 17 + 0xa;
else r |= c & 0xf;
}
return r;
}
BN.prototype._parseHex = function _parseHex(number, start) {
// Create possibly bigger array to ensure that it fits the number
this.length = Math.ceil((number.length - start) / 6);
this.words = new Array(this.length);
for(var i = 0; i < this.length; i++)this.words[i] = 0;
var j, w;
// Scan 24-bit chunks and add them to the number
var off = 0;
for(i = number.length - 6, j = 0; i >= start; i -= 6){
w = parseHex(number, i, i + 6);
this.words[j] |= w << off & 0x3ffffff;
// NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
this.words[j + 1] |= w >>> 26 - off & 0x3fffff;
off += 24;
if (off >= 26) {
off -= 26;
j++;
}
}
if (i + 6 !== start) {
w = parseHex(number, start, i + 6);
this.words[j] |= w << off & 0x3ffffff;
this.words[j + 1] |= w >>> 26 - off & 0x3fffff;
}
this.strip();
};
function parseBase(str, start, end, mul) {
var r = 0;
var len = Math.min(str.length, end);
for(var i = start; i < len; i++){
var c = str.charCodeAt(i) - 48;
r *= mul;
// 'a'
if (c >= 49) r += c - 49 + 0xa;
else if (c >= 17) r += c - 17 + 0xa;
else r += c;
}
return r;
}
BN.prototype._parseBase = function _parseBase(number, base, start) {
// Initialize as zero
this.words = [
0
];
this.length = 1;
// Find length of limb in base
for(var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base)limbLen++;
limbLen--;
limbPow = limbPow / base | 0;
var total = number.length - start;
var mod = total % limbLen;
var end = Math.min(total, total - mod) + start;
var word = 0;
for(var i = start; i < end; i += limbLen){
word = parseBase(number, i, i + limbLen, base);
this.imuln(limbPow);
if (this.words[0] + word < 0x4000000) this.words[0] += word;
else this._iaddn(word);
}
if (mod !== 0) {
var pow = 1;
word = parseBase(number, i, number.length, base);
for(i = 0; i < mod; i++)pow *= base;
this.imuln(pow);
if (this.words[0] + word < 0x4000000) this.words[0] += word;
else this._iaddn(word);
}
};
BN.prototype.copy = function copy(dest) {
dest.words = new Array(this.length);
for(var i = 0; i < this.length; i++)dest.words[i] = this.words[i];
dest.length = this.length;
dest.negative = this.negative;
dest.red = this.red;
};
BN.prototype.clone = function clone() {
var r = new BN(null);
this.copy(r);
return r;
};
BN.prototype._expand = function _expand(size) {
while(this.length < size)this.words[this.length++] = 0;
return this;
};
// Remove leading `0` from `this`
BN.prototype.strip = function strip() {
while(this.length > 1 && this.words[this.length - 1] === 0)this.length--;
return this._normSign();
};
BN.prototype._normSign = function _normSign() {
// -0 = 0
if (this.length === 1 && this.words[0] === 0) this.negative = 0;
return this;
};
BN.prototype.inspect = function inspect() {
return (this.red ? "<BN-R: " : "<BN: ") + this.toString(16) + ">";
};
/*
var zeros = [];
var groupSizes = [];
var groupBases = [];
var s = '';
var i = -1;
while (++i < BN.wordSize) {
zeros[i] = s;
s += '0';
}
groupSizes[0] = 0;
groupSizes[1] = 0;
groupBases[0] = 0;
groupBases[1] = 0;
var base = 2 - 1;
while (++base < 36 + 1) {
var groupSize = 0;
var groupBase = 1;
while (groupBase < (1 << BN.wordSize) / base) {
groupBase *= base;
groupSize += 1;
}
groupSizes[base] = groupSize;
groupBases[base] = groupBase;
}
*/ 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"
];
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
];
var groupBases = [
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
];
BN.prototype.toString = function toString(base, padding) {
base = base || 10;
padding = padding | 0 || 1;
var out;
if (base === 16 || base === "hex") {
out = "";
var off = 0;
var carry = 0;
for(var i = 0; i < this.length; i++){
var w = this.words[i];
var word = ((w << off | carry) & 0xffffff).toString(16);
carry = w >>> 24 - off & 0xffffff;
off += 2;
if (off >= 26) {
off -= 26;
i--;
}
if (carry !== 0 || i !== this.length - 1) out = zeros[6 - word.length] + word + out;
else out = word + out;
}
if (carry !== 0) out = carry.toString(16) + out;
while(out.length % padding !== 0)out = "0" + out;
if (this.negative !== 0) out = "-" + out;
return out;
}
if (base === (base | 0) && base >= 2 && base <= 36) {
// var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
var groupSize = groupSizes[base];
// var groupBase = Math.pow(base, groupSize);
var groupBase = groupBases[base];
out = "";
var c = this.clone();
c.negative = 0;
while(!c.isZero()){
var r = c.modn(groupBase).toString(base);
c = c.idivn(groupBase);
if (!c.isZero()) out = zeros[groupSize - r.length] + r + out;
else out = r + out;
}
if (this.isZero()) out = "0" + out;
while(out.length % padding !== 0)out = "0" + out;
if (this.negative !== 0) out = "-" + out;
return out;
}
assert(false, "Base should be between 2 and 36");
};
BN.prototype.toNumber = function toNumber() {
var ret = this.words[0];
if (this.length === 2) 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;
else if (this.length > 2) assert(false, "Number can only safely store up to 53 bits");
return this.negative !== 0 ? -ret : ret;
};
BN.prototype.toJSON = function toJSON() {
return this.toString(16);
};
BN.prototype.toBuffer = function toBuffer(endian, length) {
assert(typeof Buffer !== "undefined");
return this.toArrayLike(Buffer, endian, length);
};
BN.prototype.toArray = function toArray(endian, length) {
return this.toArrayLike(Array, endian, length);
};
BN.prototype.toArrayLike = function toArrayLike(ArrayType, endian, length) {
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");
this.strip();
var littleEndian = endian === "le";
var res = new ArrayType(reqLength);
var b, i;
var q = this.clone();
if (!littleEndian) {
// Assume big-endian
for(i = 0; i < reqLength - byteLength; i++)res[i] = 0;
for(i = 0; !q.isZero(); i++){
b = q.andln(0xff);
q.iushrn(8);
res[reqLength - i - 1] = b;
}
} else {
for(i = 0; !q.isZero(); i++){
b = q.andln(0xff);
q.iushrn(8);
res[i] = b;
}
for(; i < reqLength; i++)res[i] = 0;
}
return res;
};
if (Math.clz32) BN.prototype._countBits = function _countBits(w) {
return 32 - Math.clz32(w);
};
else BN.prototype._countBits = function _countBits(w) {
var t = w;
var r = 0;
if (t >= 0x1000) {
r += 13;
t >>>= 13;
}
if (t >= 0x40) {
r += 7;
t >>>= 7;
}
if (t >= 0x8) {
r += 4;
t >>>= 4;
}
if (t >= 0x02) {
r += 2;
t >>>= 2;
}
return r + t;
};
BN.prototype._zeroBits = function _zeroBits(w) {
// Short-cut
if (w === 0) return 26;
var t = w;
var r = 0;
if ((t & 0x1fff) === 0) {
r += 13;
t >>>= 13;
}
if ((t & 0x7f) === 0) {
r += 7;
t >>>= 7;
}
if ((t & 0xf) === 0) {
r += 4;
t >>>= 4;
}
if ((t & 0x3) === 0) {
r += 2;
t >>>= 2;
}
if ((t & 0x1) === 0) r++;
return r;
};
// Return number of used bits in a BN
BN.prototype.bitLength = function bitLength() {
var w = this.words[this.length - 1];
var hi = this._countBits(w);
return (this.length - 1) * 26 + hi;
};
function toBitArray(num) {
var w = new Array(num.bitLength());
for(var bit = 0; bit < w.length; bit++){
var off = bit / 26 | 0;
var wbit = bit % 26;
w[bit] = (num.words[off] & 1 << wbit) >>> wbit;
}
return w;
}
// Number of trailing zero bits
BN.prototype.zeroBits = function zeroBits() {
if (this.isZero()) return 0;
var r = 0;
for(var i = 0; i < this.length; i++){
var b = this._zeroBits(this.words[i]);
r += b;
if (b !== 26) break;
}
return r;
};
BN.prototype.byteLength = function byteLength() {
return Math.ceil(this.bitLength() / 8);
};
BN.prototype.toTwos = function toTwos(width) {
if (this.negative !== 0) return this.abs().inotn(width).iaddn(1);
return this.clone();
};
BN.prototype.fromTwos = function fromTwos(width) {
if (this.testn(width - 1)) return this.notn(width).iaddn(1).ineg();
return this.clone();
};
BN.prototype.isNeg = function isNeg() {
return this.negative !== 0;
};
// Return negative clone of `this`
BN.prototype.neg = function neg() {
return this.clone().ineg();
};
BN.prototype.ineg = function ineg() {
if (!this.isZero()) this.negative ^= 1;
return this;
};
// Or `num` with `this` in-place
BN.prototype.iuor = function iuor(num) {
while(this.length < num.length)this.words[this.length++] = 0;
for(var i = 0; i < num.length; i++)this.words[i] = this.words[i] | num.words[i];
return this.strip();
};
BN.prototype.ior = function ior(num) {
assert((this.negative | num.negative) === 0);
return this.iuor(num);
};
// Or `num` with `this`
BN.prototype.or = function or(num) {
if (this.length > num.length) return this.clone().ior(num);
return num.clone().ior(this);
};
BN.prototype.uor = function uor(num) {
if (this.length > num.length) return this.clone().iuor(num);
return num.clone().iuor(this);
};
// And `num` with `this` in-place
BN.prototype.iuand = function iuand(num) {
// b = min-length(num, this)
var b;
if (this.length > num.length) b = num;
else b = this;
for(var i = 0; i < b.length; i++)this.words[i] = this.words[i] & num.words[i];
this.length = b.length;
return this.strip();
};
BN.prototype.iand = function iand(num) {
assert((this.negative | num.negative) === 0);
return this.iuand(num);
};
// And `num` with `this`
BN.prototype.and = function and(num) {
if (this.length > num.length) return this.clone().iand(num);
return num.clone().iand(this);
};
BN.prototype.uand = function uand(num) {
if (this.length > num.length) return this.clone().iuand(num);
return num.clone().iuand(this);
};
// Xor `num` with `this` in-place
BN.prototype.iuxor = function iuxor(num) {
// a.length > b.length
var a;
var b;
if (this.length > num.length) {
a = this;
b = num;
} else {
a = num;
b = this;
}
for(var i = 0; i < b.length; i++)this.words[i] = a.words[i] ^ b.words[i];
if (this !== a) for(; i < a.length; i++)this.words[i] = a.words[i];
this.length = a.length;
return this.strip();
};
BN.prototype.ixor = function ixor(num) {
assert((this.negative | num.negative) === 0);
return this.iuxor(num);
};
// Xor `num` with `this`
BN.prototype.xor = function xor(num) {
if (this.length > num.length) return this.clone().ixor(num);
return num.clone().ixor(this);
};
BN.prototype.uxor = function uxor(num) {
if (this.length > num.length) return this.clone().iuxor(num);
return num.clone().iuxor(this);
};
// Not ``this`` with ``width`` bitwidth
BN.prototype.inotn = function inotn(width) {
assert(typeof width === "number" && width >= 0);
var bytesNeeded = Math.ceil(width / 26) | 0;
var bitsLeft = width % 26;
// Extend the buffer with leading zeroes
this._expand(bytesNeeded);
if (bitsLeft > 0) bytesNeeded--;
// Handle complete words
for(var i = 0; i < bytesNeeded; i++)this.words[i] = ~this.words[i] & 0x3ffffff;
// Handle the residue
if (bitsLeft > 0) this.words[i] = ~this.words[i] & 0x3ffffff >> 26 - bitsLeft;
// And remove leading zeroes
return this.strip();
};
BN.prototype.notn = function notn(width) {
return this.clone().inotn(width);
};
// Set `bit` of `this`
BN.prototype.setn = function setn(bit, val) {
assert(typeof bit === "number" && bit >= 0);
var off = bit / 26 | 0;
var wbit = bit % 26;
this._expand(off + 1);
if (val) this.words[off] = this.words[off] | 1 << wbit;
else this.words[off] = this.words[off] & ~(1 << wbit);
return this.strip();
};
// Add `num` to `this` in-place
BN.prototype.iadd = function iadd(num) {
var r;
// negative + positive
if (this.negative !== 0 && num.negative === 0) {
this.negative = 0;
r = this.isub(num);
this.negative ^= 1;
return this._normSign();
// positive + negative
} else if (this.negative === 0 && num.negative !== 0) {
num.negative = 0;
r = this.isub(num);
num.negative = 1;
return r._normSign();
}
// a.length > b.length
var a, b;
if (this.length > num.length) {
a = this;
b = num;
} else {
a = num;
b = this;
}
var carry = 0;
for(var i = 0; i < b.length; i++){
r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
this.words[i] = r & 0x3ffffff;
carry = r >>> 26;
}
for(; carry !== 0 && i < a.length; i++){
r = (a.words[i] | 0) + carry;
this.words[i] = r & 0x3ffffff;
carry = r >>> 26;
}
this.length = a.length;
if (carry !== 0) {
this.words[this.length] = carry;
this.length++;
// Copy the rest of the words
} else if (a !== this) for(; i < a.length; i++)this.words[i] = a.words[i];
return this;
};
// Add `num` to `this`
BN.prototype.add = function add(num) {
var res;
if (num.negative !== 0 && this.negative === 0) {
num.negative = 0;
res = this.sub(num);
num.negative ^= 1;
return res;
} else if (num.negative === 0 && this.negative !== 0) {
this.negative = 0;
res = num.sub(this);
this.negative = 1;
return res;
}
if (this.length > num.length) return this.clone().iadd(num);
return num.clone().iadd(this);
};
// Subtract `num` from `this` in-place
BN.prototype.isub = function isub(num) {
// this - (-num) = this + num
if (num.negative !== 0) {
num.negative = 0;
var r = this.iadd(num);
num.negative = 1;
return r._normSign();
// -this - num = -(this + num)
} else if (this.negative !== 0) {
this.negative = 0;
this.iadd(num);
this.negative = 1;
return this._normSign();
}
// At this point both numbers are positive
var cmp = this.cmp(num);
// Optimization - zeroify
if (cmp === 0) {
this.negative = 0;
this.length = 1;
this.words[0] = 0;
return this;
}
// a > b
var a, b;
if (cmp > 0) {
a = this;
b = num;
} else {
a = num;
b = this;
}
var carry = 0;
for(var i = 0; i < b.length; i++){
r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
carry = r >> 26;
this.words[i] = r & 0x3ffffff;
}
for(; carry !== 0 && i < a.length; i++){
r = (a.words[i] | 0) + carry;
carry = r >> 26;
this.words[i] = r & 0x3ffffff;
}
// Copy rest of the words
if (carry === 0 && i < a.length && a !== this) for(; i < a.length; i++)this.words[i] = a.words[i];
this.length = Math.max(this.length, i);
if (a !== this) this.negative = 1;
return this.strip();
};
// Subtract `num` from `this`
BN.prototype.sub = function sub(num) {
return this.clone().isub(num);
};
function smallMulTo(self, num, out) {
out.negative = num.negative ^ self.negative;
var len = self.length + num.length | 0;
out.length = len;
len = len - 1 | 0;
// Peel one iteration (compiler can't do it, because of code complexity)
var a = self.words[0] | 0;
var b = num.words[0] | 0;
var r = a * b;
var lo = r & 0x3ffffff;
var carry = r / 0x4000000 | 0;
out.words[0] = lo;
for(var k = 1; k < len; k++){
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
// note that ncarry could be >= 0x3ffffff
var ncarry = carry >>> 26;
var rword = carry & 0x3ffffff;
var maxJ = Math.min(k, num.length - 1);
for(var j = Math.max(0, k - self.length + 1); j <= maxJ; j++){
var i = k - j | 0;
a = self.words[i] | 0;
b = num.words[j] | 0;
r = a * b + rword;
ncarry += r / 0x4000000 | 0;
rword = r & 0x3ffffff;
}
out.words[k] = rword | 0;
carry = ncarry | 0;
}
if (carry !== 0) out.words[k] = carry | 0;
else out.length--;
return out.strip();
}
// TODO(indutny): it may be reasonable to omit it for users who don't need
// to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
// multiplication (like elliptic secp256k1).
var comb10MulTo = function comb10MulTo(self, num, out) {
var a = self.words;
var b = num.words;
var o = out.words;
var c = 0;
var lo;
var mid;
var hi;
var a0 = a[0] | 0;
var al0 = a0 & 0x1fff;
var ah0 = a0 >>> 13;
var a1 = a[1] | 0;
var al1 = a1 & 0x1fff;
var ah1 = a1 >>> 13;
var a2 = a[2] | 0;
var al2 = a2 & 0x1fff;
var ah2 = a2 >>> 13;
var a3 = a[3] | 0;
var al3 = a3 & 0x1fff;
var ah3 = a3 >>> 13;
var a4 = a[4] | 0;
var al4 = a4 & 0x1fff;
var ah4 = a4 >>> 13;
var a5 = a[5] | 0;
var al5 = a5 & 0x1fff;
var ah5 = a5 >>> 13;
var a6 = a[6] | 0;
var al6 = a6 & 0x1fff;
var ah6 = a6 >>> 13;
var a7 = a[7] | 0;
var al7 = a7 & 0x1fff;
var ah7 = a7 >>> 13;
var a8 = a[8] | 0;
var al8 = a8 & 0x1fff;
var ah8 = a8 >>> 13;
var a9 = a[9] | 0;
var al9 = a9 & 0x1fff;
var ah9 = a9 >>> 13;
var b0 = b[0] | 0;
var bl0 = b0 & 0x1fff;
var bh0 = b0 >>> 13;
var b1 = b[1] | 0;
var bl1 = b1 & 0x1fff;
var bh1 = b1 >>> 13;
var b2 = b[2] | 0;
var bl2 = b2 & 0x1fff;
var bh2 = b2 >>> 13;
var b3 = b[3] | 0;
var bl3 = b3 & 0x1fff;
var bh3 = b3 >>> 13;
var b4 = b[4] | 0;
var bl4 = b4 & 0x1fff;
var bh4 = b4 >>> 13;
var b5 = b[5] | 0;
var bl5 = b5 & 0x1fff;
var bh5 = b5 >>> 13;
var b6 = b[6] | 0;
var bl6 = b6 & 0x1fff;
var bh6 = b6 >>> 13;
var b7 = b[7] | 0;
var bl7 = b7 & 0x1fff;
var bh7 = b7 >>> 13;
var b8 = b[8] | 0;
var bl8 = b8 & 0x1fff;
var bh8 = b8 >>> 13;
var b9 = b[9] | 0;
var bl9 = b9 & 0x1fff;
var bh9 = b9 >>> 13;
out.negative = self.negative ^ num.negative;
out.length = 19;
/* k = 0 */ lo = Math.imul(al0, bl0);
mid = Math.imul(al0, bh0);
mid = mid + Math.imul(ah0, bl0) | 0;
hi = Math.imul(ah0, bh0);
var w0 = (c + lo | 0) + ((mid & 0x1fff) << 13) | 0;
c = (hi + (mid >>> 13) | 0) + (w0 >>> 26) | 0;
w0 &= 0x3ffffff;
/* k = 1 */ lo = Math.imul(al1, bl0);
mid = Math.imul(al1, bh0);
mid = mid + Math.imul(ah1, bl0) | 0;
hi = Math.imul(ah1, bh0);
lo = lo + Math.imul(al0, bl1) | 0;
mid = mid + Math.imul(al0, bh1) | 0;
mid = mid + Math.imul(ah0, bl1) | 0;
hi = hi + Math.imul(ah0, bh1) | 0;
var w1 = (c + lo | 0) + ((mid & 0x1fff) << 13) | 0;
c = (hi + (mid >>> 13) | 0) + (w1 >>> 26) | 0;
w1 &= 0x3ffffff;
/* k = 2 */ lo = Math.imul(al2, bl0);
mid = Math.imul(al2, bh0);
mid = mid + Math.imul(ah2, bl0) | 0;
hi = Math.imul(ah2, bh0);
lo = lo + Math.imul(al1, bl1) | 0;
mid = mid + Math.imul(al1, bh1) | 0;
mid = mid + Math.imul(ah1, bl1) | 0;
hi = hi + Math.imul(ah1, bh1) | 0;
lo = lo + Math.imul(al0, bl2) | 0;
mid = mid + Math.imul(al0, bh2) | 0;
mid = mid + Math.imul(ah0, bl2) | 0;
hi = hi + Math.imul(ah0, bh2) | 0;
var w2 = (c + lo | 0) + ((mid & 0x1fff) << 13) | 0;
c = (hi + (mid >>> 13) | 0) + (w2 >>> 26) | 0;
w2 &= 0x3ffffff;
/* k = 3 */ lo = Math.imul(al3, bl0);
mid = Math.imul(al3, bh0);
mid = mid + Math.imul(ah3, bl0) | 0;
hi = Math.imul(ah3, bh0);
lo = lo + Math.imul(al2, bl1) | 0;
mid = mid + Math.imul(al2, bh1) | 0;
mid = mid + Math.imul(ah2, bl1) | 0;
hi = hi + Math.imul(ah2, bh1) | 0;
lo = lo + Math.imul(al1, bl2) | 0;
mid = mid + Math.imul(al1, bh2) | 0;
mid = mid + Math.imul(ah1, bl2) | 0;
hi = hi + Math.imul(ah1, bh2) | 0;
lo = lo + Math.imul(al0, bl3) | 0;
mid = mid + Math.imul(al0, bh3) | 0;
mid = mid + Math.imul(ah0, bl3) | 0;
hi = hi + Math.imul(ah0, bh3) | 0;
var w3 = (c + lo | 0) + ((mid & 0x1fff) << 13) | 0;
c = (hi + (mid >>> 13) | 0) + (w3 >>> 26) | 0;
w3 &= 0x3ffffff;
/* k = 4 */ lo = Math.imul(al4, bl0);
mid = Math.imul(al4, bh0);
mid = mid + Math.imul(ah4, bl0) | 0;
hi = Math.imul(ah4, bh0);
lo = lo + Math.imul(al3, bl1) | 0;
mid = mid + Math.imul(al3, bh1) | 0;
mid = mid + Math.imul(ah3, bl1) | 0;
hi = hi + Math.imul(ah3, bh1) | 0;
lo = lo + Math.imul(al2, bl2) | 0;
mid = mid + Math.imul(al2, bh2) | 0;
mid = mid + Math.imul(ah2, bl2) | 0;
hi = hi + Math.imul(ah2, bh2) | 0;
lo = lo + Math.imul(al1, bl3) | 0;
mid = mid + Math.imul(al1, bh3) | 0;
mid = mid + Math.imul(ah1, bl3) | 0;
hi = hi + Math.imul(ah1, bh3) | 0;
lo = lo + Math.imul(al0, bl4) | 0;
mid = mid + Math.imul(al0, bh4) | 0;
mid = mid + Math.imul(ah0, bl4) | 0;
hi = hi + Math.imul(ah0, bh4) | 0;
var w4 = (c + lo | 0) + ((mid & 0x1fff) << 13) | 0;
c = (hi + (mid >>> 13) | 0) + (w4 >>> 26) | 0;
w4 &= 0x3ffffff;
/* k = 5 */ lo = Math.imul(al5, bl0);
mid = Math.imul(al5, bh0);
mid = mid + Math.imul(ah5, bl0) | 0;
hi = Math.imul(ah5, bh0);
lo = lo + Math.imul(al4, bl1) | 0;
mid = mid + Math.imul(al4, bh1) | 0;
mid = mid + Math.imul(ah4, bl1) | 0;
hi = hi + Math.imul(ah4, bh1) | 0;
lo = lo + Math.imul(al3, bl2) | 0;
mid = mid + Math.imul(al3, bh2) | 0;
mid = mid + Math.imul(ah3, bl2) | 0;
hi = hi + Math.imul(ah3, bh2) | 0;
lo = lo + Math.imul(al2, bl3) | 0;
mid = mid + Math.imul(al2, bh3) | 0;
mid = mid + Math.imul(ah2, bl3) | 0;
hi = hi + Math.imul(ah2, bh3) | 0;
lo = lo + Math.imul(al1, bl4) | 0;
mid = mid + Math.imul(al1, bh4) | 0;
mid = mid + Math.imul(ah1, bl4) | 0;
hi = hi + Math.imul(ah1, bh4) | 0;
lo = lo + Math.imul(al0, bl5) | 0;
mid = mid + Math.imul(al0, bh5) | 0;
mid = mid + Math.imul(ah0, bl5) | 0;
hi = hi + Math.imul(ah0, bh5) | 0;
var w5 = (c + lo | 0) + ((mid & 0x1fff) << 13) | 0;
c = (hi + (mid >>> 13) | 0) + (w5 >>> 26) | 0;
w5 &= 0x3ffffff;
/* k = 6 */ lo = Math.imul(al6, bl0);
mid = Math.imul(al6, bh0);
mid = mid + Math.imul(ah6, bl0) | 0;
hi = Math.imul(ah6, bh0);
lo = lo + Math.imul(al5, bl1) | 0;
mid = mid + Math.imul(al5, bh1) | 0;
mid = mid + Math.imul(ah5, bl1) | 0;
hi = hi + Math.imul(ah5, bh1) | 0;
lo = lo + Math.imul(al4, bl2) | 0;
mid = mid + Math.imul(al4, bh2) | 0;
mid = mid + Math.imul(ah4, bl2) | 0;
hi = hi + Math.imul(ah4, bh2) | 0;
lo = lo + Math.imul(al3, bl3) | 0;
mid = mid + Math.imul(al3, bh3) | 0;
mid = mid + Math.imul(ah3, bl3) | 0;
hi = hi + Math.imul(ah3, bh3) | 0;
lo = lo + Math.imul(al2, bl4) | 0;
mid = mid + Math.imul(al2, bh4) | 0;
mid = mid + Math.imul(ah2, bl4) | 0;
hi = hi + Math.imul(ah2, bh4) | 0;
lo = lo + Math.imul(al1, bl5) | 0;
mid = mid + Math.imul(al1, bh5) | 0;
mid = mid + Math.imul(ah1, bl5) | 0;
hi = hi + Math.imul(ah1, bh5) | 0;
lo = lo + Math.imul(al0, bl6) | 0;
mid = mid + Math.imul(al0, bh6) | 0;
mid = mid + Math.imul(ah0, bl6) | 0;
hi = hi + Math.imul(ah0, bh6) | 0;
var w6 = (c + lo | 0) + ((mid & 0x1fff) << 13) | 0;
c = (hi + (mid >>> 13) | 0) + (w6 >>> 26) | 0;
w6 &= 0x3ffffff;
/* k = 7 */ lo = Math.imul(al7, bl0);
mid = Math.imul(al7, bh0);
mid = mid + Math.imul(ah7, bl0) | 0;
hi = Math.imul(ah7, bh0);
lo = lo + Math.imul(al6, bl1) | 0;
mid = mid + Math.imul(al6, bh1) | 0;
mid = mid + Math.imul(ah6, bl1) | 0;
hi = hi + Math.imul(ah6, bh1) | 0;
lo = lo + Math.imul(al5, bl2) | 0;
mid = mid + Math.imul(al5, bh2) | 0;
mid = mid + Math.imul(ah5, bl2) | 0;
hi = hi + Math.imul(ah5, bh2) | 0;
lo = lo + Math.imul(al4, bl3) | 0;
mid = mid + Math.imul(al4, bh3) | 0;
mid = mid + Math.imul(ah4, bl3) | 0;
hi = hi + Math.imul(ah4, bh3) | 0;
lo = lo + Math.imul(al3, bl4) | 0;
mid = mid + Math.imul(al3, bh4) | 0;
mid = mid + Math.imul(ah3, bl4) | 0;
hi = hi + Math.imul(ah3, bh4) | 0;
lo = lo + Math.imul(al2, bl5) | 0;
mid = mid + Math.imul(al2, bh5) | 0;
mid = mid + Math.imul(ah2, bl5) | 0;
hi = hi + Math.imul(ah2, bh5) | 0;
lo = lo + Math.imul(al1, bl6) | 0;
mid = mid + Math.imul(al1, bh6) | 0;
mid = mid + Math.imul(ah1, bl6) | 0;
hi = hi + Math.imul(ah1, bh6) | 0;
lo = lo + Math.imul(al0, bl7) | 0;
mid = mid + Math.imul(al0, bh7) | 0;
mid = mid + Math.imul(ah0, bl7) | 0;
hi = hi + Math.imul(ah0, bh7) | 0;
var w7 = (c + lo | 0) + ((mid & 0x1fff) << 13) | 0;
c = (hi + (mid >>> 13) | 0) + (w7 >>> 26) | 0;
w7 &= 0x3ffffff;
/* k = 8 */ lo = Math.imul(al8, bl0);
mid = Math.imul(al8, bh0);
mid = mid + Math.imul(ah8, bl0) | 0;
hi = Math.imul(ah8, bh0);
lo = lo + Math.imul(al7, bl1) | 0;
mid = mid + Math.imul(al7, bh1) | 0;
mid = mid + Math.imul(ah7, bl1) | 0;
hi = hi + Math.imul(ah7, bh1) | 0;
lo = lo + Math.imul(al6, bl2) | 0;
mid = mid + Math.imul(al6, bh2) | 0;
mid = mid + Math.imul(ah6, bl2) | 0;
hi = hi + Math.imul(ah6, bh2) | 0;
lo = lo + Math.imul(al5, bl3) | 0;
mid = mid + Math.imul(al5, bh3) | 0;
mid = mid + Math.imul(ah5, bl3) | 0;
hi = hi + Math.imul(ah5, bh3) | 0;
lo = lo + Math.imul(al4, bl4) | 0;
mid = mid + Math.imul(al4, bh4) | 0;
mid = mid + Math.imul(ah4, bl4) | 0;
hi = hi + Math.imul(ah4, bh4) | 0;
lo = lo + Math.imul(al3, bl5) | 0;
mid = mid + Math.imul(al3, bh5) | 0;
mid = mid + Math.imul(ah3, bl5) | 0;
hi = hi + Math.imul(ah3, bh5) | 0;
lo = lo + Math.imul(al2, bl6) | 0;
mid = mid + Math.imul(al2, bh6) | 0;
mid = mid + Math.imul(ah2, bl6) | 0;
hi = hi + Math.imul(ah2, bh6) | 0;
lo = lo + Math.imul(al1, bl7) | 0;
mid = mid + Math.imul(al1, bh7) | 0;
mid = mid + Math.imul(ah1, bl7) | 0;
hi = hi + Math.imul(ah1, bh7) | 0;
lo = lo + Math.imul(al0, bl8) | 0;
mid = mid + Math.imul(al0, bh8) | 0;
mid = mid + Math.imul(ah0, bl8) | 0;
hi = hi + Math.imul(ah0, bh8) | 0;
var w8 = (c + lo | 0) + ((mid & 0x1fff) << 13) | 0;
c = (hi + (mid >>> 13) | 0) + (w8 >>> 26) | 0;
w8 &= 0x3ffffff;
/* k = 9 */ lo = Math.imul(al9, bl0);
mid = Math.imul(al9, bh0);
mid = mid + Math.imul(ah9, bl0) | 0;
hi = Math.imul(ah9, bh0);
lo = lo + Math.imul(al8, bl1) | 0;
mid = mid + Math.imul(al8, bh1) | 0;
mid = mid + Math.imul(ah8, bl1) | 0;
hi = hi + Math.imul(ah8, bh1) | 0;
lo = lo + Math.imul(al7, bl2) | 0;
mid = mid + Math.imul(al7, bh2) | 0;
mid = mid + Math.imul(ah7, bl2) | 0;
hi = hi + Math.imul(ah7, bh2) | 0;
lo = lo + Math.imul(al6, bl3) | 0;
mid = mid + Math.imul(al6, bh3) | 0;
mid = mid + Math.imul(ah6, bl3) | 0;
hi = hi + Math.imul(ah6, bh3) | 0;
lo = lo + Math.imul(al5, bl4) | 0;
mid = mid + Math.imul(al5, bh4) | 0;
mid = mid + Math.imul(ah5, bl4) | 0;
hi = hi