UNPKG

@scrypt-inc/bsv

Version:

A pure and powerful JavaScript Bitcoin SV (BSV) library.

1,393 lines (1,376 loc) 793 kB
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