pax_global_header00006660000000000000000000000064140152573440014517gustar00rootroot0000000000000052 comment=5d5532d9fb7192b5d2545bdb2aa024ca1822a313 bn.js-5.2.0/000077500000000000000000000000001401525734400125355ustar00rootroot00000000000000bn.js-5.2.0/.eslintrc.yaml000066400000000000000000000003121401525734400153160ustar00rootroot00000000000000--- plugins: - es5 extends: - plugin:es5/no-es2015 rules: es5/no-es6-static-methods: - error - exceptMethods: - Math.imul semi: - 2 - always no-extra-semi: 2 no-var: 0 bn.js-5.2.0/.github/000077500000000000000000000000001401525734400140755ustar00rootroot00000000000000bn.js-5.2.0/.github/workflows/000077500000000000000000000000001401525734400161325ustar00rootroot00000000000000bn.js-5.2.0/.github/workflows/ci.yaml000066400000000000000000000017721401525734400174200ustar00rootroot00000000000000name: CI on: [push, pull_request] env: CI: true jobs: test: name: Run tests runs-on: ubuntu-latest steps: - name: Fetch code uses: actions/checkout@v2 with: fetch-depth: 1 - name: Restore node_modules cache uses: actions/cache@v1 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package.json') }} - name: Install dependencies run: npm install --ignore-scripts - name: Run tests run: npm run unit lint: name: Run lint runs-on: ubuntu-latest steps: - name: Fetch code uses: actions/checkout@v2 with: fetch-depth: 1 - name: Restore node_modules cache uses: actions/cache@v1 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package.json') }} - name: Install dependencies run: npm install --ignore-scripts - name: Run lint command run: npm run lint bn.js-5.2.0/.gitignore000066400000000000000000000001221401525734400145200ustar00rootroot00000000000000coverage/ node_modules/ npm-debug.log package-lock.json yarn.lock yarn-error.log bn.js-5.2.0/CHANGELOG.md000066400000000000000000000030011401525734400143400ustar00rootroot000000000000005.2.0 / 2021-02-23 ------------------ - fix: Buffer not using global in browser (#260) - Fix LE constructor for HEX (#265) 5.1.3 / 2020-08-14 ------------------ - Add support for defined but not implemented Symbol.for (#252) 5.1.2 / 2020-05-20 ------------------ - Fix BN v5/v4 interoperability issue (#249) 5.1.1 / 2019-12-24 ------------------ - Temporary workaround for BN#_move (#236) - Add eslintrc instead config in package.json (#237) 5.1.0 / 2019-12-23 ------------------ - Benchmark for BigInt (#226) - Add documentation for max/min (#232) - Update BN#inspect for Symbols (#225) - Improve performance of toArrayLike (#222) - temporary disable jumboMulTo in BN#mulTo (#221) - optimize toBitArray function (#212) - fix iaddn sign issue (#216) 5.0.0 / 2019-07-04 ------------------ - travis: update node versions (#205) - Refactor buffer constructor (#200) - lib: fix for negative numbers: imuln, modrn, idivn (#185) - bn: fix Red#imod (#178) - check unexpected high bits for invalid characters (#173) - document support very large integers (#158) - only define toBuffer if Buffer is defined (#172) - lib: better validation of string input (#151) - tests: reject decimal input in constructor (#91) - bn: make .strip() an internal method (#105) - lib: deprecate `.modn()` introduce `.modrn()` (#112 #129 #130) - bn: don't accept invalid characters (#141) - package: use `files` insteadof `.npmignore` (#152) - bn: improve allocation speed for buffers (#167) - toJSON to default to interoperable hex (length % 2) (#164) bn.js-5.2.0/LICENSE000066400000000000000000000020371401525734400135440ustar00rootroot00000000000000Copyright Fedor Indutny, 2015. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. bn.js-5.2.0/README.md000066400000000000000000000145741401525734400140270ustar00rootroot00000000000000# bn.js > BigNum in pure javascript [![Build Status](https://secure.travis-ci.org/indutny/bn.js.png)](http://travis-ci.org/indutny/bn.js) ## Install `npm install --save bn.js` ## Usage ```js const BN = require('bn.js'); var a = new BN('dead', 16); var b = new BN('101010', 2); var res = a.add(b); console.log(res.toString(10)); // 57047 ``` **Note**: decimals are not supported in this library. ## Notation ### Prefixes There are several prefixes to instructions that affect the way the work. Here is the list of them in the order of appearance in the function name: * `i` - perform operation in-place, storing the result in the host object (on which the method was invoked). Might be used to avoid number allocation costs * `u` - unsigned, ignore the sign of operands when performing operation, or always return positive value. Second case applies to reduction operations like `mod()`. In such cases if the result will be negative - modulo will be added to the result to make it positive ### Postfixes * `n` - the argument of the function must be a plain JavaScript Number. Decimals are not supported. * `rn` - both argument and return value of the function are plain JavaScript Numbers. Decimals are not supported. ### Examples * `a.iadd(b)` - perform addition on `a` and `b`, storing the result in `a` * `a.umod(b)` - reduce `a` modulo `b`, returning positive value * `a.iushln(13)` - shift bits of `a` left by 13 ## Instructions Prefixes/postfixes are put in parens at the of the line. `endian` - could be either `le` (little-endian) or `be` (big-endian). ### Utilities * `a.clone()` - clone number * `a.toString(base, length)` - convert to base-string and pad with zeroes * `a.toNumber()` - convert to Javascript Number (limited to 53 bits) * `a.toJSON()` - convert to JSON compatible hex string (alias of `toString(16)`) * `a.toArray(endian, length)` - convert to byte `Array`, and optionally zero pad to length, throwing if already exceeding * `a.toArrayLike(type, endian, length)` - convert to an instance of `type`, which must behave like an `Array` * `a.toBuffer(endian, length)` - convert to Node.js Buffer (if available). For compatibility with browserify and similar tools, use this instead: `a.toArrayLike(Buffer, endian, length)` * `a.bitLength()` - get number of bits occupied * `a.zeroBits()` - return number of less-significant consequent zero bits (example: `1010000` has 4 zero bits) * `a.byteLength()` - return number of bytes occupied * `a.isNeg()` - true if the number is negative * `a.isEven()` - no comments * `a.isOdd()` - no comments * `a.isZero()` - no comments * `a.cmp(b)` - compare numbers and return `-1` (a `<` b), `0` (a `==` b), or `1` (a `>` b) depending on the comparison result (`ucmp`, `cmpn`) * `a.lt(b)` - `a` less than `b` (`n`) * `a.lte(b)` - `a` less than or equals `b` (`n`) * `a.gt(b)` - `a` greater than `b` (`n`) * `a.gte(b)` - `a` greater than or equals `b` (`n`) * `a.eq(b)` - `a` equals `b` (`n`) * `a.toTwos(width)` - convert to two's complement representation, where `width` is bit width * `a.fromTwos(width)` - convert from two's complement representation, where `width` is the bit width * `BN.isBN(object)` - returns true if the supplied `object` is a BN.js instance * `BN.max(a, b)` - return `a` if `a` bigger than `b` * `BN.min(a, b)` - return `a` if `a` less than `b` ### Arithmetics * `a.neg()` - negate sign (`i`) * `a.abs()` - absolute value (`i`) * `a.add(b)` - addition (`i`, `n`, `in`) * `a.sub(b)` - subtraction (`i`, `n`, `in`) * `a.mul(b)` - multiply (`i`, `n`, `in`) * `a.sqr()` - square (`i`) * `a.pow(b)` - raise `a` to the power of `b` * `a.div(b)` - divide (`divn`, `idivn`) * `a.mod(b)` - reduct (`u`, `n`) (but no `umodn`) * `a.divmod(b)` - quotient and modulus obtained by dividing * `a.divRound(b)` - rounded division ### Bit operations * `a.or(b)` - or (`i`, `u`, `iu`) * `a.and(b)` - and (`i`, `u`, `iu`, `andln`) (NOTE: `andln` is going to be replaced with `andn` in future) * `a.xor(b)` - xor (`i`, `u`, `iu`) * `a.setn(b, value)` - set specified bit to `value` * `a.shln(b)` - shift left (`i`, `u`, `iu`) * `a.shrn(b)` - shift right (`i`, `u`, `iu`) * `a.testn(b)` - test if specified bit is set * `a.maskn(b)` - clear bits with indexes higher or equal to `b` (`i`) * `a.bincn(b)` - add `1 << b` to the number * `a.notn(w)` - not (for the width specified by `w`) (`i`) ### Reduction * `a.gcd(b)` - GCD * `a.egcd(b)` - Extended GCD results (`{ a: ..., b: ..., gcd: ... }`) * `a.invm(b)` - inverse `a` modulo `b` ## Fast reduction When doing lots of reductions using the same modulo, it might be beneficial to use some tricks: like [Montgomery multiplication][0], or using special algorithm for [Mersenne Prime][1]. ### Reduction context To enable this tricks one should create a reduction context: ```js var red = BN.red(num); ``` where `num` is just a BN instance. Or: ```js var red = BN.red(primeName); ``` Where `primeName` is either of these [Mersenne Primes][1]: * `'k256'` * `'p224'` * `'p192'` * `'p25519'` Or: ```js var red = BN.mont(num); ``` To reduce numbers with [Montgomery trick][0]. `.mont()` is generally faster than `.red(num)`, but slower than `BN.red(primeName)`. ### Converting numbers Before performing anything in reduction context - numbers should be converted to it. Usually, this means that one should: * Convert inputs to reducted ones * Operate on them in reduction context * Convert outputs back from the reduction context Here is how one may convert numbers to `red`: ```js var redA = a.toRed(red); ``` Where `red` is a reduction context created using instructions above Here is how to convert them back: ```js var a = redA.fromRed(); ``` ### Red instructions Most of the instructions from the very start of this readme have their counterparts in red context: * `a.redAdd(b)`, `a.redIAdd(b)` * `a.redSub(b)`, `a.redISub(b)` * `a.redShl(num)` * `a.redMul(b)`, `a.redIMul(b)` * `a.redSqr()`, `a.redISqr()` * `a.redSqrt()` - square root modulo reduction context's prime * `a.redInvm()` - modular inverse of the number * `a.redNeg()` * `a.redPow(b)` - modular exponentiation ### Number Size Optimized for elliptic curves that work with 256-bit numbers. There is no limitation on the size of the numbers. ## LICENSE This software is licensed under the MIT License. [0]: https://en.wikipedia.org/wiki/Montgomery_modular_multiplication [1]: https://en.wikipedia.org/wiki/Mersenne_prime bn.js-5.2.0/benchmarks/000077500000000000000000000000001401525734400146525ustar00rootroot00000000000000bn.js-5.2.0/benchmarks/index.js000066400000000000000000000267041401525734400163300ustar00rootroot00000000000000/* global BigInt */ /* eslint-disable new-cap, no-new, no-unused-expressions */ var benchmark = require('benchmark'); var crypto = require('crypto'); var bn = require('../'); var bignum; try { bignum = require('bignum'); } catch (err) { console.log('Load bignum error: ' + err.message.split('\n')[0]); } var sjcl = require('eccjs').sjcl.bn; var bigi = require('bigi'); var BigInteger = require('js-big-integer').BigInteger; var SilentMattBigInteger = require('biginteger').BigInteger; var XorShift128Plus = require('xorshift.js').XorShift128Plus; var benchmarks = []; var selfOnly = process.env.SELF_ONLY; var seed = process.env.SEED || crypto.randomBytes(16).toString('hex'); console.log('Seed: ' + seed); var prng = new XorShift128Plus(seed); var fixtures = []; var findex = 0; function findexRefresh () { findex = 0; } function add (op, obj) { benchmarks.push({ name: op, start: function start () { var suite = new benchmark.Suite(); console.log('Benchmarking: ' + op); Object.keys(obj).forEach(function (name) { if (name === 'BigInt' && typeof BigInt === 'undefined') { return; } if (name === 'bignum' && bignum === undefined) { return; } if (!selfOnly || name === 'bn.js') { var testFn = obj[name]; suite.add(name + '#' + op, function () { var fixture = fixtures[findex++]; if (findex === fixtures.length) { findexRefresh(); } testFn(fixture); }, { onStart: findexRefresh, onCycle: findexRefresh }); } }); suite .on('cycle', function (event) { console.log(String(event.target)); }) .on('complete', function () { console.log('------------------------'); console.log('Fastest is ' + this.filter('fastest')[0].name); }) .run(); console.log('========================'); } }); } function start () { var re = process.argv[2] ? new RegExp(process.argv[2], 'i') : /./; benchmarks .filter(function (b) { return re.test(b.name); }) .forEach(function (b) { b.start(); }); } if (/fast/i.test(process.argv[3])) { console.log('Running in fast mode...'); benchmark.options.minTime = 0.3; benchmark.options.maxTime = 1; benchmark.options.minSamples = 3; } else { benchmark.options.minTime = 1; } while (fixtures.length < 25) { var fixture = {}; fixtures.push(fixture); var a = prng.randomBytes(32).toString('hex'); var b = prng.randomBytes(32).toString('hex'); var aj = prng.randomBytes(768).toString('hex'); var bj = prng.randomBytes(768).toString('hex'); fixture.a10base = new bn(a, 16).toString(10); fixture.a16base = new bn(a, 16).toString(16); // BN fixture.a1 = new bn(a, 16); fixture.b1 = new bn(b, 16); fixture.a1j = new bn(aj, 16); fixture.b1j = new bn(bj, 16); fixture.as1 = fixture.a1.mul(fixture.a1).iaddn(0x2adbeef); fixture.am1 = fixture.a1.toRed(bn.red('k256')); fixture.pow1 = fixture.am1.fromRed(); // BigInt fixture.a2 = BigInt(fixture.a1.toString(10)); fixture.b2 = BigInt(fixture.b1.toString(10)); fixture.a2j = BigInt(fixture.a1j.toString(10)); fixture.b2j = BigInt(fixture.b1j.toString(10)); fixture.as2 = fixture.a2 * fixture.a2 + 0x2adbeefn; // bignum if (bignum) { fixture.a3 = new bignum(a, 16); fixture.b3 = new bignum(b, 16); fixture.a3j = new bignum(aj, 16); fixture.b3j = new bignum(bj, 16); fixture.as3 = fixture.a3.mul(fixture.a3).add(0x2adbeef); } // bigi fixture.a4 = new bigi(a, 16); fixture.b4 = new bigi(b, 16); fixture.a4j = new bigi(aj, 16); fixture.b4j = new bigi(bj, 16); fixture.as4 = fixture.a4.multiply(fixture.a4).add(bigi.valueOf(0x2adbeef)); // sjcl fixture.a5 = new sjcl(a, 16); fixture.b5 = new sjcl(b, 16); fixture.a5j = new sjcl(aj, 16); fixture.b5j = new sjcl(bj, 16); // fixture.as5 = fixture.a5.mul(fixture.a5).add(0x2adbeef); fixture.am5 = new sjcl.prime.p256k(fixture.a5); // BigInteger fixture.a6 = new BigInteger(a, 16); fixture.b6 = new BigInteger(b, 16); fixture.a6j = new BigInteger(aj, 16); fixture.b6j = new BigInteger(bj, 16); fixture.as6 = fixture.a6.multiply(fixture.a6).add( new BigInteger('2adbeef', 16)); // SilentMattBigInteger fixture.a7 = SilentMattBigInteger.parse(a, 16); fixture.b7 = SilentMattBigInteger.parse(b, 16); fixture.a7j = SilentMattBigInteger.parse(aj, 16); fixture.b7j = SilentMattBigInteger.parse(aj, 16); fixture.as7 = fixture.a7.multiply(fixture.a7).add( SilentMattBigInteger.parse('2adbeef', 16)); } add('create-10', { 'bn.js': function (fixture) { new bn(fixture.a10base, 10); }, BigInt: function (fixture) { BigInt(fixture.a10base); }, bignum: function (fixture) { new bignum(fixture.a10base, 10); }, bigi: function (fixture) { new bigi(fixture.a10base, 10); }, yaffle: function (fixture) { new BigInteger(fixture.a10base, 10); }, 'silentmatt-biginteger': function (fixture) { SilentMattBigInteger.parse(fixture.a10base, 10); } }); add('create-hex', { 'bn.js': function (fixture) { new bn(fixture.a16base, 16); }, bignum: function (fixture) { new bignum(fixture.a16base, 16); }, bigi: function (fixture) { new bigi(fixture.a16base, 16); }, sjcl: function (fixture) { new sjcl(fixture.a16base); }, yaffle: function (fixture) { new BigInteger(fixture.a16base, 16); }, 'silentmatt-biginteger': function (fixture) { SilentMattBigInteger.parse(fixture.a16base, 16); } }); add('toString-10', { 'bn.js': function (fixture) { fixture.a1.toString(10); }, BigInt: function (fixture) { fixture.a2.toString(10); }, bignum: function (fixture) { fixture.a3.toString(10); }, bigi: function (fixture) { fixture.a4.toString(10); }, yaffle: function (fixture) { fixture.a6.toString(10); }, 'silentmatt-biginteger': function (fixture) { fixture.a7.toString(10); } }); add('toString-hex', { 'bn.js': function (fixture) { fixture.a1.toString(16); }, BigInt: function (fixture) { fixture.a2.toString(16); }, bignum: function (fixture) { fixture.a3.toString(16); }, bigi: function (fixture) { fixture.a4.toString(16); }, sjcl: function (fixture) { fixture.a5.toString(16); }, yaffle: function (fixture) { fixture.a6.toString(16); }, 'silentmatt-biginteger': function (fixture) { fixture.a7.toString(16); } }); add('add', { 'bn.js': function (fixture) { fixture.a1.add(fixture.b1); }, BigInt: function (fixture) { fixture.a2 + fixture.b2; }, bignum: function (fixture) { fixture.a3.add(fixture.b3); }, bigi: function (fixture) { fixture.a4.add(fixture.b4); }, sjcl: function (fixture) { fixture.a5.add(fixture.b5); }, yaffle: function (fixture) { fixture.a6.add(fixture.b6); }, 'silentmatt-biginteger': function (fixture) { fixture.a7.add(fixture.a7); } }); add('sub', { 'bn.js': function (fixture) { fixture.b1.sub(fixture.a1); }, BigInt: function (fixture) { fixture.a2 - fixture.b2; }, bignum: function (fixture) { fixture.b3.sub(fixture.a3); }, bigi: function (fixture) { fixture.b4.subtract(fixture.a4); }, sjcl: function (fixture) { fixture.b5.sub(fixture.a5); }, yaffle: function (fixture) { fixture.b6.subtract(fixture.a6); }, 'silentmatt-biginteger': function (fixture) { fixture.b7.subtract(fixture.a7); } }); add('mul', { 'bn.js': function (fixture) { fixture.a1.mul(fixture.b1); }, 'bn.js[FFT]': function (fixture) { fixture.a1.mulf(fixture.b1); }, BigInt: function (fixture) { fixture.a2 * fixture.b2; }, bignum: function (fixture) { fixture.a3.mul(fixture.b3); }, bigi: function (fixture) { fixture.a4.multiply(fixture.b4); }, sjcl: function (fixture) { fixture.a5.mul(fixture.b5); }, yaffle: function (fixture) { fixture.a6.multiply(fixture.b6); }, 'silentmatt-biginteger': function (fixture) { fixture.a7.multiply(fixture.b7); } }); add('mul-jumbo', { 'bn.js': function (fixture) { fixture.a1j.mul(fixture.b1j); }, 'bn.js[FFT]': function (fixture) { fixture.a1j.mulf(fixture.b1j); }, BigInt: function (fixture) { fixture.a2j * fixture.b2j; }, bignum: function (fixture) { fixture.a3j.mul(fixture.b3j); }, bigi: function (fixture) { fixture.a4j.multiply(fixture.b4j); }, sjcl: function (fixture) { fixture.a5j.mul(fixture.b5j); }, yaffle: function (fixture) { fixture.a6j.multiply(fixture.b6j); }, 'silentmatt-biginteger': function (fixture) { fixture.a7j.multiply(fixture.b7j); } }); add('sqr', { 'bn.js': function (fixture) { fixture.a1.mul(fixture.a1); }, BigInt: function (fixture) { fixture.a2 * fixture.a2; }, bignum: function (fixture) { fixture.a3.mul(fixture.a3); }, bigi: function (fixture) { fixture.a4.square(); }, sjcl: function (fixture) { fixture.a5.mul(fixture.a5); }, yaffle: function (fixture) { fixture.a6.multiply(fixture.a6); }, 'silentmatt-biginteger': function (fixture) { fixture.a7.multiply(fixture.a7); } }); add('div', { 'bn.js': function (fixture) { fixture.as1.div(fixture.a1); }, BigInt: function (fixture) { fixture.as2 / fixture.a2; }, bignum: function (fixture) { fixture.as3.div(fixture.a3); }, bigi: function (fixture) { fixture.as4.divide(fixture.a4); }, yaffle: function (fixture) { fixture.as6.divide(fixture.a6); }, 'silentmatt-biginteger': function (fixture) { fixture.as7.divide(fixture.a7); } }); add('mod', { 'bn.js': function (fixture) { fixture.as1.mod(fixture.a1); }, BigInt: function (fixture) { fixture.as2 / fixture.a2; }, bignum: function (fixture) { fixture.as3.mod(fixture.a3); }, bigi: function (fixture) { fixture.as4.mod(fixture.a4); }, yaffle: function (fixture) { var remainder = fixture.as6.remainder(fixture.a6); return remainder.compareTo(BigInteger.ZERO) < 0 ? remainder.add(fixture.a6) : remainder; }, 'silentmatt-biginteger': function (fixture) { var remainder = fixture.as7.remainder(fixture.a7); return remainder.compare(BigInteger.ZERO) < 0 ? remainder.add(fixture.a7) : remainder; } }); add('mul-mod k256', { 'bn.js': function (fixture) { fixture.am1.redSqr(); }, sjcl: function (fixture) { fixture.am5.square().fullReduce(); } }); var prime1; if (bignum) { prime1 = new bignum( 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', 16); } // var prime4 = new bigi( // 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', // 16); var prime5 = new sjcl( 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'); add('pow k256', { 'bn.js': function (fixture) { fixture.am1.redPow(fixture.pow1); }, bignum: function (fixture) { fixture.a3.powm(fixture.a3, prime1); } }); add('invm k256', { 'bn.js': function (fixture) { fixture.am1.redInvm(); }, sjcl: function (fixture) { fixture.am5.inverseMod(prime5); } }); add('gcd', { 'bn.js': function (fixture) { fixture.a1.gcd(fixture.b1); }, bigi: function (fixture) { fixture.a4.gcd(fixture.b4); } }); add('egcd', { 'bn.js': function (fixture) { fixture.a1.egcd(fixture.b1); } }); add('bitLength', { 'bn.js': function () { fixture.a1.bitLength(); } }); add('toArray', { 'bn.js': function () { fixture.a1j.toArray(); } }); start(); bn.js-5.2.0/benchmarks/package.json000066400000000000000000000007001401525734400171350ustar00rootroot00000000000000{ "name": "bn.js-benchmark", "version": "0.0.0", "description": "", "license": "MIT", "author": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { "benchmark": "^2.1.4", "bigi": "1.4.2", "biginteger": "1.0.3", "eccjs": "0.3.1", "js-big-integer": "1.0.2", "xorshift.js": "^1.0.3" }, "optionalDependencies": { "bignum": "0.13.1" } } bn.js-5.2.0/lib/000077500000000000000000000000001401525734400133035ustar00rootroot00000000000000bn.js-5.2.0/lib/bn.js000066400000000000000000002604751401525734400142560ustar00rootroot00000000000000(function (module, 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 module === 'object') { module.exports = BN; } else { exports.BN = BN; } BN.BN = BN; BN.wordSize = 26; var Buffer; try { if (typeof window !== 'undefined' && typeof window.Buffer !== 'undefined') { Buffer = window.Buffer; } else { 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); }; 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++; this.negative = 1; } if (start < number.length) { if (base === 16) { this._parseHex(number, start, endian); } else { this._parseBase(number, base, start); if (endian === 'le') { 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 parseHex4Bits (string, index) { var c = string.charCodeAt(index); // '0' - '9' if (c >= 48 && c <= 57) { return c - 48; // 'A' - 'F' } else if (c >= 65 && c <= 70) { return c - 55; // 'a' - 'f' } else if (c >= 97 && c <= 102) { return c - 87; } else { assert(false, 'Invalid character in ' + string); } } function parseHexByte (string, lowerBound, index) { var r = parseHex4Bits(string, index); if (index - 1 >= lowerBound) { r |= parseHex4Bits(string, index - 1) << 4; } return r; } BN.prototype._parseHex = function _parseHex (number, start, endian) { // 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; } // 24-bits chunks var off = 0; var j = 0; var w; if (endian === 'be') { for (i = number.length - 1; i >= start; i -= 2) { w = parseHexByte(number, start, i) << off; this.words[j] |= w & 0x3ffffff; if (off >= 18) { off -= 18; j += 1; this.words[j] |= w >>> 26; } else { off += 8; } } } else { var parseLength = number.length - start; 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) { off -= 18; j += 1; this.words[j] |= w >>> 26; } else { off += 8; } } } this._strip(); }; function parseBase (str, start, end, mul) { var r = 0; var b = 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) { b = c - 49 + 0xa; // 'A' } else if (c >= 17) { b = c - 17 + 0xa; // '0' - '9' } else { b = c; } assert(c >= 0 && b < mul, 'Invalid character'); r += b; } 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); } } this._strip(); }; 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; }; function move (dest, src) { dest.words = src.words; dest.length = src.length; dest.negative = src.negative; dest.red = src.red; } BN.prototype._move = function _move (dest) { move(dest, this); }; 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; }; // 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') { try { BN.prototype[Symbol.for('nodejs.util.inspect.custom')] = inspect; } catch (e) { BN.prototype.inspect = inspect; } } else { BN.prototype.inspect = inspect; } function inspect () { return (this.red ? ''; } /* 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; if (carry !== 0 || i !== this.length - 1) { out = zeros[6 - word.length] + word + out; } else { out = word + out; } off += 2; if (off >= 26) { off -= 26; i--; } } 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.modrn(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, 2); }; if (Buffer) { BN.prototype.toBuffer = function toBuffer (endian, length) { return this.toArrayLike(Buffer, endian, length); }; } BN.prototype.toArray = function toArray (endian, length) { return this.toArrayLike(Array, endian, length); }; var allocate = function allocate (ArrayType, size) { if (ArrayType.allocUnsafe) { return ArrayType.allocUnsafe(size); } return new ArrayType(size); }; BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) { this._strip(); 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'); var res = allocate(ArrayType, reqLength); var postfix = endian === 'le' ? 'LE' : 'BE'; this['_toArrayLike' + postfix](res, byteLength); return res; }; BN.prototype._toArrayLikeLE = function _toArrayLikeLE (res, byteLength) { var position = 0; var carry = 0; for (var i = 0, shift = 0; i < this.length; i++) { var word = (this.words[i] << shift) | carry; res[position++] = word & 0xff; if (position < res.length) { res[position++] = (word >> 8) & 0xff; } if (position < res.length) { res[position++] = (word >> 16) & 0xff; } if (shift === 6) { if (position < res.length) { res[position++] = (word >> 24) & 0xff; } carry = 0; shift = 0; } else { carry = word >>> 24; shift += 2; } } if (position < res.length) { res[position++] = carry; while (position < res.length) { res[position++] = 0; } } }; BN.prototype._toArrayLikeBE = function _toArrayLikeBE (res, byteLength) { var position = res.length - 1; var carry = 0; for (var i = 0, shift = 0; i < this.length; i++) { var word = (this.words[i] << shift) | carry; res[position--] = word & 0xff; if (position >= 0) { res[position--] = (word >> 8) & 0xff; } if (position >= 0) { res[position--] = (word >> 16) & 0xff; } if (shift === 6) { if (position >= 0) { res[position--] = (word >> 24) & 0xff; } carry = 0; shift = 0; } else { carry = word >>> 24; shift += 2; } } if (position >= 0) { res[position--] = carry; while (position >= 0) { res[position--] = 0; } } }; 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] >>> wbit) & 0x01; } 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 + Math.imul(ah5, bh4)) | 0; lo = (lo + Math.imul(al4, bl5)) | 0; mid = (mid + Math.imul(al4, bh5)) | 0; mid = (mid + Math.imul(ah4, bl5)) | 0; hi = (hi + Math.imul(ah4, bh5)) | 0; lo = (lo + Math.imul(al3, bl6)) | 0; mid = (mid + Math.imul(al3, bh6)) | 0; mid = (mid + Math.imul(ah3, bl6)) | 0; hi = (hi + Math.imul(ah3, bh6)) | 0; lo = (lo + Math.imul(al2, bl7)) | 0; mid = (mid + Math.imul(al2, bh7)) | 0; mid = (mid + Math.imul(ah2, bl7)) | 0; hi = (hi + Math.imul(ah2, bh7)) | 0; lo = (lo + Math.imul(al1, bl8)) | 0; mid = (mid + Math.imul(al1, bh8)) | 0; mid = (mid + Math.imul(ah1, bl8)) | 0; hi = (hi + Math.imul(ah1, bh8)) | 0; lo = (lo + Math.imul(al0, bl9)) | 0; mid = (mid + Math.imul(al0, bh9)) | 0; mid = (mid + Math.imul(ah0, bl9)) | 0; hi = (hi + Math.imul(ah0, bh9)) | 0; var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0; w9 &= 0x3ffffff; /* k = 10 */ lo = Math.imul(al9, bl1); mid = Math.imul(al9, bh1); mid = (mid + Math.imul(ah9, bl1)) | 0; hi = Math.imul(ah9, bh1); lo = (lo + Math.imul(al8, bl2)) | 0; mid = (mid + Math.imul(al8, bh2)) | 0; mid = (mid + Math.imul(ah8, bl2)) | 0; hi = (hi + Math.imul(ah8, bh2)) | 0; lo = (lo + Math.imul(al7, bl3)) | 0; mid = (mid + Math.imul(al7, bh3)) | 0; mid = (mid + Math.imul(ah7, bl3)) | 0; hi = (hi + Math.imul(ah7, bh3)) | 0; lo = (lo + Math.imul(al6, bl4)) | 0; mid = (mid + Math.imul(al6, bh4)) | 0; mid = (mid + Math.imul(ah6, bl4)) | 0; hi = (hi + Math.imul(ah6, bh4)) | 0; lo = (lo + Math.imul(al5, bl5)) | 0; mid = (mid + Math.imul(al5, bh5)) | 0; mid = (mid + Math.imul(ah5, bl5)) | 0; hi = (hi + Math.imul(ah5, bh5)) | 0; lo = (lo + Math.imul(al4, bl6)) | 0; mid = (mid + Math.imul(al4, bh6)) | 0; mid = (mid + Math.imul(ah4, bl6)) | 0; hi = (hi + Math.imul(ah4, bh6)) | 0; lo = (lo + Math.imul(al3, bl7)) | 0; mid = (mid + Math.imul(al3, bh7)) | 0; mid = (mid + Math.imul(ah3, bl7)) | 0; hi = (hi + Math.imul(ah3, bh7)) | 0; lo = (lo + Math.imul(al2, bl8)) | 0; mid = (mid + Math.imul(al2, bh8)) | 0; mid = (mid + Math.imul(ah2, bl8)) | 0; hi = (hi + Math.imul(ah2, bh8)) | 0; lo = (lo + Math.imul(al1, bl9)) | 0; mid = (mid + Math.imul(al1, bh9)) | 0; mid = (mid + Math.imul(ah1, bl9)) | 0; hi = (hi + Math.imul(ah1, bh9)) | 0; var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0; w10 &= 0x3ffffff; /* k = 11 */ lo = Math.imul(al9, bl2); mid = Math.imul(al9, bh2); mid = (mid + Math.imul(ah9, bl2)) | 0; hi = Math.imul(ah9, bh2); lo = (lo + Math.imul(al8, bl3)) | 0; mid = (mid + Math.imul(al8, bh3)) | 0; mid = (mid + Math.imul(ah8, bl3)) | 0; hi = (hi + Math.imul(ah8, bh3)) | 0; lo = (lo + Math.imul(al7, bl4)) | 0; mid = (mid + Math.imul(al7, bh4)) | 0; mid = (mid + Math.imul(ah7, bl4)) | 0; hi = (hi + Math.imul(ah7, bh4)) | 0; lo = (lo + Math.imul(al6, bl5)) | 0; mid = (mid + Math.imul(al6, bh5)) | 0; mid = (mid + Math.imul(ah6, bl5)) | 0; hi = (hi + Math.imul(ah6, bh5)) | 0; lo = (lo + Math.imul(al5, bl6)) | 0; mid = (mid + Math.imul(al5, bh6)) | 0; mid = (mid + Math.imul(ah5, bl6)) | 0; hi = (hi + Math.imul(ah5, bh6)) | 0; lo = (lo + Math.imul(al4, bl7)) | 0; mid = (mid + Math.imul(al4, bh7)) | 0; mid = (mid + Math.imul(ah4, bl7)) | 0; hi = (hi + Math.imul(ah4, bh7)) | 0; lo = (lo + Math.imul(al3, bl8)) | 0; mid = (mid + Math.imul(al3, bh8)) | 0; mid = (mid + Math.imul(ah3, bl8)) | 0; hi = (hi + Math.imul(ah3, bh8)) | 0; lo = (lo + Math.imul(al2, bl9)) | 0; mid = (mid + Math.imul(al2, bh9)) | 0; mid = (mid + Math.imul(ah2, bl9)) | 0; hi = (hi + Math.imul(ah2, bh9)) | 0; var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0; w11 &= 0x3ffffff; /* k = 12 */ lo = Math.imul(al9, bl3); mid = Math.imul(al9, bh3); mid = (mid + Math.imul(ah9, bl3)) | 0; hi = Math.imul(ah9, bh3); lo = (lo + Math.imul(al8, bl4)) | 0; mid = (mid + Math.imul(al8, bh4)) | 0; mid = (mid + Math.imul(ah8, bl4)) | 0; hi = (hi + Math.imul(ah8, bh4)) | 0; lo = (lo + Math.imul(al7, bl5)) | 0; mid = (mid + Math.imul(al7, bh5)) | 0; mid = (mid + Math.imul(ah7, bl5)) | 0; hi = (hi + Math.imul(ah7, bh5)) | 0; lo = (lo + Math.imul(al6, bl6)) | 0; mid = (mid + Math.imul(al6, bh6)) | 0; mid = (mid + Math.imul(ah6, bl6)) | 0; hi = (hi + Math.imul(ah6, bh6)) | 0; lo = (lo + Math.imul(al5, bl7)) | 0; mid = (mid + Math.imul(al5, bh7)) | 0; mid = (mid + Math.imul(ah5, bl7)) | 0; hi = (hi + Math.imul(ah5, bh7)) | 0; lo = (lo + Math.imul(al4, bl8)) | 0; mid = (mid + Math.imul(al4, bh8)) | 0; mid = (mid + Math.imul(ah4, bl8)) | 0; hi = (hi + Math.imul(ah4, bh8)) | 0; lo = (lo + Math.imul(al3, bl9)) | 0; mid = (mid + Math.imul(al3, bh9)) | 0; mid = (mid + Math.imul(ah3, bl9)) | 0; hi = (hi + Math.imul(ah3, bh9)) | 0; var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0; w12 &= 0x3ffffff; /* k = 13 */ lo = Math.imul(al9, bl4); mid = Math.imul(al9, bh4); mid = (mid + Math.imul(ah9, bl4)) | 0; hi = Math.imul(ah9, bh4); lo = (lo + Math.imul(al8, bl5)) | 0; mid = (mid + Math.imul(al8, bh5)) | 0; mid = (mid + Math.imul(ah8, bl5)) | 0; hi = (hi + Math.imul(ah8, bh5)) | 0; lo = (lo + Math.imul(al7, bl6)) | 0; mid = (mid + Math.imul(al7, bh6)) | 0; mid = (mid + Math.imul(ah7, bl6)) | 0; hi = (hi + Math.imul(ah7, bh6)) | 0; lo = (lo + Math.imul(al6, bl7)) | 0; mid = (mid + Math.imul(al6, bh7)) | 0; mid = (mid + Math.imul(ah6, bl7)) | 0; hi = (hi + Math.imul(ah6, bh7)) | 0; lo = (lo + Math.imul(al5, bl8)) | 0; mid = (mid + Math.imul(al5, bh8)) | 0; mid = (mid + Math.imul(ah5, bl8)) | 0; hi = (hi + Math.imul(ah5, bh8)) | 0; lo = (lo + Math.imul(al4, bl9)) | 0; mid = (mid + Math.imul(al4, bh9)) | 0; mid = (mid + Math.imul(ah4, bl9)) | 0; hi = (hi + Math.imul(ah4, bh9)) | 0; var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0; w13 &= 0x3ffffff; /* k = 14 */ lo = Math.imul(al9, bl5); mid = Math.imul(al9, bh5); mid = (mid + Math.imul(ah9, bl5)) | 0; hi = Math.imul(ah9, bh5); lo = (lo + Math.imul(al8, bl6)) | 0; mid = (mid + Math.imul(al8, bh6)) | 0; mid = (mid + Math.imul(ah8, bl6)) | 0; hi = (hi + Math.imul(ah8, bh6)) | 0; lo = (lo + Math.imul(al7, bl7)) | 0; mid = (mid + Math.imul(al7, bh7)) | 0; mid = (mid + Math.imul(ah7, bl7)) | 0; hi = (hi + Math.imul(ah7, bh7)) | 0; lo = (lo + Math.imul(al6, bl8)) | 0; mid = (mid + Math.imul(al6, bh8)) | 0; mid = (mid + Math.imul(ah6, bl8)) | 0; hi = (hi + Math.imul(ah6, bh8)) | 0; lo = (lo + Math.imul(al5, bl9)) | 0; mid = (mid + Math.imul(al5, bh9)) | 0; mid = (mid + Math.imul(ah5, bl9)) | 0; hi = (hi + Math.imul(ah5, bh9)) | 0; var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0; w14 &= 0x3ffffff; /* k = 15 */ lo = Math.imul(al9, bl6); mid = Math.imul(al9, bh6); mid = (mid + Math.imul(ah9, bl6)) | 0; hi = Math.imul(ah9, bh6); lo = (lo + Math.imul(al8, bl7)) | 0; mid = (mid + Math.imul(al8, bh7)) | 0; mid = (mid + Math.imul(ah8, bl7)) | 0; hi = (hi + Math.imul(ah8, bh7)) | 0; lo = (lo + Math.imul(al7, bl8)) | 0; mid = (mid + Math.imul(al7, bh8)) | 0; mid = (mid + Math.imul(ah7, bl8)) | 0; hi = (hi + Math.imul(ah7, bh8)) | 0; lo = (lo + Math.imul(al6, bl9)) | 0; mid = (mid + Math.imul(al6, bh9)) | 0; mid = (mid + Math.imul(ah6, bl9)) | 0; hi = (hi + Math.imul(ah6, bh9)) | 0; var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0; w15 &= 0x3ffffff; /* k = 16 */ lo = Math.imul(al9, bl7); mid = Math.imul(al9, bh7); mid = (mid + Math.imul(ah9, bl7)) | 0; hi = Math.imul(ah9, bh7); lo = (lo + Math.imul(al8, bl8)) | 0; mid = (mid + Math.imul(al8, bh8)) | 0; mid = (mid + Math.imul(ah8, bl8)) | 0; hi = (hi + Math.imul(ah8, bh8)) | 0; lo = (lo + Math.imul(al7, bl9)) | 0; mid = (mid + Math.imul(al7, bh9)) | 0; mid = (mid + Math.imul(ah7, bl9)) | 0; hi = (hi + Math.imul(ah7, bh9)) | 0; var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0; w16 &= 0x3ffffff; /* k = 17 */ lo = Math.imul(al9, bl8); mid = Math.imul(al9, bh8); mid = (mid + Math.imul(ah9, bl8)) | 0; hi = Math.imul(ah9, bh8); lo = (lo + Math.imul(al8, bl9)) | 0; mid = (mid + Math.imul(al8, bh9)) | 0; mid = (mid + Math.imul(ah8, bl9)) | 0; hi = (hi + Math.imul(ah8, bh9)) | 0; var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0; w17 &= 0x3ffffff; /* k = 18 */ lo = Math.imul(al9, bl9); mid = Math.imul(al9, bh9); mid = (mid + Math.imul(ah9, bl9)) | 0; hi = Math.imul(ah9, bh9); var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0; w18 &= 0x3ffffff; o[0] = w0; o[1] = w1; o[2] = w2; o[3] = w3; o[4] = w4; o[5] = w5; o[6] = w6; o[7] = w7; o[8] = w8; o[9] = w9; o[10] = w10; o[11] = w11; o[12] = w12; o[13] = w13; o[14] = w14; o[15] = w15; o[16] = w16; o[17] = w17; o[18] = w18; if (c !== 0) { o[19] = c; out.length++; } return out; }; // Polyfill comb if (!Math.imul) { comb10MulTo = smallMulTo; } function bigMulTo (self, num, out) { out.negative = num.negative ^ self.negative; out.length = self.length + num.length; var carry = 0; var hncarry = 0; for (var k = 0; k < out.length - 1; k++) { // Sum all words with the same `i + j = k` and accumulate `ncarry`, // note that ncarry could be >= 0x3ffffff var ncarry = hncarry; hncarry = 0; 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; var a = self.words[i] | 0; var b = num.words[j] | 0; var r = a * b; var lo = r & 0x3ffffff; ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; lo = (lo + rword) | 0; rword = lo & 0x3ffffff; ncarry = (ncarry + (lo >>> 26)) | 0; hncarry += ncarry >>> 26; ncarry &= 0x3ffffff; } out.words[k] = rword; carry = ncarry; ncarry = hncarry; } if (carry !== 0) { out.words[k] = carry; } else { out.length--; } return out._strip(); } function jumboMulTo (self, num, out) { // Temporary disable, see https://github.com/indutny/bn.js/issues/211 // var fftm = new FFTM(); // return fftm.mulp(self, num, out); return bigMulTo(self, num, out); } BN.prototype.mulTo = function mulTo (num, out) { var res; var len = this.length + num.length; if (this.length === 10 && num.length === 10) { res = comb10MulTo(this, num, out); } else if (len < 63) { res = smallMulTo(this, num, out); } else if (len < 1024) { res = bigMulTo(this, num, out); } else { res = jumboMulTo(this, num, out); } return res; }; // Cooley-Tukey algorithm for FFT // slightly revisited to rely on looping instead of recursion function FFTM (x, y) { this.x = x; this.y = y; } FFTM.prototype.makeRBT = function makeRBT (N) { var t = new Array(N); var l = BN.prototype._countBits(N) - 1; for (var i = 0; i < N; i++) { t[i] = this.revBin(i, l, N); } return t; }; // Returns binary-reversed representation of `x` FFTM.prototype.revBin = function revBin (x, l, N) { if (x === 0 || x === N - 1) return x; var rb = 0; for (var i = 0; i < l; i++) { rb |= (x & 1) << (l - i - 1); x >>= 1; } return rb; }; // Performs "tweedling" phase, therefore 'emulating' // behaviour of the recursive algorithm FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) { for (var i = 0; i < N; i++) { rtws[i] = rws[rbt[i]]; itws[i] = iws[rbt[i]]; } }; FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) { this.permute(rbt, rws, iws, rtws, itws, N); 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); for (var p = 0; p < N; p += l) { var rtwdf_ = rtwdf; var itwdf_ = itwdf; for (var j = 0; j < s; j++) { var re = rtws[p + j]; var ie = itws[p + j]; var ro = rtws[p + j + s]; var io = itws[p + j + s]; var rx = rtwdf_ * ro - itwdf_ * io; io = rtwdf_ * io + itwdf_ * ro; ro = rx; rtws[p + j] = re + ro; itws[p + j] = ie + io; rtws[p + j + s] = re - ro; itws[p + j + s] = ie - io; /* jshint maxdepth : false */ if (j !== l) { rx = rtwdf * rtwdf_ - itwdf * itwdf_; itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_; rtwdf_ = rx; } } } } }; FFTM.prototype.guessLen13b = function guessLen13b (n, m) { var N = Math.max(m, n) | 1; var odd = N & 1; var i = 0; for (N = N / 2 | 0; N; N = N >>> 1) { i++; } return 1 << i + 1 + odd; }; FFTM.prototype.conjugate = function conjugate (rws, iws, N) { if (N <= 1) return; for (var i = 0; i < N / 2; i++) { var t = rws[i]; rws[i] = rws[N - i - 1]; rws[N - i - 1] = t; t = iws[i]; iws[i] = -iws[N - i - 1]; iws[N - i - 1] = -t; } }; 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 + Math.round(ws[2 * i] / N) + carry; ws[i] = w & 0x3ffffff; if (w < 0x4000000) { carry = 0; } else { carry = w / 0x4000000 | 0; } } return ws; }; FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) { var carry = 0; 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; } // Pad with zeroes for (i = 2 * len; i < N; ++i) { rws[i] = 0; } assert(carry === 0); assert((carry & ~0x1fff) === 0); }; FFTM.prototype.stub = function stub (N) { var ph = new Array(N); for (var i = 0; i < N; i++) { ph[i] = 0; } return ph; }; FFTM.prototype.mulp = function mulp (x, y, out) { var N = 2 * this.guessLen13b(x.length, y.length); var rbt = this.makeRBT(N); var _ = this.stub(N); var rws = new Array(N); var rwst = new Array(N); var iwst = new Array(N); var nrws = new Array(N); var nrwst = new Array(N); var niwst = new Array(N); var rmws = out.words; rmws.length = N; this.convert13b(x.words, x.length, rws, N); this.convert13b(y.words, y.length, nrws, N); this.transform(rws, _, rwst, iwst, N, rbt); this.transform(nrws, _, nrwst, niwst, N, rbt); for (var i = 0; i < N; i++) { var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i]; iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i]; rwst[i] = rx; } this.conjugate(rwst, iwst, N); this.transform(rwst, iwst, rmws, _, N, rbt); this.conjugate(rmws, _, N); this.normalize13b(rmws, N); out.negative = x.negative ^ y.negative; out.length = x.length + y.length; return out._strip(); }; // Multiply `this` by `num` BN.prototype.mul = function mul (num) { var out = new BN(null); out.words = new Array(this.length + num.length); return this.mulTo(num, out); }; // Multiply employing FFT BN.prototype.mulf = function mulf (num) { var out = new BN(null); out.words = new Array(this.length + num.length); return jumboMulTo(this, num, out); }; // In-place Multiplication BN.prototype.imul = function imul (num) { return this.clone().mulTo(num, this); }; BN.prototype.imuln = function imuln (num) { var isNegNum = num < 0; if (isNegNum) num = -num; assert(typeof num === 'number'); assert(num < 0x4000000); // Carry var carry = 0; for (var i = 0; i < this.length; i++) { var w = (this.words[i] | 0) * num; var lo = (w & 0x3ffffff) + (carry & 0x3ffffff); carry >>= 26; carry += (w / 0x4000000) | 0; // NOTE: lo is 27bit maximum carry += lo >>> 26; this.words[i] = lo & 0x3ffffff; } if (carry !== 0) { this.words[i] = carry; this.length++; } return isNegNum ? this.ineg() : this; }; BN.prototype.muln = function muln (num) { return this.clone().imuln(num); }; // `this` * `this` BN.prototype.sqr = function sqr () { return this.mul(this); }; // `this` * `this` in-place BN.prototype.isqr = function isqr () { return this.imul(this.clone()); }; // Math.pow(`this`, `num`) BN.prototype.pow = function pow (num) { var w = toBitArray(num); if (w.length === 0) return new BN(1); // Skip leading zeroes var res = this; for (var i = 0; i < w.length; i++, res = res.sqr()) { if (w[i] !== 0) break; } if (++i < w.length) { for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) { if (w[i] === 0) continue; res = res.mul(q); } } return res; }; // Shift-left in-place BN.prototype.iushln = function iushln (bits) { assert(typeof bits === 'number' && bits >= 0); var r = bits % 26; var s = (bits - r) / 26; var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); var i; if (r !== 0) { var carry = 0; for (i = 0; i < this.length; i++) { var newCarry = this.words[i] & carryMask; var c = ((this.words[i] | 0) - newCarry) << r; this.words[i] = c | carry; carry = newCarry >>> (26 - r); } if (carry) { this.words[i] = carry; this.length++; } } if (s !== 0) { for (i = this.length - 1; i >= 0; i--) { this.words[i + s] = this.words[i]; } for (i = 0; i < s; i++) { this.words[i] = 0; } this.length += s; } return this._strip(); }; BN.prototype.ishln = function ishln (bits) { // TODO(indutny): implement me assert(this.negative === 0); return this.iushln(bits); }; // Shift-right in-place // 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); var h; if (hint) { h = (hint - (hint % 26)) / 26; } else { h = 0; } var r = bits % 26; var s = Math.min((bits - r) / 26, this.length); var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); var maskedWords = extended; h -= s; h = Math.max(0, h); // Extended mode, copy masked part if (maskedWords) { for (var i = 0; i < s; i++) { maskedWords.words[i] = this.words[i]; } maskedWords.length = s; } if (s === 0) { // No-op, we should not move anything at all } else if (this.length > s) { this.length -= s; for (i = 0; i < this.length; i++) { this.words[i] = this.words[i + s]; } } else { this.words[0] = 0; this.length = 1; } var carry = 0; for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) { var word = this.words[i] | 0; this.words[i] = (carry << (26 - r)) | (word >>> r); carry = word & mask; } // Push carried bits as a mask if (maskedWords && carry !== 0) { maskedWords.words[maskedWords.length++] = carry; } if (this.length === 0) { this.words[0] = 0; this.length = 1; } return this._strip(); }; BN.prototype.ishrn = function ishrn (bits, hint, extended) { // TODO(indutny): implement me assert(this.negative === 0); return this.iushrn(bits, hint, extended); }; // Shift-left BN.prototype.shln = function shln (bits) { return this.clone().ishln(bits); }; BN.prototype.ushln = function ushln (bits) { return this.clone().iushln(bits); }; // Shift-right BN.prototype.shrn = function shrn (bits) { return this.clone().ishrn(bits); }; BN.prototype.ushrn = function ushrn (bits) { return this.clone().iushrn(bits); }; // Test if n bit is set BN.prototype.testn = function testn (bit) { assert(typeof bit === 'number' && bit >= 0); var r = bit % 26; var s = (bit - r) / 26; var q = 1 << r; // Fast case: bit is much higher than all existing words if (this.length <= s) return false; // Check bit and return var w = this.words[s]; return !!(w & q); }; // Return only lowers bits of number (in-place) BN.prototype.imaskn = function imaskn (bits) { 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'); if (this.length <= s) { return this; } if (r !== 0) { s++; } this.length = Math.min(s, this.length); if (r !== 0) { var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); this.words[this.length - 1] &= mask; } return this._strip(); }; // Return only lowers bits of number BN.prototype.maskn = function maskn (bits) { return this.clone().imaskn(bits); }; // Add plain number `num` to `this` BN.prototype.iaddn = function iaddn (num) { assert(typeof num === 'number'); assert(num < 0x4000000); if (num < 0) return this.isubn(-num); // Possible sign change if (this.negative !== 0) { if (this.length === 1 && (this.words[0] | 0) <= num) { this.words[0] = num - (this.words[0] | 0); this.negative = 0; return this; } this.negative = 0; this.isubn(num); this.negative = 1; return this; } // Add without checks return this._iaddn(num); }; BN.prototype._iaddn = function _iaddn (num) { this.words[0] += num; // Carry for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) { this.words[i] -= 0x4000000; if (i === this.length - 1) { this.words[i + 1] = 1; } else { this.words[i + 1]++; } } this.length = Math.max(this.length, i + 1); return this; }; // Subtract plain number `num` from `this` BN.prototype.isubn = function isubn (num) { assert(typeof num === 'number'); assert(num < 0x4000000); if (num < 0) return this.iaddn(-num); if (this.negative !== 0) { this.negative = 0; this.iaddn(num); this.negative = 1; return this; } this.words[0] -= num; if (this.length === 1 && this.words[0] < 0) { this.words[0] = -this.words[0]; this.negative = 1; } else { // Carry for (var i = 0; i < this.length && this.words[i] < 0; i++) { this.words[i] += 0x4000000; this.words[i + 1] -= 1; } } return this._strip(); }; BN.prototype.addn = function addn (num) { return this.clone().iaddn(num); }; BN.prototype.subn = function subn (num) { return this.clone().isubn(num); }; BN.prototype.iabs = function iabs () { this.negative = 0; return this; }; BN.prototype.abs = function abs () { return this.clone().iabs(); }; BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) { var len = num.length + shift; var i; this._expand(len); var w; var carry = 0; for (i = 0; i < num.length; i++) { w = (this.words[i + shift] | 0) + carry; var right = (num.words[i] | 0) * mul; w -= right & 0x3ffffff; carry = (w >> 26) - ((right / 0x4000000) | 0); this.words[i + shift] = w & 0x3ffffff; } for (; i < this.length - shift; i++) { w = (this.words[i + shift] | 0) + carry; carry = w >> 26; this.words[i + shift] = w & 0x3ffffff; } if (carry === 0) return this._strip(); // Subtraction overflow assert(carry === -1); carry = 0; for (i = 0; i < this.length; i++) { w = -(this.words[i] | 0) + carry; carry = w >> 26; this.words[i] = w & 0x3ffffff; } this.negative = 1; return this._strip(); }; BN.prototype._wordDiv = function _wordDiv (num, mode) { var shift = this.length - num.length; var a = this.clone(); var b = num; // Normalize var bhi = b.words[b.length - 1] | 0; var bhiBits = this._countBits(bhi); shift = 26 - bhiBits; if (shift !== 0) { b = b.ushln(shift); a.iushln(shift); bhi = b.words[b.length - 1] | 0; } // Initialize quotient var m = a.length - b.length; var q; if (mode !== 'mod') { q = new BN(null); q.length = m + 1; q.words = new Array(q.length); for (var i = 0; i < q.length; i++) { q.words[i] = 0; } } var diff = a.clone()._ishlnsubmul(b, 1, m); if (diff.negative === 0) { a = diff; if (q) { q.words[m] = 1; } } for (var j = m - 1; j >= 0; j--) { 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 // (0x7ffffff) qj = Math.min((qj / bhi) | 0, 0x3ffffff); a._ishlnsubmul(b, qj, j); while (a.negative !== 0) { qj--; a.negative = 0; a._ishlnsubmul(b, 1, j); if (!a.isZero()) { a.negative ^= 1; } } if (q) { q.words[j] = qj; } } if (q) { q._strip(); } a._strip(); // Denormalize if (mode !== 'div' && shift !== 0) { a.iushrn(shift); } return { div: q || null, mod: a }; }; // NOTE: 1) `mode` can be set to `mod` to request mod only, // to `div` to request div only, or be absent to // request both div & mod // 2) `positive` is true if unsigned mod is requested BN.prototype.divmod = function divmod (num, mode, positive) { assert(!num.isZero()); if (this.isZero()) { return { div: new BN(0), mod: new BN(0) }; } var div, mod, res; if (this.negative !== 0 && num.negative === 0) { res = this.neg().divmod(num, mode); if (mode !== 'mod') { div = res.div.neg(); } if (mode !== 'div') { mod = res.mod.neg(); if (positive && mod.negative !== 0) { mod.iadd(num); } } return { div: div, mod: mod }; } if (this.negative === 0 && num.negative !== 0) { res = this.divmod(num.neg(), mode); if (mode !== 'mod') { div = res.div.neg(); } return { div: div, mod: res.mod }; } if ((this.negative & num.negative) !== 0) { res = this.neg().divmod(num.neg(), mode); if (mode !== 'div') { mod = res.mod.neg(); if (positive && mod.negative !== 0) { mod.isub(num); } } return { div: res.div, mod: mod }; } // Both numbers are positive at this point // Strip both numbers to approximate shift value if (num.length > this.length || this.cmp(num) < 0) { return { div: new BN(0), mod: this }; } // Very short reduction if (num.length === 1) { if (mode === 'div') { return { div: this.divn(num.words[0]), mod: null }; } if (mode === 'mod') { return { div: null, mod: new BN(this.modrn(num.words[0])) }; } return { div: this.divn(num.words[0]), mod: new BN(this.modrn(num.words[0])) }; } return this._wordDiv(num, mode); }; // Find `this` / `num` BN.prototype.div = function div (num) { return this.divmod(num, 'div', false).div; }; // Find `this` % `num` BN.prototype.mod = function mod (num) { return this.divmod(num, 'mod', false).mod; }; BN.prototype.umod = function umod (num) { return this.divmod(num, 'mod', true).mod; }; // Find Round(`this` / `num`) BN.prototype.divRound = function divRound (num) { var dm = this.divmod(num); // Fast case - exact division if (dm.mod.isZero()) return dm.div; var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod; var half = num.ushrn(1); var r2 = num.andln(1); var cmp = mod.cmp(half); // Round down if (cmp < 0 || (r2 === 1 && cmp === 0)) return dm.div; // Round up return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1); }; BN.prototype.modrn = function modrn (num) { var isNegNum = num < 0; if (isNegNum) num = -num; assert(num <= 0x3ffffff); var p = (1 << 26) % num; var acc = 0; for (var i = this.length - 1; i >= 0; i--) { acc = (p * acc + (this.words[i] | 0)) % num; } return isNegNum ? -acc : acc; }; // WARNING: DEPRECATED BN.prototype.modn = function modn (num) { return this.modrn(num); }; // In-place division by number BN.prototype.idivn = function idivn (num) { var isNegNum = num < 0; if (isNegNum) num = -num; assert(num <= 0x3ffffff); var carry = 0; for (var i = this.length - 1; i >= 0; i--) { var w = (this.words[i] | 0) + carry * 0x4000000; this.words[i] = (w / num) | 0; carry = w % num; } this._strip(); return isNegNum ? this.ineg() : this; }; BN.prototype.divn = function divn (num) { return this.clone().idivn(num); }; BN.prototype.egcd = function egcd (p) { assert(p.negative === 0); assert(!p.isZero()); var x = this; var y = p.clone(); if (x.negative !== 0) { x = x.umod(p); } else { x = x.clone(); } // A * x + B * y = x var A = new BN(1); var B = new BN(0); // C * x + D * y = y var C = new BN(0); var D = new BN(1); var g = 0; while (x.isEven() && y.isEven()) { x.iushrn(1); y.iushrn(1); ++g; } var yp = y.clone(); var xp = x.clone(); while (!x.isZero()) { for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1); if (i > 0) { x.iushrn(i); while (i-- > 0) { if (A.isOdd() || B.isOdd()) { A.iadd(yp); B.isub(xp); } A.iushrn(1); B.iushrn(1); } } for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); if (j > 0) { y.iushrn(j); while (j-- > 0) { if (C.isOdd() || D.isOdd()) { C.iadd(yp); D.isub(xp); } C.iushrn(1); D.iushrn(1); } } if (x.cmp(y) >= 0) { x.isub(y); A.isub(C); B.isub(D); } else { y.isub(x); C.isub(A); D.isub(B); } } return { a: C, b: D, gcd: y.iushln(g) }; }; // This is reduced incarnation of the binary EEA // above, designated to invert members of the // _prime_ fields F(p) at a maximal speed BN.prototype._invmp = function _invmp (p) { assert(p.negative === 0); assert(!p.isZero()); var a = this; var b = p.clone(); if (a.negative !== 0) { a = a.umod(p); } else { a = a.clone(); } var x1 = new BN(1); var x2 = new BN(0); var delta = b.clone(); while (a.cmpn(1) > 0 && b.cmpn(1) > 0) { for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1); if (i > 0) { a.iushrn(i); while (i-- > 0) { if (x1.isOdd()) { x1.iadd(delta); } x1.iushrn(1); } } for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); if (j > 0) { b.iushrn(j); while (j-- > 0) { if (x2.isOdd()) { x2.iadd(delta); } x2.iushrn(1); } } if (a.cmp(b) >= 0) { a.isub(b); x1.isub(x2); } else { b.isub(a); x2.isub(x1); } } var res; if (a.cmpn(1) === 0) { res = x1; } else { res = x2; } if (res.cmpn(0) < 0) { res.iadd(p); } return res; }; BN.prototype.gcd = function gcd (num) { if (this.isZero()) return num.abs(); if (num.isZero()) return this.abs(); var a = this.clone(); var b = num.clone(); a.negative = 0; b.negative = 0; // Remove common factor of two for (var shift = 0; a.isEven() && b.isEven(); shift++) { a.iushrn(1); b.iushrn(1); } do { while (a.isEven()) { a.iushrn(1); } while (b.isEven()) { b.iushrn(1); } var r = a.cmp(b); if (r < 0) { // Swap `a` and `b` to make `a` always bigger than `b` var t = a; a = b; b = t; } else if (r === 0 || b.cmpn(1) === 0) { break; } a.isub(b); } while (true); return b.iushln(shift); }; // Invert number in the field F(num) BN.prototype.invm = function invm (num) { return this.egcd(num).a.umod(num); }; BN.prototype.isEven = function isEven () { return (this.words[0] & 1) === 0; }; BN.prototype.isOdd = function isOdd () { return (this.words[0] & 1) === 1; }; // And first word and num BN.prototype.andln = function andln (num) { return this.words[0] & num; }; // Increment at the bit position in-line BN.prototype.bincn = function bincn (bit) { assert(typeof bit === 'number'); var r = bit % 26; var s = (bit - r) / 26; var q = 1 << r; // Fast case: bit is much higher than all existing words if (this.length <= s) { this._expand(s + 1); this.words[s] |= q; return this; } // Add bit and propagate, if needed var carry = q; for (var i = s; carry !== 0 && i < this.length; i++) { var w = this.words[i] | 0; w += carry; carry = w >>> 26; w &= 0x3ffffff; this.words[i] = w; } if (carry !== 0) { this.words[i] = carry; this.length++; } return this; }; BN.prototype.isZero = function isZero () { return this.length === 1 && this.words[0] === 0; }; BN.prototype.cmpn = function cmpn (num) { var negative = num < 0; if (this.negative !== 0 && !negative) return -1; if (this.negative === 0 && negative) return 1; this._strip(); var res; if (this.length > 1) { res = 1; } else { if (negative) { num = -num; } assert(num <= 0x3ffffff, 'Number is too big'); var w = this.words[0] | 0; res = w === num ? 0 : w < num ? -1 : 1; } if (this.negative !== 0) return -res | 0; return res; }; // Compare two numbers and return: // 1 - if `this` > `num` // 0 - if `this` == `num` // -1 - if `this` < `num` BN.prototype.cmp = function cmp (num) { if (this.negative !== 0 && num.negative === 0) return -1; if (this.negative === 0 && num.negative !== 0) return 1; var res = this.ucmp(num); if (this.negative !== 0) return -res | 0; return res; }; // Unsigned comparison BN.prototype.ucmp = function ucmp (num) { // At this point both numbers have the same sign if (this.length > num.length) return 1; if (this.length < num.length) return -1; var res = 0; for (var i = this.length - 1; i >= 0; i--) { var a = this.words[i] | 0; var b = num.words[i] | 0; if (a === b) continue; if (a < b) { res = -1; } else if (a > b) { res = 1; } break; } return res; }; BN.prototype.gtn = function gtn (num) { return this.cmpn(num) === 1; }; BN.prototype.gt = function gt (num) { return this.cmp(num) === 1; }; BN.prototype.gten = function gten (num) { return this.cmpn(num) >= 0; }; BN.prototype.gte = function gte (num) { return this.cmp(num) >= 0; }; BN.prototype.ltn = function ltn (num) { return this.cmpn(num) === -1; }; BN.prototype.lt = function lt (num) { return this.cmp(num) === -1; }; BN.prototype.lten = function lten (num) { return this.cmpn(num) <= 0; }; BN.prototype.lte = function lte (num) { return this.cmp(num) <= 0; }; BN.prototype.eqn = function eqn (num) { return this.cmpn(num) === 0; }; BN.prototype.eq = function eq (num) { return this.cmp(num) === 0; }; // // A reduce context, could be using montgomery or something better, depending // on the `m` itself. // BN.red = function red (num) { return new Red(num); }; BN.prototype.toRed = function toRed (ctx) { 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'); return this.red.convertFrom(this); }; BN.prototype._forceRed = function _forceRed (ctx) { this.red = ctx; return this; }; BN.prototype.forceRed = function forceRed (ctx) { 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'); return this.red.add(this, num); }; BN.prototype.redIAdd = function redIAdd (num) { 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'); return this.red.sub(this, num); }; BN.prototype.redISub = function redISub (num) { 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'); return this.red.shl(this, num); }; BN.prototype.redMul = function redMul (num) { 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'); 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'); this.red._verify1(this); return this.red.sqr(this); }; BN.prototype.redISqr = function redISqr () { 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'); this.red._verify1(this); return this.red.sqrt(this); }; BN.prototype.redInvm = function redInvm () { 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'); this.red._verify1(this); return this.red.neg(this); }; BN.prototype.redPow = function redPow (num) { assert(this.red && !num.red, 'redPow(normalNum)'); this.red._verify1(this); return this.red.pow(this, num); }; // Prime numbers with efficient reduction var primes = { k256: null, p224: null, p192: null, p25519: null }; // Pseudo-Mersenne prime function MPrime (name, p) { // P = 2 ^ N - K this.name = name; this.p = new BN(p, 16); this.n = this.p.bitLength(); this.k = new BN(1).iushln(this.n).isub(this.p); this.tmp = this._tmp(); } MPrime.prototype._tmp = function _tmp () { var tmp = new BN(null); tmp.words = new Array(Math.ceil(this.n / 13)); return tmp; }; MPrime.prototype.ireduce = function ireduce (num) { // Assumes that `num` is less than `P^2` // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P) var r = num; var rlen; do { this.split(r, this.tmp); r = this.imulK(r); r = r.iadd(this.tmp); rlen = r.bitLength(); } while (rlen > this.n); var cmp = rlen < this.n ? -1 : r.ucmp(this.p); if (cmp === 0) { r.words[0] = 0; r.length = 1; } else if (cmp > 0) { r.isub(this.p); } else { if (r.strip !== undefined) { // r is a BN v4 instance r.strip(); } else { // r is a BN v5 instance r._strip(); } } return r; }; MPrime.prototype.split = function split (input, out) { input.iushrn(this.n, 0, out); }; MPrime.prototype.imulK = function imulK (num) { return num.imul(this.k); }; function K256 () { MPrime.call( this, 'k256', 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f'); } inherits(K256, MPrime); K256.prototype.split = function split (input, output) { // 256 = 9 * 26 + 22 var mask = 0x3fffff; var outLen = Math.min(input.length, 9); for (var i = 0; i < outLen; i++) { output.words[i] = input.words[i]; } output.length = outLen; if (input.length <= 9) { input.words[0] = 0; input.length = 1; return; } // Shift by 9 limbs var prev = input.words[9]; output.words[output.length++] = prev & mask; for (i = 10; i < input.length; i++) { var next = input.words[i] | 0; input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22); prev = next; } prev >>>= 22; input.words[i - 10] = prev; if (prev === 0 && input.length > 10) { input.length -= 10; } else { input.length -= 9; } }; K256.prototype.imulK = function imulK (num) { // K = 0x1000003d1 = [ 0x40, 0x3d1 ] num.words[num.length] = 0; num.words[num.length + 1] = 0; num.length += 2; // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390 var lo = 0; for (var i = 0; i < num.length; i++) { var w = num.words[i] | 0; lo += w * 0x3d1; num.words[i] = lo & 0x3ffffff; lo = w * 0x40 + ((lo / 0x4000000) | 0); } // Fast length reduction if (num.words[num.length - 1] === 0) { num.length--; if (num.words[num.length - 1] === 0) { num.length--; } } return num; }; function P224 () { MPrime.call( this, 'p224', 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001'); } inherits(P224, MPrime); function P192 () { MPrime.call( this, 'p192', 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff'); } inherits(P192, MPrime); function P25519 () { // 2 ^ 255 - 19 MPrime.call( this, '25519', '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed'); } inherits(P25519, MPrime); P25519.prototype.imulK = function imulK (num) { // K = 0x13 var carry = 0; for (var i = 0; i < num.length; i++) { var hi = (num.words[i] | 0) * 0x13 + carry; var lo = hi & 0x3ffffff; hi >>>= 26; num.words[i] = lo; carry = hi; } if (carry !== 0) { num.words[num.length++] = carry; } return num; }; // Exported mostly for testing purposes, use plain name instead BN._prime = function prime (name) { // Cached version of prime if (primes[name]) return primes[name]; var prime; if (name === 'k256') { prime = new K256(); } else if (name === 'p224') { prime = new P224(); } else if (name === 'p192') { prime = new P192(); } else if (name === 'p25519') { prime = new P25519(); } else { throw new Error('Unknown prime ' + name); } primes[name] = prime; return prime; }; // // Base reduction engine // function Red (m) { 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'); 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'); }; 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'); }; Red.prototype.imod = function imod (a) { if (this.prime) return this.prime.ireduce(a)._forceRed(this); move(a, a.umod(this.m)._forceRed(this)); return a; }; Red.prototype.neg = function neg (a) { if (a.isZero()) { return a.clone(); } return this.m.sub(a)._forceRed(this); }; Red.prototype.add = function add (a, b) { this._verify2(a, b); var res = a.add(b); if (res.cmp(this.m) >= 0) { res.isub(this.m); } return res._forceRed(this); }; Red.prototype.iadd = function iadd (a, b) { this._verify2(a, b); var res = a.iadd(b); if (res.cmp(this.m) >= 0) { res.isub(this.m); } return res; }; Red.prototype.sub = function sub (a, b) { this._verify2(a, b); var res = a.sub(b); if (res.cmpn(0) < 0) { res.iadd(this.m); } return res._forceRed(this); }; Red.prototype.isub = function isub (a, b) { this._verify2(a, b); var res = a.isub(b); if (res.cmpn(0) < 0) { res.iadd(this.m); } return res; }; Red.prototype.shl = function shl (a, num) { this._verify1(a); return this.imod(a.ushln(num)); }; Red.prototype.imul = function imul (a, b) { this._verify2(a, b); return this.imod(a.imul(b)); }; Red.prototype.mul = function mul (a, b) { this._verify2(a, b); return this.imod(a.mul(b)); }; Red.prototype.isqr = function isqr (a) { return this.imul(a, a.clone()); }; Red.prototype.sqr = function sqr (a) { return this.mul(a, a); }; Red.prototype.sqrt = function sqrt (a) { if (a.isZero()) return a.clone(); var mod3 = this.m.andln(3); assert(mod3 % 2 === 1); // Fast case if (mod3 === 3) { var pow = this.m.add(new BN(1)).iushrn(2); return this.pow(a, pow); } // Tonelli-Shanks algorithm (Totally unoptimized and slow) // // Find Q and S, that Q * 2 ^ S = (P - 1) var q = this.m.subn(1); var s = 0; while (!q.isZero() && q.andln(1) === 0) { s++; q.iushrn(1); } assert(!q.isZero()); var one = new BN(1).toRed(this); var nOne = one.redNeg(); // Find quadratic non-residue // NOTE: Max is such because of generalized Riemann hypothesis. var lpow = this.m.subn(1).iushrn(1); var z = this.m.bitLength(); z = new BN(2 * z * z).toRed(this); while (this.pow(z, lpow).cmp(nOne) !== 0) { z.redIAdd(nOne); } var c = this.pow(z, q); var r = this.pow(a, q.addn(1).iushrn(1)); var t = this.pow(a, q); var m = s; while (t.cmp(one) !== 0) { var tmp = t; for (var i = 0; tmp.cmp(one) !== 0; i++) { tmp = tmp.redSqr(); } assert(i < m); var b = this.pow(c, new BN(1).iushln(m - i - 1)); r = r.redMul(b); c = b.redSqr(); t = t.redMul(c); m = i; } return r; }; Red.prototype.invm = function invm (a) { var inv = a._invmp(this.m); if (inv.negative !== 0) { inv.negative = 0; return this.imod(inv).redNeg(); } else { return this.imod(inv); } }; Red.prototype.pow = function pow (a, num) { if (num.isZero()) return new BN(1).toRed(this); if (num.cmpn(1) === 0) return a.clone(); var windowSize = 4; var wnd = new Array(1 << windowSize); wnd[0] = new BN(1).toRed(this); wnd[1] = a; for (var i = 2; i < wnd.length; i++) { wnd[i] = this.mul(wnd[i - 1], a); } var res = wnd[0]; var current = 0; var currentLen = 0; var start = num.bitLength() % 26; if (start === 0) { start = 26; } for (i = num.length - 1; i >= 0; i--) { var word = num.words[i]; for (var j = start - 1; j >= 0; j--) { var bit = (word >> j) & 1; if (res !== wnd[0]) { res = this.sqr(res); } if (bit === 0 && current === 0) { currentLen = 0; continue; } current <<= 1; current |= bit; currentLen++; if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue; res = this.mul(res, wnd[current]); currentLen = 0; current = 0; } start = 26; } return res; }; Red.prototype.convertTo = function convertTo (num) { var r = num.umod(this.m); return r === num ? r.clone() : r; }; Red.prototype.convertFrom = function convertFrom (num) { var res = num.clone(); res.red = null; return res; }; // // Montgomery method engine // BN.mont = function mont (num) { return new Mont(num); }; function Mont (m) { Red.call(this, m); this.shift = this.m.bitLength(); if (this.shift % 26 !== 0) { this.shift += 26 - (this.shift % 26); } this.r = new BN(1).iushln(this.shift); this.r2 = this.imod(this.r.sqr()); this.rinv = this.r._invmp(this.m); this.minv = this.rinv.mul(this.r).isubn(1).div(this.m); this.minv = this.minv.umod(this.r); this.minv = this.r.sub(this.minv); } inherits(Mont, Red); Mont.prototype.convertTo = function convertTo (num) { return this.imod(num.ushln(this.shift)); }; Mont.prototype.convertFrom = function convertFrom (num) { var r = this.imod(num.mul(this.rinv)); r.red = null; return r; }; Mont.prototype.imul = function imul (a, b) { if (a.isZero() || b.isZero()) { a.words[0] = 0; a.length = 1; return a; } var t = a.imul(b); var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); var u = t.isub(c).iushrn(this.shift); var res = u; if (u.cmp(this.m) >= 0) { res = u.isub(this.m); } else if (u.cmpn(0) < 0) { res = u.iadd(this.m); } return res._forceRed(this); }; Mont.prototype.mul = function mul (a, b) { if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this); var t = a.mul(b); var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); var u = t.isub(c).iushrn(this.shift); var res = u; if (u.cmp(this.m) >= 0) { res = u.isub(this.m); } else if (u.cmpn(0) < 0) { res = u.iadd(this.m); } return res._forceRed(this); }; Mont.prototype.invm = function invm (a) { // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R var res = this.imod(a._invmp(this.m).mul(this.r2)); return res._forceRed(this); }; })(typeof module === 'undefined' || module, this); bn.js-5.2.0/logo.png000066400000000000000000000375061401525734400142160ustar00rootroot00000000000000‰PNG  IHDRÈÈ­X®žsRGB®Îé pHYs  šœËiTXtXML:com.adobe.xmp Adobe ImageReady 1 ).Í==IDATxí]œ^Eµ?ß·½—$BB€ $„@ÀPEAŸJŧұ Q( ‚"*HQQ@’`è%!@hRÒ·÷Ýïýÿgî¹{¿oï¶dRf~»ßÜ™;åÌæÌœ3í&RK«R“Ò_‘D‚.ïöx¸v°¥·‡¤ƒÁÿz<q$l‰{éý<[:~ÙÒ[€/¯dÛ[/s;$¶t™Û—ßµã?‚Xám@ ^‰Å{y ?‚ÞöÄ àu¿î£ÍÂdn¯ƒ8.1<üÓkx/€!àuCÂÛüŠ÷ò^ñ:ˆ¶“¹½âXÃðð#ˆuÞöÄ àuP¼—GÀð#ˆ!ám@ ^ñ:ˆ6 “¹½â¸Äðð#HL¯á½<†€×A o{bð#H (ÞË#`xÄë ÚLæö:ˆc Ãà ÖUxÛ#ƒ€×Ab@ñ^CÀ †„·=1xÄë Ú,Læö:ˆãÃà 1½†÷ò^1$¼íˆAÀ 1 x/€!àu¯ƒh[0™Ûë Ž5 ?‚XWám@ ^‰Å{y ?‚ÞöÄ àu¯ƒh³0™Ûë ŽK ?‚ÄôÞË#`xÄð¶G ?‚Ä€â½<†€×A¼¢mÁdn¯ƒ8Ö0<üb]…·=1x$ïå0übHxÛ#ƒ€×A¼¢ÍÂdn¯ƒ8.1<üÓkx/€!àuCÂÛüŠ÷ò^ñ:ˆ¶“¹½âXÃðð#ˆuÞöÄ àuP¼—GÀð#ˆ!ám@ ^ñ:ˆ6 “¹½â¸Äðð#HL¯á½<†€×A o{bð#H (ÞË#`xÄë ÚLæö:ˆc Ãà ÖUxÛ#ƒ€×Ab@ñ^CÀ †„·=1xÄë Ú,Læö:ˆãÃà 1½†÷ò^1$¼íˆAÀ 1 x/€!àu¯ƒh[0™Ûë Ž5 ?‚XWám@ ^‰Å{y ?‚ÞöÄ àu¯ƒh³0™Ûë ŽK ?‚ÄôÞË#`xÄð¶G ?‚Ä€â½<†€×A¼¢mÁdn¯ƒ8Ö0<üb]…·=1x$ïå0übHxÛ#ƒ€×A¼¢ÍÂdn¯ƒ8.1<üÓkx/€!àuCÂÛüŠ÷ò^ñ:ˆ¶“¹½âXÃðð#ˆuÞöÄ àuP¼—GÀð#ˆ!ám@ ^ñ:ˆ6 “¹½â¸Äðð#HL¯á½<†€×A o{bð#H (ÞË#`xÄë ÚLæö:ˆc Ãà ÖUxÛ#ƒ€×Ab@ñ^CÀ †„·=1xÄë Ú,Læö:ˆãÃà 1½†÷ò^1$¼íˆAÀ 1 x/€!àu¯ƒh[0™Ûë Ž5 ?‚XWám@ ^‰Å{y ?‚ÞöÄ àu¯ƒh³0™Ûë ŽK ?‚ÄôÞË#`xÄð¶G ?‚Ä€â½<†€×A¼¢mÁdn¯ƒ8Ö0<üb]…·=1x$ïå0übHxÛ#ƒ€×A¼¢ÍÂdn¯ƒ8.1<üÓkx/€!àuCÂÛüŠ÷ò^ñ:ˆ¶“¹½âXÃðð#ˆuÞöÄ àuP¼—GÀð#ˆ!ám@ ^ñ:ˆ6 “¹½â¸Äðð#HL¯á½<†€×A o{bE¬˜w·W äEÄ£T*pT')1qaã.ˆ§ncF d“¹¬Qmìn‚Ò˜Ef ÇDL'Þw&w°¦bèM¥¼ž~W·º¾B‰4­ÿ¼ hð­-IioÇCÐøù2';%99A@ö¦_ðÙÃÔ "Ùduö¨Ú›$;åþ¹•òÇû eÄÐNé„ÿòÕIùê1õ2s¯j‘ö¤c¦hkèŽÃéC M4õ"i|Ø4GŒ²,[™%·ÿ%G*¶IÉš¼\–£É‘‹à†åM€CÐQh“„hšÝá aGB‘Ô:bfÏ[0x!ƒl22.++£âòóX›)Ùk\§t@÷ø×ª¤äfŠW¢ui šÔ–æ&R"´­%!Ë?*R`ª†6KpLAT%“+þ(𯿄44á¹=¨PV¬¾ñ?D€»™£¶&G®½µJö?e˜ìsò0¹þö*©¯ËÖwÆ 5‘AžõæFéÝLà—Y+‡†ßTÊ.³,ƒáfÃO²Æñpïœ2ùæÅRV 2¬Täì‹ ä¡ÇÊø2lZÿ=`;ôhúë±¼ƒ‘~È ÞÚŒP…<»SêësäßÏäIîÖ))/NIQ>þG¥dÞÓyÒÜ©º‰7ÍBéµ2­®aóÑz#¶·<@ #B]C–¬X“ò<‘æÖ„Îü5@,mlLB‡CŸ™hç8¢s q¶(¼Ph+¯A‚v³ÅX`–lLðååºF@‘‹RT9Ü™“[ &½4dö¤Ö›2üFëfmÄXøM¥|AÙÀc(&4ÊJÚdìÈYñ¶¨xU\˜’êwE¶Ù.ù¹J0Šhþq•ž Ù,ºáà¿™Å2ˆ¶QÙ ÌDŸÍÏÛB€.Õ)ð‚vùìÁ ˆ›’ç&å_óØ Rrä ’•ßõ%»vÉ †X»DÖ¬ZÑ cPL²ra+¦Ö‹é°N‚¸&cnIn+˜Ï’½v¯•gî™÷T¡nÉ™5½A&ïX/Òù‹81,‚*\øl¼tºénìø‡ ¢¨l ?ÚŠ!\ßHêj¯[ÀÚÈÛ”i°Â5ü„LÝ£Z¦N®uEʰÆÑw†ô^DŽ$r;0A «÷œpþ¾!ƒ'ÜÍŒ‰ +‰S’É< ÷˜e©Ã¢Vi1dc}é¬~ÿò°ƒä5êz)k>0±é÷õÞ"ÃŽ?Hï™¶ŽmX vAw¶ºgË×lËrÀnFŒæÔC]m޶¡Ž±®•Œ™rk4A†Î/’—f=HîGAXiÚ£€ªd^»T¯ÊÕÕÞ¹Ob+ÌBÆ \‹Ã:Ó·m$–Pކás¦;¨+‡åÃ|5¯ŒJK‹otDíÌô£îh¸µxv #3Òä’çg˜Nåd:L,†^Åu9uzí­ÃµŽY×I¬î/}ÏøŒŸ¯6¤ „„…Ä‚ íf#¢!X)yêÙr9ûÒ*9ë‡EÒ¡x­L0ËBðY ITN2ÿ9ÚKÓß*",€…º™†¥ƒÇ°Ñc„ëćÉù°ñ…ùh^.+#ËƳ´a‡ùEßkà€„ ¦„ï—;-?ЖÌÑZ˼h‚´3é±ôi‡;2Ã3('ËÎw–ôù…¶fé {¾Îúa¡œõ£*yü© io£ÄЮ|¥u„³xLÏòç« åE,£gCÚŠŸœ‚­ëÿy¯PîüG™|ë’|3ŽÔtbÞÞP uAe%)_c×j{s–´´ähƒHfuH!‡øl4(¦ÚT¬BͶìàf…$x0‹»_£ä»`ù^×PÉ‚Ên¬ÏF£sýO6òÊ/Bå³!2¯ ·f2Ú“GÓ ò6¸ÃÖŒŠ!]Nó˜øZà . I E-Ìp¥Pž4šø¯+èh8¤°Ù±©1G™‹id!½bÊ5”³P¹­-|›n\vÊü³ä–»ÊåGß./|ªF¶Û¶£p‚ص1lÁDA‰”a}»™{-UÂѨš±QnΓ•rÅMEòïG“2}ZJJŠRòÎë<ÏTb„¾~=¢qq´hkNʳ *äßÏæË»dë᪂‚NÙ{r«8£Nª¶j‚®Ó¥ 2íhù]ƒJɲey²pIÎúèT(ÈÚmb£”—¡ñ³!àâWKäñÿ+”—–äHc“c¡å2}·ÙoZT iqyEó@:i%„ƒyÒPc'¡" ˜ÙE#Eée¼87ÓÔ²€Ñß|«H–¾—+¹¹Ýf4öí·i•í·mÄT°£&L# ‡Y’ž6”ëÅ—ÊåéóeñÒlt:('ÂT”vÈ®ÚdIM2q;4t¤j ŽDeâ#ëžf<¶¸Œ¨9ÿŠ<ù뼡rÞ)…rȾ5RZ‰s Б:AK£„´i*ñå ^©µ¶áC‰&¶^ž#ÊCMì¹ØxY÷¯¢QÝô—R¹âW¹² Fý÷¥lœ’(èD¾¥uàu°çEúk–ʯÙ?ƾ šBü3ÙŽ,¹öw9rÄ¡ùrÙ9Õ2iÇZTf„IÒèMHVv»¼¿,W>úW˜HJ>Ø.å[5KÓê\ùóò?WJÓ{x—ƒ×D—<Òˆ©ÓT®œrl¾\ðõ52vlƒt¶@)¶®AÔyj#fòQß}§P^~½@  ÌNžØ •CZ]/Ï5~ÐÓ/x¹H>:¶º锲b‘šw’ò§_4ÈöÛcªØD é¡IævʇïçËoÿ\!ß¿2Xz·22:€.#¶/”oW,Ç~²FF2‹8ÚÉ÷ð­Ž<šð‰™)ùÏÊ„ób9õø<9õèzÙs—Z0d':”$F.äïú›0™µ.W }>… b § ¶›1M¢È„·fežÜ7»J¯-”•ï&dï½R’ =À-úORV¾#ò½Ó[dúî¨4îÒ7jõøcôàlCÄœ«n"—\“'ûìÝ©Çp£òm¦ï›—%¬¬;®è”v¨ïj¸Èô2=üÁ&aýW¦dÆxõ'žã{¼Å6û_ýqˆœ‹Ý±»NNI嶨M˜h^¬Üßý1Gê+åÚ :¥jx³ŠTŽYÑ,5Ž |€³àÅ29qv¹,ZèÊ~êñ…rñY«d8]' ׆¬‘ôU_aL&Wk>%3'àÌ<çð4™:b¬ünF±]Þ¨söeCäoÿÄ:ÊÔ”6lŠJܺBÃFßfhmÝ)¼ó¸V1²QÎÊç&eß=ëäŠó“òmv\ypïš’‘CR2|o‘Ê‘ÿP.?»°@>whŒD ˆ«:aÄC¹Ãò2Á(~Ä„^A†ÖÖÖÉ“.õõðëTŒ%üŒKªä¤s‹dkl·Þoºœç9þýXBöÙ©C¾½F~pú2³ †}ä!]=‘Ø¡=nJ˜_¡Ìqàþ`AãLèª6¨ u¨·ô^q<—”Ÿý¾\ê1Lå]G¸˜ (æbâ{ÌÐMàšOæ(”öKɰò”Ô£ ÕuT|EZÐXj‘W}“ÈAŸè”?Ý›-ü{9*X qiÅebeRôH€†êÕyrÅoJ•9Ü¿S{ØoÏ•»ÿ… e$Ãi`\}ˆ!¸¯®(|ŠþwERz(¦B¯Æy٠ʤ‡õÀò­F9Ÿ~#)Ï-E‡V“ÐNˆ)̘Þ1«OÂ$«L4bD“œû¥eòôŸ«åëGµÉcO&tÉ&ûS¸?_N8o˜ücÎPiÄËd>EÙ®Ž‡ÏjÌœƒi…#H˜Yú:»™gЕ.ÉŽ4%\†;qÊÜãO¢Ö«RòëËåȃjÑS¢UAî¦ÂÆÆÙWC Í ]Ù‹?ñBž<¿(G&Oî”÷V$dÉ"¼Dã•jìbÝFd'lõn†è¶º6!³0¼_wsŽ|rÿR9ì U¨ˆZ$?ø\”aLâA^O¢×Üu´ÈÐ7æ=+£wHI+ï±'PäS‰v¼ú…„l7½b¹Hò"ãì¶{J.¿-OݯH&Œ¯ƒ¢›¾þ ð£¬‹Þ,;ÁL3Ðq0|ò˜ÿ\Žsx®µE–8gÚv ÀBeŠ¢]³ké©°îw ñÀür¹ñöÅŠKŠùøÓ Ùz»”º'vÿ¢zŸZœ% çã2;ÿŒ>•f Q,ƒüù¬u f˜¶gµì´C£:³T~ü»"y䱤ì¹gJ !°^–~˜”O~©DÎ95_Nþl­ìºc&VÐ8 €†cb—æ!?³îÖÖ2ˆ–b(b¨Ž pMwæB ¿òf€§aˆ.Ä9NᾋüÎë"ç~µMNþïZÙebÊï\¼"‡¹Jê›8Vh@ʆ¨ð§‡ò²ÈÒÕ Ùoǹê[ 2fëVÕ#nû[¡ÜöH¶ì3.%h¸lØE£DîøG¡Ì˜R'ePºÙÃg‚J ˜: B熻òÐX2´4%-¹æ¢&™5½" yžÜpg‘<¿ 0:ƒF´— Èû/<ŸgÈÈû,Ód^Ά««»ª†¢ d6Â.Ç6õædŽÁÖÙ¸22¥Hë ReÇ–€÷Ñró=ùèV©žZ‹Ïm‘/|²V*ËÛ@{Bj1ÑòìÂBè6…ЗZ%¯Àbu>Ä1’…–L•jΖâÒ69ò•Pîå/–ÉÙ?BÅ$eïR²ÝˆN=,!Wߘ#¿y°R~úùô5˜Xi–;Ousb—ëÕÖ’´ÂZ`åÐXaúíÖH®r->ãê¨aJøâù”ð+¡„A£Üo×è© -ø¿„èºï5ÊÓk¤;Muн´Î^°CbzLFeôÐηë—ôSÌ*ÁI92Þ»tÈOÏ[%ÛQù„³óβûNRRçä€vÆ¡ɯ‘ƒÌÑÁu08ÃqfŽÌ2qBŒÆášJ4ÇÑÚHá&Ö4ÀoÊî5rÙ7—É}¿­“GwÈ#ÊéŸo‘Eh¸l€4Û@§x![V³áb!M«¾!8šDÐS¹gæÃ©ÉiÓ:åˆYä4ˆŒ˜]âìóÒ©fDœ>¹A¦NÅéLjÅàÁ_HʇËÝ´‘öÔÈ'Ä¢éÄíšäàYòÄk ìYâ†ÈÛK vìÖ&C+ ¢EHIŒ`⥘¸=ÄÙq/á\ê²eÉ;`ö —þ+ òé}ÛeÔV¡0Ž h×øwâ"E§v™,ëv&=Ýܦx¿õSXÜ!ŸB§ù{tž×_Ò$ ÞÆÎcèw'mÓ©£ÙÅ?Ï“ÃO"·ß]%kÐ'Ñ)³s¶ÙCæa¦[~M}½š†€4`6HÞл&0ÛÁ•ð«o.3Ž*—ÛÍÖ5Jp>g§È<ÿü×_ÕË•ç-—){Ôh¡=4…K©`á"ì/eLƒ½4kæ ˜„XÄÅ&M´(ÝŒ)’3z'[`FU@ ^˜…† ù)èÕÜ›à7ƒž´›7^MÈQ¶ÉHLÛ²÷´Þ148ĺ*¬]ì QoÉℎTnŠ•¢È0d.® Ö"çÿ˜Ûnæþ;)óæ'䳟j“ÏR£ŒÈ2D@F2ƒã-MØ}ðöI3¤p°ƒ©,ãî†À¡ÏÒD B¨ÂÚûOP?ŒÏ‰ŠøÈQMòõã–ËK·­–sNi“'žJÈ«ïaŠõÌÙ´<@xÂÙEr&¶¬<ùt¥nSêmËJït»Ö:“RÆ ˜ºm‚‚6{j~üÛb™ÌD”@e/:o1J³Räòï6ëмíÖá¼6z 6BFã¿U:Ÿiº¹ÕS_uûaœ<ô´/ý'!ÇÕ.cF¢Ñ"íÆ˜>ž´¾'gÇÆlÝ,'ÌìÛægË´1¼¼@dá‹ (ò92i§ 0#1¦Ú|v¬ ¶@ â|¿4â¤B4 óAþyX}; ;¹-ƒ£KH@ÔXùµì oÿ½jdñÝíòÊëùRß)S ÄVUaá G ÉtÃ'hšs±Ê,{4Žž¸×[¡’fK“ŒâF×®Dí]Zv ÏR"d4Ö&(vq:|—kå’1U÷)•kn+’ÎÂl¥È¬ ÙG´3¾íÏåòãïåc–¯VØÆ’ =ÜÚÂH£áÒÛ^ö>dGVÌ/ ¶R¯9M çJø_±þË\ ¥wÿ};•Ã9ãÂ!ùÄcÚõ*Ðé“k$ L“B¡±8“íÚx‘Tê õ`=Nî€e!¦§Õâ`T)‚·ç¤6¹éŽlÉË^Ïô£€…£jË€J£Q,ãZJé6)Ùz¸YÖF*†gjœþÌÂ(6j¸ëqv.µÕX7»¨ ijî´ñ øÀ‡SÁ Céì:eݱ" ­ÏA¶Èˆœ‘ëÄHÈgÁàÊ›,Û âå%ØCˆh§°®ùeqåGÑØy’!!¶BG=ìÀU˜di”û*•³¯+—^LÊÌ)9`B§4ŒIÈy—åËŸþ•+³¿Rfª‘’ Š‚][VJK§†•bÜEÐlïthG,Ê{”ûnùë0Ùÿ«C”9Hè(á­PÚæÍOJ#ÚÍí?oŸÏ^.ûL_ƒíàhŒ4lH–&Ýa~tÀôèî¥1ð•é •åØB¶/=?mø\×À9lgºD–¥ÿÁ¦Fìߢ˜¥á‚f‘•¨gÔc€_…ÝØkÅF†%!Q:ñœ€& ƒçFˆ¬ü0l$Ëϰ*ϳ‚u’!Ø×¤­øEžÕÍL`2ñ óp¯3~ƒD2|9P€ÑoÛ)y 3w”ÿwÇÔëïæfÉ[ïa¸¥žÄa ÑT2ó_·‘ø쬨£RWÝjD³œúùåòÌoVËyßh•GŸHÈË»¨Rìâ‚ðQ_+–ï^Y…YÒr` )E÷´OW Jkè ĈéɶŠeFÜŽNyrW‡c"ÁVW¾›Ä»„\xv«Âº×h,6so×õwäÈžÇW虢Þ/Ð5ždÔ:è'½!ƒ0R´ò¢n>ëVoU °¿É)áw<ž-31í6Êí ¬P? %|椙û‡9ÿëɸqníÁæ¹9Ó¡]NWOù±n£ù§¹·'Ãe=DY ‰Žòd\%½#ÍVC;dÜŽ˜­¡¢N¯!XlÇ|{ f£Â $Ã8fèM†wÆ¥§Ïô2ïàmœ¥A¢á"ñôÑÞ!é47“‡Ç@ðë˨‹JbÉ­öI0Àä‰S`¨Or±s&V÷¹±ôæ¿ ÁÌÚ¡Ó$“ „žÓü‡t±#ã3¥îÊ>ø«ä×ÿ»\~û“FYÍ?’Ôý`Ïè”=Æ Îȉߊ *†H¶¬°-+­,vPôžèéUa•+Q ¨¹) [**äÒ‹å±ÇÝJ8b.ÊÍ»htJ üÔ,¬rbŸ gt(°ç4…KÓb¢4aÎ1x¿–¬6\V²yD³°‚r¡ Åöî#bØÑ˜’^ŽéØzlé®0Z£q{|ŽË¨ÇÀé/Ö!jzBƒë¢¸Ê3,ÜE|äaEòÄ"¬qpÖLÂ-0§}¿b×09õ¬aAß³ÙH6âаlQwøb`iÁáò€ØE£ý°ª9å˜å²÷îÅò‡ûJ±/»#°¦22щ¿óQR=©TfŸ‘/ßùÊ*)+oQ^ÛIZâét…#3ŒLŸá§2=dõ%oÈá'—ÊkØe{ä<šð8ív¶ˆ< y𔣗c 2Æbœ›ZíR‰QfúkåfBý1A¡Ã</|¶øCñ¨ªr+fj¥ÓÐévBÓ r–Fœ­…{уŸ•)´Fé]WwïÔH§›N9cæìÔÏ5êîj#‘>¹ðËÞù²†ËŠeùºƆa¡¦$½®ô§Ågš¨ú™Ø© ³˜HØ{µ¾Ú2•b¸‹‚K Üs7zXJ&ï–BŸ =;ê=ì<‘NZúHÞÜ!ƒ¤CÓÝÅáu‡S²-ä»&lï¦ÌΆÜT+W|çL‹â<Ôi9ø‡â”%eÎÅfÂ[¹òNI7WÊMTë™N†ÞH Õ3ÑzÃF¢òþA3ªåü3B\Šó0œâæ¶v®l_üó\9í‡É›oCÎw“o}ÂIÛ1Š›: vñجýVËí?ùPnüq£¼¹‚ N<Ü›E³‚iöþ€2 rb:`, —ù ,_d#ûUrn+†·5µYºÚª[‚Ô,hÿ—¾…c.ý~MÔÈëͶð°£ùiø‘!(*6ºzÕ0ÜðHÐ{7LØÏÙË«ŒÎiÉDâõ Á¾Â÷Dj:éÔ1MÖ3íò¡¬ŸqÂjùügÚeîü¤nûà$Et7î’¸kN¶œ4{ˆ~K@'¡äÅ»/úÖõ=)'|Zmèô8}^ƒKºkêpQ^Ð.õ<0`ÔÀÝSþAÔhè˜g6'»jÞyòÙ„nEf£â*æñgÉÉßÛJ{ªGY(öìÓ¤õÀ™Ådñ±x¡\yÐAªpªé*Ž %7Žæ8¿…ð “©õ:ÅŠ™£áÐ-/;wµqn%Áê~9'B`¸ý}Ö”Ny|QRθ´BÞÁÁ*®fÛ”{·¹.äÇÔ·.Zcd`¾ÕkräŽû†ÉÔ/V¹» ° €³šdèÇ0%ì¶Å$CWÈ &sY?:=‰ß cåÙ{«åKXôcÂí…˜òãñØ9/eÉÌcÊå'7—¥fyÓ…N§½ˆ¦“.tË/æß“þ2>#=M~\Ö#½˜ªî2K+$ ›‡{Cï^…Q£6o­ñ ÒÍŒß;=F@”(<›7l¶*á<.|ýVÊÿœÐ¦k]ÜÕÌ-7kppꜽ™óH–üô¦ >ÃÞ(´6\¦Ã¤H“™LúúíÒ°´t]~ì˜y3Êã˜H:{=£H*Ð>gatãYš9`^n úÅÅMØË†YL"iÛ&AˆßSþ!ƒá¡MBÐb‘š…LöÄM|Wo™.þÕ"NëR¶}§^²pþOòä¨s†È]àÞÚÚl%Ú61ð0“ù•Þ ñŸ¨Äf<Žz,/·ƒÜÞ ÚrŒk@ŽIFá„çåßZ!—׬‹ty¹¿ŒL2k¿”žõ¿G© ¢Í`jÝ÷ jï€Fâ; ÅMCsGôëKŠårLìû¹r¹un¶2ÆHÜLÊQã+ÿÕ. î[-ßÀ¾®"\BÈÍ”û2á4¯6`„&4¡D)“ ñp¹¿ kÇ}f…LÙ¹Xn¹§T.½6W¶›FwêâÌ«pðþ4¼Ï—¯}¡+¯8F™T÷ì;™6-}:&ÔÇÌü3ÝAxZý2*l>ZùzŠË…½¢.öHý-á˜@½¼Š íã ‹7<2ñéÁ¦Ý#AÄÈ{¶õÅO×3˜Š0Ï=e9N •S¾]¨÷ °ciBÇ9qÖI~Ãg{Èèm°í {è“ú]ß–7IÒü:(ºé5QØæ¾÷<0¿L~pC¼Qb*N#Rô«ÃjúSX°ž²'Ž9_× ‡ÌÄM)º Ûœ ji›¶ò…Ôuµkÿ}ó©dB°u˜å9l¤›€=ÿb:íßãà¶X„ØÅÙ­‘C1ïŒ-'7þ=[¦Y!×ÜR¥;|Mìâh…@Ý€nÖG7ñlÇž¢f*ÆL˸À² …ÁŸnq·`ÂFŒ¨“t äbJüäÏ®Ðõ/îž ^J‰b+ŒÆ<çÿô‹¸5…Û<”+w€ØEªIcFÅ©V\54ÿ‰ ÌžU©œmL§x4à‘×’Ê?úN‹üé§+åè#VH)O‰¢ƒçÖÒa  Ž^ GJCô™ie;=ûéà¸#WÉ›ïe«4±/:GÝå ëÑyò©Y9’_€."Í€ÊG²Lôåª>î5œPýãßK墟á^¯­žÁ°+±›cáK ùfÚN;¾w‘ÕJ6ò¶Í±Ê¨Aš ?ͤ•YáúA,™ ŒLÙ’«˜Ü<¶5NŽƒOÏÜS-'ЮºÉ2ì‰)*à|4±¸ø©SJ䂟 —…/ãH\»}YX'K2QügÍ÷5F¦*‡..-^îÆ…AntÓìqb®¬„ŠèÃP®¾–hZ±ži!6kÀâz÷Eåã˜ôñGÔÉÖ;¤0£åÚǬ¸/Àɿ嫸(ÇNu€x!8;bÖ#¯ŒåÙø•+ò°9v¸zÚeŽé¸&Š7 4á(7ÇR/¾åª¹îËe_lŽÍF§Ý›V$§$… ¢£‚¶—LÜNɉG%§N©–Ÿaç.wð¶b({äÑ$fˆp6gŠyçÕU¸9d¯S+å7wVÉ Jb¡Yx»¢÷˜„Æ´ÃÁ8¦xÕBlr <…w|OCÛf0>Z‘%ï¾ ƒŸÝÌýYÙ¼ UÃ1‚FËø¡gì çÝëŒDœÓÂF’Ì,?³2ú)ó}_îžHM'À¹ìWó hë–~HqÄ,çcå¤CÛô< Gbžš|§!×`²&sO£†éŤÏwœŠÕ޳SÜY=w~¥|õBnŽ-”BðÅ)æuCÔ5¾{6Ç^·J¾‘—ëñÂvàìÈ™Žæg‹æø…ôd¸C+·ßL”™«ØÅö¤J|+”xœœ„ƒ÷Tâ‘+£¶Oȸ­;eÿiø>7æÌOåÁûÃóä¬/ÖC‘«Ñƒ÷µ·à؇4×ÖƒÔÕCWb¯Å´‚JÐ43žµñ‚GZ9ON3Ÿ'ËáĦ7CœiÖ—À ÿZýóÌM.¾L5n ×Àrµ1êLØ´CÔiö42‚ú±j²Ù)n€ä÷îyëæm÷ºv4t 6JB„ËA§Êµ—¸Y…k2gþ¨AfN­‘<~"ƒâ;CÅwvÿÌx€ „ =jÖÆ K/+ ×NÀÕ=ß?½ LQ&?Á}Gœç ·)|b¦È¿_Î’{ŽÅìÃ9ùžkeΈó†Ýù‹túÊ?Jk}nžäõ¢¯¼‘- عYÄ[C‚Þ(,"@ãô3÷½ñ8†€rg͈ašü…yõpšRßdþ„)¦¿0ï[Ezð‰-^³ül€&[RDmsᣩfâæ >G ý æì)?ÒHñ‰ø ­p= g³,ÿn¢U•½×ôágéØìÔ² äïóJå7Èûo$ô :oÝlGÍ}•‡ç.m’OT£ ˜zôbÒÁ:Ó6AÐâò£wà–¯wÈ pldBEH bó1ô_³VÉÎãå®âscþt®™Ü!%»ì8"!]'w>\öÀš0 /CàË^0áëA5$ &?óf^Ú0a«ŸÒÏ}O ?ðÓû Ò zJ×Ñ6ãþ´ùÏböÇjï(KvÆ•¤ ÇRäz{þ—$ä œMÿòçê°Ë #ú7êÁî<š©ËA³ÌÖÞ^'Ä*‘Ù»‚ò8‚åN€eA‰oÆ}G¸fò¯ÕrÊízÍärÌ8`S7»qKõqgâÞW|ä|D¯ÍÇ–U¶]²š‡zFŸ‰FÄ„3(帜íủ¿‚KŸ=nˆ7zµ¹¡B–âTÜí¸›w<6`òìõk¨€}'·K•ÞÕÁÌ"À‡yÓ/Î?ðîáU=ú`a›t², èAÔÕ}²B<_†ï˜C×ÓÛV\d ‰cåãÛ°>\ÐI¤d!»ì mŽbš6‰ÊÈÏ9ñ üxÐŒ†b.§{Gì€íHœŒÁ»Ðñé6qŠëdÌà•E¥ráχË!'–Êÿ½Ý§ªpK%¯üáa¨mPO÷ÞX§WMÞ—Wàtõ_Å<•Æ ú˜M&ýuîBJ,H€mï§í¹FÆcËÊ{—˿ĕPâyA:CäæyÙrórårÌa52zt×¥Å6—®dxk…%¤¡Ññ9“ùr±×šÞ;§@>1 Ÿúµü:% ¦`¥è" ħGŸƒ,†,^s©•…‹%öÞ­—¹á¦@ÝŠÀmxÃ:æý¼‹ËyWVÈßÑ“ÒÌ>£X¾uÊJ©à MŒ²ªo B ò&nâéÂŒ`ZAž„Ÿ Å¢6Ü~²øMtç¨ vŽ+±ª>;,†V £CïÏFlÌE25ï÷Âu´âæÆ¿Í)“¯ý 3%ËzÖ„zÓÜ—‘àêÚDsØ&ôÂ軡8ÅÔš¬ý1Á0®e!%6.þ› 7a:Œ 4<'R¬Ä?€‡Ùg´êhòÖ2wÖzLÙíEžÏ9öÛÃ侇pi1”mN [ùû€E`ïµÏv)ùÍpÓÊӘNJk×I–çé_„òwåòô_2E³lLMî¾6™Qÿ@ÅGñ0\Òí`ÑôîáU4Xølaa“Q9³W3 WÝ\æÈ–ƒöw‹¯—^›¦ÇÕŽÃ:˧¯ú²pažiF@šgØ&V®ÌÑo€d¸{§,T¨k`‹û‹‹‹äÊ{rd7Ü‹Lóô†Ý'vàŠ TF * ÈJ;OÔ)O÷=0g6»“¯Í.=Fag0.ü ‚Ϫ5¾|H».œsò2¬Êãþ4̘éýi;#d÷Uþµ}2ˆzP패؅Y*Tã±σ-Þ³F<ØÂKšy6ƒÛ§ßÇš#¿R"ß¹b¸¼Á -z ΀â{6^%ÊmØ» ²f_[¬ççqìÌè³,yµT~ô«r\t͵gÁ XÔĽSÛcº2íR¶òtÐE=FêÇ €¹}ñ›…òÛû²Ð›vJ¦1§QÛãŽ,\”]]ž:"jõ#ÑÑ™õ‡5«»*—‹~1\Þ^ZŒQ [§è!%rÚeñ¢2¹ì×e2,?XO D*~4(Ó´Ô›Ô L—uÉ:=ïÊárá-|;K7½ò|?¯b[à…wâ{%WaïßT\pÄÞXI£#§>­ÿŸPÄR@_ØØ‚ºl·Ž&ŠJFyôyÌ…#¯cgã$øxÍ„íÚä½³å·wçÉk¸ mâÖî^^î½â'þûàFýT÷uÏK½"?($$âÇ»tÏ^\AxW68ð·lªb •OêXÜHÑðtÀ®<éhþ.|Dõ×;MŒY6R솨ËÁ±¹rí92÷Ù¡ò™YmøªV‹T`ë¯þyãí\ùÍÝùú=— [A)oA—ã­S&a‚ér4ÖɃåXðr!65æêQ,0Ã<÷6v‰¿/r.Å>þÈZÙ÷ü2¾[ìcÚA)]‘§ÁnŸ™é… b´¯w…#:%Œ†ÍóÄ\‰?ã‹ÍØPНAáŽ-ÜSe—‚Ž*™¦«Jyj†kï¿™]Nj—I;´È)“ [aÑ uŒ@Æ…Ù›é&à*ž­æytòg¥LÅ8ºÑ°¹08Ã†Ì uÿq!zöcšaºáC÷ð̃Æ*Ì9"Xhz‰†Y—0Èr\í4פî½îÂ^»ï]ÎÞÿqLùææDâIš¹õýÝ×E~5»A?_A‘ˆºB¦qušÂwcýóÏ'äè#Ûåô«êq®¼Vr¸=u›ÍdúŠGo•“™Ñ:ºCI«$º¾Ý¤Ûäè.%¾Jh¬1#3î¦BÇ l~¬$‚ü­c äŸæc¿XÄ6W¡Q¨£PïàeÈ£ògávù/U-9…¸¦³"åØŠ31`~T‹!JpïV øLéL„¢˜ ´´x5Ï'Є¢Bž–kø7KÂ0žýó4'EBwígDGb Ýõcù…> €2õ×h£Fø…¯È«¸Ž•fI#1äV~ð†ÇYi8ÒñûW_Ø$탋´p›FiÉÈÛ˜æA(á%Øôø»+åˆjd¨^áÊÙ©t%\ëCSs?™å[_îA"yo˜Ç ÂX0‚Åž‘bW9¶$‹»´¦L*’ÛþV†óÎy¨ WQ¬7iF¯öÁ VDBÏuÐfäÍã'¶Z×½àê~ÞÂáòbs÷÷òTÜtÈø×Ì®v æÓ­â¢yé3H`ž<óðÊ».EoC‡)äXH“ÙÒ½t^áÆ”‚\–#Ÿ›ÉÆs`èÍdÐÇmƇdJd1DÁÝÇ‘7ñš/Ù*C2/¯¶øëlg”tTòR<œ&}pnR?à3"pFt27'걕ˆ:ÒbFâLׯ/o”°y1‡3ƒºÐee£Ï®N2û˜9áÓµ²#>Çɧ´“Š–‡ñ?2+ŸÆ8qƒ¹™)òvùT «gü„z¹àMøÖD¥^xmÃ9ƒGÛ³Ó‰+ù;pI4ÈU•¨Tˆn£ñ½‰ë/\%?U!×ÿ>ìê]tÈ]çcíËGWËX|zØéÁÌ’Q8BºÏÜc4½œ6y`j:'[ã‡a㥎p‘ÔÈQ*1jpª׎œN~úU>‘šHxePˆŒ#q¼õ¢oÔË'O)•‡ßq=ñÞø¬Ùç­Å=Tép ù2.²î«¾\ºh²zŽø¸„ºÌÕ½`Ø­»ý˜|ú«Aòp?¯)åÚh4ᑼÚÐ#2/ƒ6Ò!øÂRdiŽ‚–“1ÃÛ_øõ¥:|J€LÆMº °©Ê.M¥q˜ÞsØýü¢|œOÁÇC÷¨—±˜eãw7Ì0¹>$ F‹ÆÐ-~ÿ—*9ù›…án,½ç× òéÖ‡xhÒ £³üöû²UùòþG¹:` ¸EÐÆlÛíñÅ'mèX?²ï£k9”Àôò±òšq1_~ÊÀÈLÆÌ“&ŠÇÇéG­X%Íý|,î "™·*ñ¨îÏ Ïà½ÑEÜ "‡z^¦J#[ {U(Úüè' G$~ÅiÆt|ù‰ Vôç"ۚɺš.¼™å£Ïøa^d‚­p#<\ Ñe#9à«dЂq/ì”bOýŒN¥Ç5ö´ü´í›ŠcÎSw…†ÜÅO"ÓôFoø^C2pð`ô ½×c³Ÿš />ëfçë^ñâp*;~]—7¸2Dâ9‚¥êVˆgÙ2døÐÀ:M±žàÅ©à†#Д×=nPwÈ ‘¼?¾Ç P´VF…hRY¯ïÁ´­È\ZIôÃP–¶}v›™Û˜`$>™FóB®‡o2^rÉl°$(ß¹m7€Ïš³ÒßEgfþaÙ‚ÆÉih¦ö´}ЛA¢:‰ã·£arW5ÒÆ´`r8bg¾gÆåcÑφ_Å‘ž,ùÚ%Ï'gèŽÐlk#VOÑwec°CÑŠ\áYpGÞÇæfö ¡Çü#ïY™&¤/\†JÆ3{zš´^ nM¡·üøá(.ÅæmÑüÞ5„˜¸—Z–²ô˜Ÿ¥¥9 djabñb`#6·Œ¬®q#™»…Lq0s¦ü t3„­CX^ôW=(H[ÃGžù¾=ô„ ‚9àáPyßhè–~_ùð½CIIÞ´˜–Vž|$ üëgZŒZ‰ÁÛ0~$tô}褟>tgæOw`,=¥~Œ£&&ðé§…ˆ`ˆ&ŒËWa6u3m~¢z«íðwNnÀ„£‚¥Š0ÌÚò7z” ýézgQú²5= â÷þãzŽ ,tÔxw ×¢>æÍ3úœù®›;Z·`•«³å©E ™„œ~æ¶œñx槬Åö•~fÃî+ü¦ú~³AØ(6kmäkQPöþ&оó~ž,y7#âXîX×Ùm|¦^±úljƒ‘u-²Ü,¢„ ùA±¼;]lØdðİLz9-›Àì$ýc>–ãñGæHòû3w×.Åüæ8ñ ¦a&3½-Å2ˆáíM¶î a³í³!sm(+8{1ï©2¹úƙμrÕ} 2Så` N/{Ó…€×A,ؘ¢f“v£,,™ƒ_SÊâ½µX¤|øÉ¡rΕ%z €'/¹að±7ñ‘Õ£Ûñ™5 #˜²e›zB²Iã,Ö–~?‚D¹b3zVæÀ1ïH~âÉJ¹äzœ½øR©~¾¢›q©œëªþ2‘ÏÞ$å¸ À>/½Á°ÎE GJcœæÝ›.¬;V'&-y»@öÁ…μée/Ü*CÃe¶Íÿ쯴áæœïÆÎ[ÆskF.>Ãnéí!d‚áÍæ€¯œ€Ä«xvÚS¸PÊy˜‰{Àt›?ÎÀr`‡œ}Ò)ÂÎgÝüÈEPå,ààxiódJ2ˆõ––wÎÞ¤ð0:E!6Dn›-߯¶ùJÜúúÞŠ„,}Ÿ8®MÎÿÚ£;™Ów³Ä›Ty×#½!ƒ¸fà7+À PÐ+p0ì¾0|á“ÉÓ:äÒÓ›åÐýª¥ ›'m›¿Óê7«ÒJaBñ:‡ÃÓzÎM#ˆ–âO&>³U&à3voÆlU“ ç©=˜èNæ°¼úV bmòx8Is­Ë2H€‹·6LÀÂ~ôa+q+<õÆzŒ$Üšæáʺ2€…ßÊ>ÈeHØ©AN×'÷q#`ž=(·Ž€YìSÈ7›@þ~Ù*i­I4ñ"X·Ë¯u‚[^Äp¡2§É„Á»7q<‚:d]RŒ"¯øú%Îô·}‡ b½½y"`׿YºõW*¯ƒ¬?l}Ê›~Ù *Ñaý!*é&ŸnéóÞ¾ü®±ùöàpð#Èúë||Ê›^Ù *Ñaý!àGõ‡­Oy3@àÿjŒ×-‡ç/IEND®B`‚bn.js-5.2.0/package.json000066400000000000000000000014711401525734400150260ustar00rootroot00000000000000{ "name": "bn.js", "version": "5.2.0", "description": "Big number implementation in pure javascript", "keywords": [ "BN", "Big number", "BigNum", "Modulo", "Montgomery" ], "homepage": "https://github.com/indutny/bn.js", "bugs": { "url": "https://github.com/indutny/bn.js/issues" }, "repository": { "type": "git", "url": "git@github.com:indutny/bn.js" }, "license": "MIT", "author": "Fedor Indutny ", "files": [ "lib/bn.js" ], "main": "lib/bn.js", "browser": { "buffer": false }, "scripts": { "lint": "standardx", "test": "npm run lint && npm run unit", "unit": "mocha --reporter=spec test/*-test.js" }, "devDependencies": { "eslint-plugin-es5": "^1.5.0", "mocha": "^8.3.0", "standardx": "^7.0.0" } } bn.js-5.2.0/test/000077500000000000000000000000001401525734400135145ustar00rootroot00000000000000bn.js-5.2.0/test/arithmetic-test.js000066400000000000000000000533731401525734400171730ustar00rootroot00000000000000/* global describe, it */ var assert = require('assert').strict; var BN = require('../').BN; var fixtures = require('./fixtures'); describe('BN.js/Arithmetic', function () { describe('.add()', function () { it('should add numbers', function () { assert.equal(new BN(14).add(new BN(26)).toString(16), '28'); var k = new BN(0x1234); var r = k; for (var i = 0; i < 257; i++) { r = r.add(k); } assert.equal(r.toString(16), '125868'); }); it('should handle carry properly (in-place)', function () { var k = new BN('abcdefabcdefabcdef', 16); var r = new BN('deadbeef', 16); for (var i = 0; i < 257; i++) { r.iadd(k); } assert.equal(r.toString(16), 'ac79bd9b79be7a277bde'); }); it('should properly do positive + negative', function () { var a = new BN('abcd', 16); var b = new BN('-abce', 16); assert.equal(a.iadd(b).toString(16), '-1'); a = new BN('abcd', 16); b = new BN('-abce', 16); assert.equal(a.add(b).toString(16), '-1'); assert.equal(b.add(a).toString(16), '-1'); }); }); describe('.iaddn()', function () { it('should allow a sign change', function () { var a = new BN(-100); assert.equal(a.negative, 1); a.iaddn(200); assert.equal(a.negative, 0); assert.equal(a.toString(), '100'); }); it('should add negative number', function () { var a = new BN(-100); assert.equal(a.negative, 1); a.iaddn(-200); assert.equal(a.toString(), '-300'); }); it('should allow neg + pos with big number', function () { var a = new BN('-1000000000', 10); assert.equal(a.negative, 1); a.iaddn(200); assert.equal(a.toString(), '-999999800'); }); it('should carry limb', function () { var a = new BN('3ffffff', 16); assert.equal(a.iaddn(1).toString(16), '4000000'); }); it('should throw error with num eq 0x4000000', function () { assert.throws(function () { new BN(0).iaddn(0x4000000); }, /^Error: Assertion failed$/); }); it('should reset sign if value equal to value in instance', function () { var a = new BN(-1); assert.equal(a.addn(1).toString(), '0'); }); }); describe('.sub()', function () { it('should subtract small numbers', function () { assert.equal(new BN(26).sub(new BN(14)).toString(16), 'c'); assert.equal(new BN(14).sub(new BN(26)).toString(16), '-c'); assert.equal(new BN(26).sub(new BN(26)).toString(16), '0'); assert.equal(new BN(-26).sub(new BN(26)).toString(16), '-34'); }); var a = new BN( '31ff3c61db2db84b9823d320907a573f6ad37c437abe458b1802cda041d6384' + 'a7d8daef41395491e2', 16); var b = new BN( '6f0e4d9f1d6071c183677f601af9305721c91d31b0bbbae8fb790000', 16); var r = new BN( '31ff3c61db2db84b9823d3208989726578fd75276287cd9516533a9acfb9a67' + '76281f34583ddb91e2', 16); it('should subtract big numbers', function () { assert.equal(a.sub(b).cmp(r), 0); }); it('should subtract numbers in place', function () { assert.equal(b.clone().isub(a).neg().cmp(r), 0); }); it('should subtract with carry', function () { // Carry and copy var a = new BN('12345', 16); var b = new BN('1000000000000', 16); assert.equal(a.isub(b).toString(16), '-fffffffedcbb'); a = new BN('12345', 16); b = new BN('1000000000000', 16); assert.equal(b.isub(a).toString(16), 'fffffffedcbb'); }); }); describe('.isubn()', function () { it('should subtract negative number', function () { var r = new BN( '7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b', 16); assert.equal(r.isubn(-1).toString(16), '7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681c'); }); it('should work for positive numbers', function () { var a = new BN(-100); assert.equal(a.negative, 1); a.isubn(200); assert.equal(a.negative, 1); assert.equal(a.toString(), '-300'); }); it('should not allow a sign change', function () { var a = new BN(-100); assert.equal(a.negative, 1); a.isubn(-200); assert.equal(a.negative, 0); assert.equal(a.toString(), '100'); }); it('should change sign on small numbers at 0', function () { var a = new BN(0).subn(2); assert.equal(a.toString(), '-2'); }); it('should change sign on small numbers at 1', function () { var a = new BN(1).subn(2); assert.equal(a.toString(), '-1'); }); it('should throw error with num eq 0x4000000', function () { assert.throws(function () { new BN(0).isubn(0x4000000); }, /^Error: Assertion failed$/); }); }); function testMethod (name, mul) { describe(name, function () { it('should multiply numbers of different signs', function () { var offsets = [ 1, // smallMulTo 250, // comb10MulTo 1000, // bigMulTo 15000 // jumboMulTo ]; for (var i = 0; i < offsets.length; ++i) { var x = new BN(1).ishln(offsets[i]); assert.equal(mul(x, x).isNeg(), false); assert.equal(mul(x, x.neg()).isNeg(), true); assert.equal(mul(x.neg(), x).isNeg(), true); assert.equal(mul(x.neg(), x.neg()).isNeg(), false); } }); it('should multiply with carry', function () { var n = new BN(0x1001); var r = n; for (var i = 0; i < 4; i++) { r = mul(r, n); } assert.equal(r.toString(16), '100500a00a005001'); }); it('should correctly multiply big numbers', function () { var n = new BN( '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', 16 ); assert.equal( mul(n, n).toString(16), '39e58a8055b6fb264b75ec8c646509784204ac15a8c24e05babc9729ab9' + 'b055c3a9458e4ce3289560a38e08ba8175a9446ce14e608245ab3a9' + '978a8bd8acaa40'); assert.equal( mul(mul(n, n), n).toString(16), '1b888e01a06e974017a28a5b4da436169761c9730b7aeedf75fc60f687b' + '46e0cf2cb11667f795d5569482640fe5f628939467a01a612b02350' + '0d0161e9730279a7561043af6197798e41b7432458463e64fa81158' + '907322dc330562697d0d600'); }); it('should multiply neg number on 0', function () { assert.equal( mul(new BN('-100000000000'), new BN('3').div(new BN('4'))) .toString(16), '0' ); }); it('should regress mul big numbers', function () { var q = fixtures.dhGroups.p17.q; var qs = fixtures.dhGroups.p17.qs; q = new BN(q, 16); assert.equal(mul(q, q).toString(16), qs); }); }); } testMethod('.mul()', function (x, y) { return BN.prototype.mul.apply(x, [y]); }); testMethod('.mulf()', function (x, y) { return BN.prototype.mulf.apply(x, [y]); }); describe('.imul()', function () { it('should multiply numbers in-place', function () { var a = new BN('abcdef01234567890abcd', 16); var b = new BN('deadbeefa551edebabba8', 16); var c = a.mul(b); assert.equal(a.imul(b).toString(16), c.toString(16)); a = new BN('abcdef01234567890abcd214a25123f512361e6d236', 16); b = new BN('deadbeefa551edebabba8121234fd21bac0341324dd', 16); c = a.mul(b); assert.equal(a.imul(b).toString(16), c.toString(16)); }); it('should multiply by 0', function () { var a = new BN('abcdef01234567890abcd', 16); var b = new BN('0', 16); var c = a.mul(b); assert.equal(a.imul(b).toString(16), c.toString(16)); }); it('should regress mul big numbers in-place', function () { var q = fixtures.dhGroups.p17.q; var qs = fixtures.dhGroups.p17.qs; q = new BN(q, 16); assert.equal(q.isqr().toString(16), qs); }); }); describe('.muln()', function () { it('should multiply number by small number', function () { var a = new BN('abcdef01234567890abcd', 16); var b = new BN('dead', 16); var c = a.mul(b); assert.equal(a.muln(0xdead).toString(16), c.toString(16)); }); it('should throw error with num eq 0x4000000', function () { assert.throws(function () { new BN(0).imuln(0x4000000); }, /^Error: Assertion failed$/); }); it('should negate number if number is negative', function () { var a = new BN('dead', 16); assert.equal(a.clone().imuln(-1).toString(16), a.clone().neg().toString(16)); assert.equal(a.clone().muln(-1).toString(16), a.clone().neg().toString(16)); var b = new BN('dead', 16); assert.equal(b.clone().imuln(-42).toString(16), b.clone().neg().muln(42).toString(16)); assert.equal(b.clone().muln(-42).toString(16), b.clone().neg().muln(42).toString(16)); }); }); describe('.pow()', function () { it('should raise number to the power', function () { var a = new BN('ab', 16); var b = new BN('13', 10); var c = a.pow(b); assert.equal(c.toString(16), '15963da06977df51909c9ba5b'); }); }); describe('.div()', function () { it('should divide small numbers (<=26 bits)', function () { assert.equal(new BN('256').div(new BN(10)).toString(10), '25'); assert.equal(new BN('-256').div(new BN(10)).toString(10), '-25'); assert.equal(new BN('256').div(new BN(-10)).toString(10), '-25'); assert.equal(new BN('-256').div(new BN(-10)).toString(10), '25'); assert.equal(new BN('10').div(new BN(256)).toString(10), '0'); assert.equal(new BN('-10').div(new BN(256)).toString(10), '0'); assert.equal(new BN('10').div(new BN(-256)).toString(10), '0'); assert.equal(new BN('-10').div(new BN(-256)).toString(10), '0'); }); it('should divide large numbers (>53 bits)', function () { assert.equal(new BN('1222222225255589').div(new BN('611111124969028')) .toString(10), '1'); assert.equal(new BN('-1222222225255589').div(new BN('611111124969028')) .toString(10), '-1'); assert.equal(new BN('1222222225255589').div(new BN('-611111124969028')) .toString(10), '-1'); assert.equal(new BN('-1222222225255589').div(new BN('-611111124969028')) .toString(10), '1'); assert.equal(new BN('611111124969028').div(new BN('1222222225255589')) .toString(10), '0'); assert.equal(new BN('-611111124969028').div(new BN('1222222225255589')) .toString(10), '0'); assert.equal(new BN('611111124969028').div(new BN('-1222222225255589')) .toString(10), '0'); assert.equal(new BN('-611111124969028').div(new BN('-1222222225255589')) .toString(10), '0'); }); it('should divide numbers', function () { assert.equal(new BN('69527932928').div(new BN('16974594')).toString(16), 'fff'); assert.equal(new BN('-69527932928').div(new BN('16974594')).toString(16), '-fff'); var b = new BN( '39e58a8055b6fb264b75ec8c646509784204ac15a8c24e05babc9729ab9' + 'b055c3a9458e4ce3289560a38e08ba8175a9446ce14e608245ab3a9' + '978a8bd8acaa40', 16); var n = new BN( '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', 16 ); assert.equal(b.div(n).toString(16), n.toString(16)); assert.equal(new BN('1').div(new BN('-5')).toString(10), '0'); }); it('should not fail on regression after moving to _wordDiv', function () { // Regression after moving to word div var p = new BN( 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', 16); var a = new BN( '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', 16); var as = a.sqr(); assert.equal( as.div(p).toString(16), '39e58a8055b6fb264b75ec8c646509784204ac15a8c24e05babc9729e58090b9'); p = new BN( 'ffffffff00000001000000000000000000000000ffffffffffffffffffffffff', 16); a = new BN( 'fffffffe00000003fffffffd0000000200000001fffffffe00000002ffffffff' + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16); assert.equal( a.div(p).toString(16), 'ffffffff00000002000000000000000000000001000000000000000000000001'); }); }); describe('.idivn()', function () { it('should divide numbers in-place', function () { assert.equal(new BN('10', 16).idivn(3).toString(16), '5'); assert.equal(new BN('10', 16).idivn(-3).toString(16), '-5'); assert.equal(new BN('12', 16).idivn(3).toString(16), '6'); assert.equal(new BN('10000000000000000').idivn(3).toString(10), '3333333333333333'); assert.equal( new BN('100000000000000000000000000000').idivn(3).toString(10), '33333333333333333333333333333'); var t = new BN(3); assert.equal( new BN('12345678901234567890123456', 16).idivn(3).toString(16), new BN('12345678901234567890123456', 16).div(t).toString(16)); }); }); describe('.divRound()', function () { it('should divide numbers with rounding', function () { assert.equal(new BN(9).divRound(new BN(20)).toString(10), '0'); assert.equal(new BN(10).divRound(new BN(20)).toString(10), '1'); assert.equal(new BN(150).divRound(new BN(20)).toString(10), '8'); assert.equal(new BN(149).divRound(new BN(20)).toString(10), '7'); assert.equal(new BN(149).divRound(new BN(17)).toString(10), '9'); assert.equal(new BN(144).divRound(new BN(17)).toString(10), '8'); assert.equal(new BN(-144).divRound(new BN(17)).toString(10), '-8'); }); it('should return 1 on exact division', function () { assert.equal(new BN(144).divRound(new BN(144)).toString(10), '1'); }); }); describe('.mod()', function () { it('should modulo small numbers (<=26 bits)', function () { assert.equal(new BN('256').mod(new BN(10)).toString(10), '6'); assert.equal(new BN('-256').mod(new BN(10)).toString(10), '-6'); assert.equal(new BN('256').mod(new BN(-10)).toString(10), '6'); assert.equal(new BN('-256').mod(new BN(-10)).toString(10), '-6'); assert.equal(new BN('10').mod(new BN(256)).toString(10), '10'); assert.equal(new BN('-10').mod(new BN(256)).toString(10), '-10'); assert.equal(new BN('10').mod(new BN(-256)).toString(10), '10'); assert.equal(new BN('-10').mod(new BN(-256)).toString(10), '-10'); }); it('should modulo large numbers (>53 bits)', function () { assert.equal(new BN('1222222225255589').mod(new BN('611111124969028')) .toString(10), '611111100286561'); assert.equal(new BN('-1222222225255589').mod(new BN('611111124969028')) .toString(10), '-611111100286561'); assert.equal(new BN('1222222225255589').mod(new BN('-611111124969028')) .toString(10), '611111100286561'); assert.equal(new BN('-1222222225255589').mod(new BN('-611111124969028')) .toString(10), '-611111100286561'); assert.equal(new BN('611111124969028').mod(new BN('1222222225255589')) .toString(10), '611111124969028'); assert.equal(new BN('-611111124969028').mod(new BN('1222222225255589')) .toString(10), '-611111124969028'); assert.equal(new BN('611111124969028').mod(new BN('-1222222225255589')) .toString(10), '611111124969028'); assert.equal(new BN('-611111124969028').mod(new BN('-1222222225255589')) .toString(10), '-611111124969028'); }); it('should mod numbers', function () { assert.equal(new BN('10').mod(new BN(256)).toString(16), 'a'); assert.equal(new BN('69527932928').mod(new BN('16974594')).toString(16), '102f302'); // 178 = 10 * 17 + 8 assert.equal(new BN(178).div(new BN(10)).toNumber(), 17); assert.equal(new BN(178).mod(new BN(10)).toNumber(), 8); assert.equal(new BN(178).umod(new BN(10)).toNumber(), 8); // -178 = 10 * (-17) + (-8) assert.equal(new BN(-178).div(new BN(10)).toNumber(), -17); assert.equal(new BN(-178).mod(new BN(10)).toNumber(), -8); assert.equal(new BN(-178).umod(new BN(10)).toNumber(), 2); // 178 = -10 * (-17) + 8 assert.equal(new BN(178).div(new BN(-10)).toNumber(), -17); assert.equal(new BN(178).mod(new BN(-10)).toNumber(), 8); assert.equal(new BN(178).umod(new BN(-10)).toNumber(), 8); // -178 = -10 * (17) + (-8) assert.equal(new BN(-178).div(new BN(-10)).toNumber(), 17); assert.equal(new BN(-178).mod(new BN(-10)).toNumber(), -8); assert.equal(new BN(-178).umod(new BN(-10)).toNumber(), 2); // -4 = 1 * (-3) + -1 assert.equal(new BN(-4).div(new BN(-3)).toNumber(), 1); assert.equal(new BN(-4).mod(new BN(-3)).toNumber(), -1); // -4 = -1 * (3) + -1 assert.equal(new BN(-4).mod(new BN(3)).toNumber(), -1); // -4 = 1 * (-3) + (-1 + 3) assert.equal(new BN(-4).umod(new BN(-3)).toNumber(), 2); var p = new BN( 'ffffffff00000001000000000000000000000000ffffffffffffffffffffffff', 16); var a = new BN( 'fffffffe00000003fffffffd0000000200000001fffffffe00000002ffffffff' + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16); assert.equal( a.mod(p).toString(16), '0'); }); it('should properly carry the sign inside division', function () { var a = new BN('945304eb96065b2a98b57a48a06ae28d285a71b5', 'hex'); var b = new BN( 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe', 'hex'); assert.equal(a.mul(b).mod(a).cmpn(0), 0); }); }); describe('.modrn()', function () { it('should act like .mod() on small numbers', function () { assert.equal(new BN('10', 16).modrn(256).toString(16), '10'); assert.equal(new BN('10', 16).modrn(-256).toString(16), '-10'); assert.equal(new BN('100', 16).modrn(256).toString(16), '0'); assert.equal(new BN('1001', 16).modrn(256).toString(16), '1'); assert.equal(new BN('100000000001', 16).modrn(256).toString(16), '1'); assert.equal(new BN('100000000001', 16).modrn(257).toString(16), new BN('100000000001', 16).mod(new BN(257)).toString(16)); assert.equal(new BN('123456789012', 16).modrn(3).toString(16), new BN('123456789012', 16).mod(new BN(3)).toString(16)); }); }); describe('.abs()', function () { it('should return absolute value', function () { assert.equal(new BN(0x1001).abs().toString(), '4097'); assert.equal(new BN(-0x1001).abs().toString(), '4097'); assert.equal(new BN('ffffffff', 16).abs().toString(), '4294967295'); }); }); describe('.invm()', function () { it('should invert relatively-prime numbers', function () { var p = new BN(257); var a = new BN(3); var b = a.invm(p); assert.equal(a.mul(b).mod(p).toString(16), '1'); var p192 = new BN( 'fffffffffffffffffffffffffffffffeffffffffffffffff', 16); a = new BN('deadbeef', 16); b = a.invm(p192); assert.equal(a.mul(b).mod(p192).toString(16), '1'); // Even base var phi = new BN('872d9b030ba368706b68932cf07a0e0c', 16); var e = new BN(65537); var d = e.invm(phi); assert.equal(e.mul(d).mod(phi).toString(16), '1'); // Even base (take #2) a = new BN('5'); b = new BN('6'); var r = a.invm(b); assert.equal(r.mul(a).mod(b).toString(16), '1'); }); }); describe('.gcd()', function () { it('should return GCD', function () { assert.equal(new BN(3).gcd(new BN(2)).toString(10), '1'); assert.equal(new BN(18).gcd(new BN(12)).toString(10), '6'); assert.equal(new BN(-18).gcd(new BN(12)).toString(10), '6'); assert.equal(new BN(-18).gcd(new BN(-12)).toString(10), '6'); assert.equal(new BN(-18).gcd(new BN(0)).toString(10), '18'); assert.equal(new BN(0).gcd(new BN(-18)).toString(10), '18'); assert.equal(new BN(2).gcd(new BN(0)).toString(10), '2'); assert.equal(new BN(0).gcd(new BN(3)).toString(10), '3'); assert.equal(new BN(0).gcd(new BN(0)).toString(10), '0'); }); }); describe('.egcd()', function () { it('should return EGCD', function () { assert.equal(new BN(3).egcd(new BN(2)).gcd.toString(10), '1'); assert.equal(new BN(18).egcd(new BN(12)).gcd.toString(10), '6'); assert.equal(new BN(-18).egcd(new BN(12)).gcd.toString(10), '6'); assert.equal(new BN(0).egcd(new BN(12)).gcd.toString(10), '12'); }); it('should not allow 0 input', function () { assert.throws(function () { new BN(1).egcd(0); }, /^Error: Assertion failed$/); }); it('should not allow negative input', function () { assert.throws(function () { new BN(1).egcd(-1); }, /^Error: Assertion failed$/); }); }); describe('BN.max(a, b)', function () { it('should return maximum', function () { assert.equal(BN.max(new BN(3), new BN(2)).toString(16), '3'); assert.equal(BN.max(new BN(2), new BN(3)).toString(16), '3'); assert.equal(BN.max(new BN(2), new BN(2)).toString(16), '2'); assert.equal(BN.max(new BN(2), new BN(-2)).toString(16), '2'); }); }); describe('BN.min(a, b)', function () { it('should return minimum', function () { assert.equal(BN.min(new BN(3), new BN(2)).toString(16), '2'); assert.equal(BN.min(new BN(2), new BN(3)).toString(16), '2'); assert.equal(BN.min(new BN(2), new BN(2)).toString(16), '2'); assert.equal(BN.min(new BN(2), new BN(-2)).toString(16), '-2'); }); }); describe('BN.ineg', function () { it('shouldn\'t change sign for zero', function () { assert.equal(new BN(0).ineg().toString(10), '0'); }); }); }); bn.js-5.2.0/test/binary-test.js000066400000000000000000000203561401525734400163210ustar00rootroot00000000000000/* global describe, it */ var assert = require('assert').strict; var BN = require('../').BN; describe('BN.js/Binary', function () { describe('.shl()', function () { it('should shl numbers', function () { // TODO(indutny): add negative numbers when the time will come assert.equal(new BN('69527932928').shln(13).toString(16), '2060602000000'); assert.equal(new BN('69527932928').shln(45).toString(16), '206060200000000000000'); }); it('should ushl numbers', function () { assert.equal(new BN('69527932928').ushln(13).toString(16), '2060602000000'); assert.equal(new BN('69527932928').ushln(45).toString(16), '206060200000000000000'); }); }); describe('.shr()', function () { it('should shr numbers', function () { // TODO(indutny): add negative numbers when the time will come assert.equal(new BN('69527932928').shrn(13).toString(16), '818180'); assert.equal(new BN('69527932928').shrn(17).toString(16), '81818'); assert.equal(new BN('69527932928').shrn(256).toString(16), '0'); }); it('should ushr numbers', function () { assert.equal(new BN('69527932928').ushrn(13).toString(16), '818180'); assert.equal(new BN('69527932928').ushrn(17).toString(16), '81818'); assert.equal(new BN('69527932928').ushrn(256).toString(16), '0'); }); }); describe('.bincn()', function () { it('should increment bit', function () { assert.equal(new BN(0).bincn(1).toString(16), '2'); assert.equal(new BN(2).bincn(1).toString(16), '4'); assert.equal(new BN(2).bincn(1).bincn(1).toString(16), new BN(2).bincn(2).toString(16)); assert.equal(new BN(0xffffff).bincn(1).toString(16), '1000001'); assert.equal(new BN(2).bincn(63).toString(16), '8000000000000002'); }); }); describe('.imaskn()', function () { it('should mask bits in-place', function () { assert.equal(new BN(0).imaskn(1).toString(16), '0'); assert.equal(new BN(3).imaskn(1).toString(16), '1'); assert.equal(new BN('123456789', 16).imaskn(4).toString(16), '9'); assert.equal(new BN('123456789', 16).imaskn(16).toString(16), '6789'); assert.equal(new BN('123456789', 16).imaskn(28).toString(16), '3456789'); }); it('should not mask when number is bigger than length', function () { assert.equal(new BN(0xe3).imaskn(56).toString(16), 'e3'); assert.equal(new BN(0xe3).imaskn(26).toString(16), 'e3'); }); }); describe('.testn()', function () { it('should support test specific bit', function () { [ 'ff', 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' ].forEach(function (hex) { var bn = new BN(hex, 16); var bl = bn.bitLength(); for (var i = 0; i < bl; ++i) { assert.equal(bn.testn(i), true); } // test off the end assert.equal(bn.testn(bl), false); }); var xbits = '01111001010111001001000100011101' + '11010011101100011000111001011101' + '10010100111000000001011000111101' + '01011111001111100100011110000010' + '01011010100111010001010011000100' + '01101001011110100001001111100110' + '001110010111'; var x = new BN( '23478905234580795234378912401239784125643978256123048348957342' ); for (var i = 0; i < x.bitLength(); ++i) { assert.equal(x.testn(i), (xbits.charAt(i) === '1'), 'Failed @ bit ' + i); } }); it('should have short-cuts', function () { var x = new BN('abcd', 16); assert(!x.testn(128)); }); }); describe('.and()', function () { it('should and numbers', function () { assert.equal(new BN('1010101010101010101010101010101010101010', 2) .and(new BN('101010101010101010101010101010101010101', 2)) .toString(2), '0'); }); it('should and numbers of different limb-length', function () { assert.equal( new BN('abcd0000ffff', 16) .and(new BN('abcd', 16)).toString(16), 'abcd'); }); }); describe('.iand()', function () { it('should iand numbers', function () { assert.equal(new BN('1010101010101010101010101010101010101010', 2) .iand(new BN('101010101010101010101010101010101010101', 2)) .toString(2), '0'); assert.equal(new BN('1000000000000000000000000000000000000001', 2) .iand(new BN('1', 2)) .toString(2), '1'); assert.equal(new BN('1', 2) .iand(new BN('1000000000000000000000000000000000000001', 2)) .toString(2), '1'); }); }); describe('.or()', function () { it('should or numbers', function () { assert.equal(new BN('1010101010101010101010101010101010101010', 2) .or(new BN('101010101010101010101010101010101010101', 2)) .toString(2), '1111111111111111111111111111111111111111'); }); it('should or numbers of different limb-length', function () { assert.equal( new BN('abcd00000000', 16) .or(new BN('abcd', 16)).toString(16), 'abcd0000abcd'); }); }); describe('.ior()', function () { it('should ior numbers', function () { assert.equal(new BN('1010101010101010101010101010101010101010', 2) .ior(new BN('101010101010101010101010101010101010101', 2)) .toString(2), '1111111111111111111111111111111111111111'); assert.equal(new BN('1000000000000000000000000000000000000000', 2) .ior(new BN('1', 2)) .toString(2), '1000000000000000000000000000000000000001'); assert.equal(new BN('1', 2) .ior(new BN('1000000000000000000000000000000000000000', 2)) .toString(2), '1000000000000000000000000000000000000001'); }); }); describe('.xor()', function () { it('should xor numbers', function () { assert.equal(new BN('11001100110011001100110011001100', 2) .xor(new BN('1100110011001100110011001100110', 2)) .toString(2), '10101010101010101010101010101010'); }); }); describe('.ixor()', function () { it('should ixor numbers', function () { assert.equal(new BN('11001100110011001100110011001100', 2) .ixor(new BN('1100110011001100110011001100110', 2)) .toString(2), '10101010101010101010101010101010'); assert.equal(new BN('11001100110011001100110011001100', 2) .ixor(new BN('1', 2)) .toString(2), '11001100110011001100110011001101'); assert.equal(new BN('1', 2) .ixor(new BN('11001100110011001100110011001100', 2)) .toString(2), '11001100110011001100110011001101'); }); it('should and numbers of different limb-length', function () { assert.equal( new BN('abcd0000ffff', 16) .xor(new BN('abcd', 16)).toString(16), 'abcd00005432'); }); }); describe('.setn()', function () { it('should allow single bits to be set', function () { assert.equal(new BN(0).setn(2, true).toString(2), '100'); assert.equal(new BN(0).setn(27, true).toString(2), '1000000000000000000000000000'); assert.equal(new BN(0).setn(63, true).toString(16), new BN(1).iushln(63).toString(16)); assert.equal(new BN('1000000000000000000000000001', 2).setn(27, false) .toString(2), '1'); assert.equal(new BN('101', 2).setn(2, false).toString(2), '1'); }); }); describe('.notn()', function () { it('should allow bitwise negation', function () { assert.equal(new BN('111000111', 2).notn(9).toString(2), '111000'); assert.equal(new BN('000111000', 2).notn(9).toString(2), '111000111'); assert.equal(new BN('111000111', 2).notn(9).toString(2), '111000'); assert.equal(new BN('000111000', 2).notn(9).toString(2), '111000111'); assert.equal(new BN('111000111', 2).notn(32).toString(2), '11111111111111111111111000111000'); assert.equal(new BN('000111000', 2).notn(32).toString(2), '11111111111111111111111111000111'); assert.equal(new BN('111000111', 2).notn(68).toString(2), '11111111111111111111111111111111' + '111111111111111111111111111000111000'); assert.equal(new BN('000111000', 2).notn(68).toString(2), '11111111111111111111111111111111' + '111111111111111111111111111111000111'); }); }); }); bn.js-5.2.0/test/constructor-test.js000066400000000000000000000146761401525734400174320ustar00rootroot00000000000000/* global describe, it */ var assert = require('assert').strict; var BN = require('../').BN; describe('BN.js/Constructor', function () { describe('with Smi input', function () { it('should accept one limb number', function () { assert.equal(new BN(12345).toString(16), '3039'); }); it('should accept two-limb number', function () { assert.equal(new BN(0x4123456).toString(16), '4123456'); }); it('should accept 52 bits of precision', function () { var num = Math.pow(2, 52); assert.equal(new BN(num, 10).toString(10), num.toString(10)); }); it('should accept max safe integer', function () { var num = Math.pow(2, 53) - 1; assert.equal(new BN(num, 10).toString(10), num.toString(10)); }); it('should not accept an unsafe integer', function () { var num = Math.pow(2, 53); assert.throws(function () { return new BN(num, 10); }, /^Error: Assertion failed$/); }); it('should accept two-limb LE number', function () { assert.equal(new BN(0x4123456, null, 'le').toString(16), '56341204'); }); }); describe('with String input', function () { it('should accept base-16', function () { assert.equal(new BN('1A6B765D8CDF', 16).toString(16), '1a6b765d8cdf'); assert.equal(new BN('1A6B765D8CDF', 16).toString(), '29048849665247'); }); it('should accept base-hex', function () { assert.equal(new BN('FF', 'hex').toString(), '255'); }); it('should accept base-16 with spaces', function () { var num = 'a89c e5af8724 c0a23e0e 0ff77500'; assert.equal(new BN(num, 16).toString(16), num.replace(/ /g, '')); }); it('should accept long base-16', function () { var num = '123456789abcdef123456789abcdef123456789abcdef'; assert.equal(new BN(num, 16).toString(16), num); }); it('should accept positive base-10', function () { assert.equal(new BN('10654321').toString(), '10654321'); assert.equal(new BN('29048849665247').toString(16), '1a6b765d8cdf'); }); it('should accept negative base-10', function () { assert.equal(new BN('-29048849665247').toString(16), '-1a6b765d8cdf'); }); it('should accept long base-10', function () { var num = '10000000000000000'; assert.equal(new BN(num).toString(10), num); }); it('should accept base-2', function () { var base2 = '11111111111111111111111111111111111111111111111111111'; assert.equal(new BN(base2, 2).toString(2), base2); }); it('should accept base-36', function () { var base36 = 'zzZzzzZzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'; assert.equal(new BN(base36, 36).toString(36), base36.toLowerCase()); }); it('should not overflow limbs during base-10', function () { var num = '65820182292848241686198767302293' + '20890292528855852623664389292032'; assert(new BN(num).words[0] < 0x4000000); }); it('should accept base-16 LE integer', function () { assert.equal(new BN('1A6B765D8CDF', 16, 'le').toString(16), 'df8c5d766b1a'); }); it('should accept base-16 LE integer with leading zeros', function () { assert.equal(new BN('0010', 16, 'le').toNumber(), 4096); assert.equal(new BN('-010', 16, 'le').toNumber(), -4096); assert.equal(new BN('010', 16, 'le').toNumber(), 4096); }); it('should not accept wrong characters for base', function () { assert.throws(function () { return new BN('01FF'); }, /^Error: Invalid character$/); }); it('should not accept decimal', function () { assert.throws(function () { new BN('10.00', 10); // eslint-disable-line no-new }, /Invalid character/); assert.throws(function () { new BN('16.00', 16); // eslint-disable-line no-new }, /Invalid character/); }); it('should not accept non-hex characters', function () { [ '0000000z', '000000gg', '0000gg00', 'fffggfff', '/0000000', '0-000000', // if -, is first, that is OK 'ff.fffff', 'hexadecimal' ].forEach(function (str) { assert.throws(function () { new BN(str, 16); // eslint-disable-line no-new }, /Invalid character in /); }); }); }); describe('with Array input', function () { it('should not fail on empty array', function () { assert.equal(new BN([]).toString(16), '0'); }); it('should import/export big endian', function () { assert.equal(new BN([0, 1], 16).toString(16), '1'); assert.equal(new BN([1, 2, 3]).toString(16), '10203'); assert.equal(new BN([1, 2, 3, 4]).toString(16), '1020304'); assert.equal(new BN([1, 2, 3, 4, 5]).toString(16), '102030405'); assert.equal(new BN([1, 2, 3, 4, 5, 6, 7, 8]).toString(16), '102030405060708'); assert.equal(new BN([1, 2, 3, 4]).toArray().join(','), '1,2,3,4'); assert.equal(new BN([1, 2, 3, 4, 5, 6, 7, 8]).toArray().join(','), '1,2,3,4,5,6,7,8'); }); it('should import little endian', function () { assert.equal(new BN([0, 1], 16, 'le').toString(16), '100'); assert.equal(new BN([1, 2, 3], 16, 'le').toString(16), '30201'); assert.equal(new BN([1, 2, 3, 4], 16, 'le').toString(16), '4030201'); assert.equal(new BN([1, 2, 3, 4, 5], 16, 'le').toString(16), '504030201'); assert.equal(new BN([1, 2, 3, 4, 5, 6, 7, 8], 'le').toString(16), '807060504030201'); assert.equal(new BN([1, 2, 3, 4]).toArray('le').join(','), '4,3,2,1'); assert.equal(new BN([1, 2, 3, 4, 5, 6, 7, 8]).toArray('le').join(','), '8,7,6,5,4,3,2,1'); }); it('should import big endian with implicit base', function () { assert.equal(new BN([1, 2, 3, 4, 5], 'le').toString(16), '504030201'); }); }); // the Array code is able to handle Buffer describe('with Buffer input', function () { it('should not fail on empty Buffer', function () { assert.equal(new BN(Buffer.alloc(0)).toString(16), '0'); }); it('should import/export big endian', function () { assert.equal(new BN(Buffer.from('010203', 'hex')).toString(16), '10203'); }); it('should import little endian', function () { assert.equal(new BN(Buffer.from('010203', 'hex'), 'le').toString(16), '30201'); }); }); describe('with BN input', function () { it('should clone BN', function () { var num = new BN(12345); assert.equal(new BN(num).toString(10), '12345'); }); }); }); bn.js-5.2.0/test/fixtures.js000066400000000000000000000355321401525734400157330ustar00rootroot00000000000000exports.dhGroups = { p16: { prime: 'ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd1' + '29024e088a67cc74020bbea63b139b22514a08798e3404dd' + 'ef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245' + 'e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed' + 'ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3d' + 'c2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f' + '83655d23dca3ad961c62f356208552bb9ed529077096966d' + '670c354e4abc9804f1746c08ca18217c32905e462e36ce3b' + 'e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9' + 'de2bcbf6955817183995497cea956ae515d2261898fa0510' + '15728e5a8aaac42dad33170d04507a33a85521abdf1cba64' + 'ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7' + 'abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6b' + 'f12ffa06d98a0864d87602733ec86a64521f2b18177b200c' + 'bbe117577a615d6c770988c0bad946e208e24fa074e5ab31' + '43db5bfce0fd108e4b82d120a92108011a723c12a787e6d7' + '88719a10bdba5b2699c327186af4e23c1a946834b6150bda' + '2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6' + '287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed' + '1f612970cee2d7afb81bdd762170481cd0069127d5b05aa9' + '93b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199' + 'ffffffffffffffff', priv: '6d5923e6449122cbbcc1b96093e0b7e4fd3e469f58daddae' + '53b49b20664f4132675df9ce98ae0cfdcac0f4181ccb643b' + '625f98104dcf6f7d8e81961e2cab4b5014895260cb977c7d' + '2f981f8532fb5da60b3676dfe57f293f05d525866053ac7e' + '65abfd19241146e92e64f309a97ef3b529af4d6189fa416c' + '9e1a816c3bdf88e5edf48fbd8233ef9038bb46faa95122c0' + '5a426be72039639cd2d53d37254b3d258960dcb33c255ede' + '20e9d7b4b123c8b4f4b986f53cdd510d042166f7dd7dca98' + '7c39ab36381ba30a5fdd027eb6128d2ef8e5802a2194d422' + 'b05fe6e1cb4817789b923d8636c1ec4b7601c90da3ddc178' + '52f59217ae070d87f2e75cbfb6ff92430ad26a71c8373452' + 'ae1cc5c93350e2d7b87e0acfeba401aaf518580937bf0b6c' + '341f8c49165a47e49ce50853989d07171c00f43dcddddf72' + '94fb9c3f4e1124e98ef656b797ef48974ddcd43a21fa06d0' + '565ae8ce494747ce9e0ea0166e76eb45279e5c6471db7df8' + 'cc88764be29666de9c545e72da36da2f7a352fb17bdeb982' + 'a6dc0193ec4bf00b2e533efd6cd4d46e6fb237b775615576' + 'dd6c7c7bbc087a25e6909d1ebc6e5b38e5c8472c0fc429c6' + 'f17da1838cbcd9bbef57c5b5522fd6053e62ba21fe97c826' + 'd3889d0cc17e5fa00b54d8d9f0f46fb523698af965950f4b' + '941369e180f0aece3870d9335f2301db251595d173902cad' + '394eaa6ffef8be6c', pub: 'd53703b7340bc89bfc47176d351e5cf86d5a18d9662eca3c' + '9759c83b6ccda8859649a5866524d77f79e501db923416ca' + '2636243836d3e6df752defc0fb19cc386e3ae48ad647753f' + 'bf415e2612f8a9fd01efe7aca249589590c7e6a0332630bb' + '29c5b3501265d720213790556f0f1d114a9e2071be3620bd' + '4ee1e8bb96689ac9e226f0a4203025f0267adc273a43582b' + '00b70b490343529eaec4dcff140773cd6654658517f51193' + '13f21f0a8e04fe7d7b21ffeca85ff8f87c42bb8d9cb13a72' + 'c00e9c6e9dfcedda0777af951cc8ccab90d35e915e707d8e' + '4c2aca219547dd78e9a1a0730accdc9ad0b854e51edd1e91' + '4756760bab156ca6e3cb9c625cf0870def34e9ac2e552800' + 'd6ce506d43dbbc75acfa0c8d8fb12daa3c783fb726f187d5' + '58131779239c912d389d0511e0f3a81969d12aeee670e48f' + 'ba41f7ed9f10705543689c2506b976a8ffabed45e33795b0' + '1df4f6b993a33d1deab1316a67419afa31fbb6fdd252ee8c' + '7c7d1d016c44e3fcf6b41898d7f206aa33760b505e4eff2e' + 'c624bc7fe636b1d59e45d6f904fc391419f13d1f0cdb5b6c' + '2378b09434159917dde709f8a6b5dc30994d056e3f964371' + '11587ac7af0a442b8367a7bd940f752ddabf31cf01171e24' + 'd78df136e9681cd974ce4f858a5fb6efd3234a91857bb52d' + '9e7b414a8bc66db4b5a73bbeccfb6eb764b4f0cbf0375136' + 'b024b04e698d54a5' }, p17: { prime: 'ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd1' + '29024e088a67cc74020bbea63b139b22514a08798e3404dd' + 'ef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245' + 'e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed' + 'ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3d' + 'c2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f' + '83655d23dca3ad961c62f356208552bb9ed529077096966d' + '670c354e4abc9804f1746c08ca18217c32905e462e36ce3b' + 'e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9' + 'de2bcbf6955817183995497cea956ae515d2261898fa0510' + '15728e5a8aaac42dad33170d04507a33a85521abdf1cba64' + 'ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7' + 'abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6b' + 'f12ffa06d98a0864d87602733ec86a64521f2b18177b200c' + 'bbe117577a615d6c770988c0bad946e208e24fa074e5ab31' + '43db5bfce0fd108e4b82d120a92108011a723c12a787e6d7' + '88719a10bdba5b2699c327186af4e23c1a946834b6150bda' + '2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6' + '287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed' + '1f612970cee2d7afb81bdd762170481cd0069127d5b05aa9' + '93b4ea988d8fddc186ffb7dc90a6c08f4df435c934028492' + '36c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bd' + 'f8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831' + '179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1b' + 'db7f1447e6cc254b332051512bd7af426fb8f401378cd2bf' + '5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6' + 'd55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f3' + '23a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aa' + 'cc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be328' + '06a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55c' + 'da56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee' + '12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff', priv: '6017f2bc23e1caff5b0a8b4e1fc72422b5204415787801dc' + '025762b8dbb98ab57603aaaa27c4e6bdf742b4a1726b9375' + 'a8ca3cf07771779589831d8bd18ddeb79c43e7e77d433950' + 'e652e49df35b11fa09644874d71d62fdaffb580816c2c88c' + '2c4a2eefd4a660360316741b05a15a2e37f236692ad3c463' + 'fff559938fc6b77176e84e1bb47fb41af691c5eb7bb81bd8' + 'c918f52625a1128f754b08f5a1403b84667231c4dfe07ed4' + '326234c113931ce606037e960f35a2dfdec38a5f057884d3' + '0af8fab3be39c1eeb390205fd65982191fc21d5aa30ddf51' + 'a8e1c58c0c19fc4b4a7380ea9e836aaf671c90c29bc4bcc7' + '813811aa436a7a9005de9b507957c56a9caa1351b6efc620' + '7225a18f6e97f830fb6a8c4f03b82f4611e67ab9497b9271' + 'd6ac252793cc3e5538990dbd894d2dbc2d152801937d9f74' + 'da4b741b50b4d40e4c75e2ac163f7b397fd555648b249f97' + 'ffe58ffb6d096aa84534c4c5729cff137759bd34e80db4ab' + '47e2b9c52064e7f0bf677f72ac9e5d0c6606943683f9d12f' + '180cf065a5cb8ec3179a874f358847a907f8471d15f1e728' + '7023249d6d13c82da52628654438f47b8b5cdf4761fbf6ad' + '9219eceac657dbd06cf2ab776ad4c968f81c3d039367f0a4' + 'd77c7ec4435c27b6c147071665100063b5666e06eb2fb2cc' + '3159ba34bc98ca346342195f6f1fb053ddc3bc1873564d40' + '1c6738cdf764d6e1ff25ca5926f80102ea6593c17170966b' + 'b5d7352dd7fb821230237ea3ebed1f920feaadbd21be295a' + '69f2083deae9c5cdf5f4830eb04b7c1f80cc61c17232d79f' + '7ecc2cc462a7965f804001c89982734e5abba2d31df1b012' + '152c6b226dff34510b54be8c2cd68d795def66c57a3abfb6' + '896f1d139e633417f8c694764974d268f46ece3a8d6616ea' + 'a592144be48ee1e0a1595d3e5edfede5b27cec6c48ceb2ff' + 'b42cb44275851b0ebf87dfc9aa2d0cb0805e9454b051dfe8' + 'a29fadd82491a4b4c23f2d06ba45483ab59976da1433c9ce' + '500164b957a04cf62dd67595319b512fc4b998424d1164dd' + 'bbe5d1a0f7257cbb04ec9b5ed92079a1502d98725023ecb2', pub: '3bf836229c7dd874fe37c1790d201e82ed8e192ed61571ca' + '7285264974eb2a0171f3747b2fc23969a916cbd21e14f7e2' + 'f0d72dcd2247affba926f9e7bb99944cb5609aed85e71b89' + 'e89d2651550cb5bd8281bd3144066af78f194032aa777739' + 'cccb7862a1af401f99f7e5c693f25ddce2dedd9686633820' + 'd28d0f5ed0c6b5a094f5fe6170b8e2cbc9dff118398baee6' + 'e895a6301cb6e881b3cae749a5bdf5c56fc897ff68bc73f2' + '4811bb108b882872bade1f147d886a415cda2b93dd90190c' + 'be5c2dd53fe78add5960e97f58ff2506afe437f4cf4c912a' + '397c1a2139ac6207d3ab76e6b7ffd23bb6866dd7f87a9ae5' + '578789084ff2d06ea0d30156d7a10496e8ebe094f5703539' + '730f5fdbebc066de417be82c99c7da59953071f49da7878d' + 'a588775ff2a7f0084de390f009f372af75cdeba292b08ea8' + '4bd13a87e1ca678f9ad148145f7cef3620d69a891be46fbb' + 'cad858e2401ec0fd72abdea2f643e6d0197b7646fbb83220' + '0f4cf7a7f6a7559f9fb0d0f1680822af9dbd8dec4cd1b5e1' + '7bc799e902d9fe746ddf41da3b7020350d3600347398999a' + 'baf75d53e03ad2ee17de8a2032f1008c6c2e6618b62f225b' + 'a2f350179445debe68500fcbb6cae970a9920e321b468b74' + '5fb524fb88abbcacdca121d737c44d30724227a99745c209' + 'b970d1ff93bbc9f28b01b4e714d6c9cbd9ea032d4e964d8e' + '8fff01db095160c20b7646d9fcd314c4bc11bcc232aeccc0' + 'fbedccbc786951025597522eef283e3f56b44561a0765783' + '420128638c257e54b972a76e4261892d81222b3e2039c61a' + 'ab8408fcaac3d634f848ab3ee65ea1bd13c6cd75d2e78060' + 'e13cf67fbef8de66d2049e26c0541c679fff3e6afc290efe' + '875c213df9678e4a7ec484bc87dae5f0a1c26d7583e38941' + 'b7c68b004d4df8b004b666f9448aac1cc3ea21461f41ea5d' + 'd0f7a9e6161cfe0f58bcfd304bdc11d78c2e9d542e86c0b5' + '6985cc83f693f686eaac17411a8247bf62f5ccc7782349b5' + 'cc1f20e312fa2acc0197154d1bfee507e8db77e8f2732f2d' + '641440ccf248e8643b2bd1e1f9e8239356ab91098fcb431d', q: 'a899c59999bf877d96442d284359783bdc64b5f878b688fe' + '51407f0526e616553ad0aaaac4d5bed3046f10a1faaf42bb' + '2342dc4b7908eea0c46e4c4576897675c2bfdc4467870d3d' + 'cd90adaed4359237a4bc6924bfb99aa6bf5f5ede15b574ea' + 'e977eac096f3c67d09bda574c6306c6123fa89d2f086b8dc' + 'ff92bc570c18d83fe6c810ccfd22ce4c749ef5e6ead3fffe' + 'c63d95e0e3fde1df9db6a35fa1d107058f37e41957769199' + 'd945dd7a373622c65f0af3fd9eb1ddc5c764bbfaf7a3dc37' + '2548e683b970dac4aa4b9869080d2376c9adecebb84e172c' + '09aeeb25fb8df23e60033260c4f8aac6b8b98ab894b1fb84' + 'ebb83c0fb2081c3f3eee07f44e24d8fabf76f19ed167b0d7' + 'ff971565aa4efa3625fce5a43ceeaa3eebb3ce88a00f597f' + '048c69292b38dba2103ecdd5ec4ccfe3b2d87fa6202f334b' + 'c1cab83b608dfc875b650b69f2c7e23c0b2b4adf149a6100' + 'db1b6dbad4679ecb1ea95eafaba3bd00db11c2134f5a8686' + '358b8b2ab49a1b2e85e1e45caeac5cd4dc0b3b5fffba8871' + '1c6baf399edd48dad5e5c313702737a6dbdcede80ca358e5' + '1d1c4fe42e8948a084403f61baed38aa9a1a5ce2918e9f33' + '100050a430b47bc592995606440272a4994677577a6aaa1b' + 'a101045dbec5a4e9566dab5445d1af3ed19519f07ac4e2a8' + 'bd0a84b01978f203a9125a0be020f71fab56c2c9e344d4f4' + '12d53d3cd8eb74ca5122002e931e3cb0bd4b7492436be17a' + 'd7ebe27148671f59432c36d8c56eb762655711cfc8471f70' + '83a8b7283bcb3b1b1d47d37c23d030288cfcef05fbdb4e16' + '652ee03ee7b77056a808cd700bc3d9ef826eca9a59be959c' + '947c865d6b372a1ca2d503d7df6d7611b12111665438475a' + '1c64145849b3da8c2d343410df892d958db232617f9896f1' + 'de95b8b5a47132be80dd65298c7f2047858409bf762dbc05' + 'a62ca392ac40cfb8201a0607a2cae07d99a307625f2b2d04' + 'fe83fbd3ab53602263410f143b73d5b46fc761882e78c782' + 'd2c36e716a770a7aefaf7f76cea872db7bffefdbc4c2f9e0' + '39c19adac915e7a63dcb8c8c78c113f29a3e0bc10e100ce0', qs: '6f0a2fb763eaeb8eb324d564f03d4a55fdcd709e5f1b65e9' + '5702b0141182f9f945d71bc3e64a7dfdae7482a7dd5a4e58' + 'bc38f78de2013f2c468a621f08536969d2c8d011bb3bc259' + '2124692c91140a5472cad224acdacdeae5751dadfdf068b8' + '77bfa7374694c6a7be159fc3d24ff9eeeecaf62580427ad8' + '622d48c51a1c4b1701d768c79d8c819776e096d2694107a2' + 'f3ec0c32224795b59d32894834039dacb369280afb221bc0' + '90570a93cf409889b818bb30cccee98b2aa26dbba0f28499' + '08e1a3cd43fa1f1fb71049e5c77c3724d74dc351d9989057' + '37bbda3805bd6b1293da8774410fb66e3194e18cdb304dd9' + 'a0b59b583dcbc9fc045ac9d56aea5cfc9f8a0b95da1e11b7' + '574d1f976e45fe12294997fac66ca0b83fc056183549e850' + 'a11413cc4abbe39a211e8c8cbf82f2a23266b3c10ab9e286' + '07a1b6088909cddff856e1eb6b2cde8bdac53fa939827736' + 'ca1b892f6c95899613442bd02dbdb747f02487718e2d3f22' + 'f73734d29767ed8d0e346d0c4098b6fdcb4df7d0c4d29603' + '5bffe80d6c65ae0a1b814150d349096baaf950f2caf298d2' + 'b292a1d48cf82b10734fe8cedfa16914076dfe3e9b51337b' + 'ed28ea1e6824bb717b641ca0e526e175d3e5ed7892aebab0' + 'f207562cc938a821e2956107c09b6ce4049adddcd0b7505d' + '49ae6c69a20122461102d465d93dc03db026be54c303613a' + 'b8e5ce3fd4f65d0b6162ff740a0bf5469ffd442d8c509cd2' + '3b40dab90f6776ca17fc0678774bd6eee1fa85ababa52ec1' + 'a15031eb677c6c488661dddd8b83d6031fe294489ded5f08' + '8ad1689a14baeae7e688afa3033899c81f58de39b392ca94' + 'af6f15a46f19fa95c06f9493c8b96a9be25e78b9ea35013b' + 'caa76de6303939299d07426a88a334278fc3d0d9fa71373e' + 'be51d3c1076ab93a11d3d0d703366ff8cde4c11261d488e5' + '60a2bdf3bfe2476032294800d6a4a39d306e65c6d7d8d66e' + '5ec63eee94531e83a9bddc458a2b508285c0ee10b7bd94da' + '2815a0c5bd5b2e15cbe66355e42f5af8955cdfc0b3a4996d' + '288db1f4b32b15643b18193e378cb7491f3c3951cdd044b1' + 'a519571bffac2da986f5f1d506c66530a55f70751e24fa8e' + 'd83ac2347f4069fb561a5565e78c6f0207da24e889a93a96' + '65f717d9fe8a2938a09ab5f81be7ccecf466c0397fc15a57' + '469939793f302739765773c256a3ca55d0548afd117a7cae' + '98ca7e0d749a130c7b743d376848e255f8fdbe4cb4480b63' + 'cd2c015d1020cf095d175f3ca9dcdfbaf1b2a6e6468eee4c' + 'c750f2132a77f376bd9782b9d0ff4da98621b898e251a263' + '4301ba2214a8c430b2f7a79dbbfd6d7ff6e9b0c137b025ff' + '587c0bf912f0b19d4fff96b1ecd2ca990c89b386055c60f2' + '3b94214bd55096f17a7b2c0fa12b333235101cd6f28a128c' + '782e8a72671adadebbd073ded30bd7f09fb693565dcf0bf3' + '090c21d13e5b0989dd8956f18f17f4f69449a13549c9d80a' + '77e5e61b5aeeee9528634100e7bc390672f0ded1ca53555b' + 'abddbcf700b9da6192255bddf50a76b709fbed251dce4c7e' + '1ca36b85d1e97c1bc9d38c887a5adf140f9eeef674c31422' + 'e65f63cae719f8c1324e42fa5fd8500899ef5aa3f9856aa7' + 'ce10c85600a040343204f36bfeab8cfa6e9deb8a2edd2a8e' + '018d00c7c9fa3a251ad0f57183c37e6377797653f382ec7a' + '2b0145e16d3c856bc3634b46d90d7198aff12aff88a30e34' + 'e2bfaf62705f3382576a9d3eeb0829fca2387b5b654af46e' + '5cf6316fb57d59e5ea6c369061ac64d99671b0e516529dd5' + 'd9c48ea0503e55fee090d36c5ea8b5954f6fcc0060794e1c' + 'b7bc24aa1e5c0142fd4ce6e8fd5aa92a7bf84317ea9e1642' + 'b6995bac6705adf93cbce72433ed0871139970d640f67b78' + 'e63a7a6d849db2567df69ac7d79f8c62664ac221df228289' + 'd0a4f9ebd9acb4f87d49da64e51a619fd3f3baccbd9feb12' + '5abe0cc2c8d17ed1d8546da2b6c641f4d3020a5f9b9f26ac' + '16546c2d61385505612275ea344c2bbf1ce890023738f715' + '5e9eba6a071678c8ebd009c328c3eb643679de86e69a9fa5' + '67a9e146030ff03d546310a0a568c5ba0070e0da22f2cef8' + '54714b04d399bbc8fd261f9e8efcd0e83bdbc3f5cfb2d024' + '3e398478cc598e000124eb8858f9df8f52946c2a1ca5c400' } }; bn.js-5.2.0/test/pummel/000077500000000000000000000000001401525734400150135ustar00rootroot00000000000000bn.js-5.2.0/test/pummel/dh-group-test.js000066400000000000000000000013001401525734400200450ustar00rootroot00000000000000/* global describe, it */ var assert = require('assert').strict; var BN = require('../../').BN; var fixtures = require('../fixtures'); describe('BN.js/Slow DH test', function () { var groups = fixtures.dhGroups; Object.keys(groups).forEach(function (name) { it('should match public key for ' + name + ' group', function () { var group = groups[name]; this.timeout(3600 * 1000); var base = new BN(2); var mont = BN.red(new BN(group.prime, 16)); var priv = new BN(group.priv, 16); var multed = base.toRed(mont).redPow(priv).fromRed(); var actual = Buffer.from(multed.toArray()); assert.equal(actual.toString('hex'), group.pub); }); }); }); bn.js-5.2.0/test/red-test.js000066400000000000000000000226471401525734400156140ustar00rootroot00000000000000/* global describe, it */ var assert = require('assert').strict; var BN = require('../').BN; describe('BN.js/Reduction context', function () { function testMethod (name, fn) { describe(name + ' method', function () { it('should support add, iadd, sub, isub operations', function () { var p = new BN(257); var m = fn(p); var a = new BN(123).toRed(m); var b = new BN(231).toRed(m); assert.equal(a.redAdd(b).fromRed().toString(10), '97'); assert.equal(a.redSub(b).fromRed().toString(10), '149'); assert.equal(b.redSub(a).fromRed().toString(10), '108'); assert.equal(a.clone().redIAdd(b).fromRed().toString(10), '97'); assert.equal(a.clone().redISub(b).fromRed().toString(10), '149'); assert.equal(b.clone().redISub(a).fromRed().toString(10), '108'); }); it('should support pow and mul operations', function () { var p192 = new BN( 'fffffffffffffffffffffffffffffffeffffffffffffffff', 16); var m = fn(p192); var a = new BN(123); var b = new BN(231); var c = a.toRed(m).redMul(b.toRed(m)).fromRed(); assert(c.cmp(a.mul(b).mod(p192)) === 0); assert.equal(a.toRed(m).redPow(new BN(0)).fromRed() .cmp(new BN(1)), 0); assert.equal(a.toRed(m).redPow(new BN(3)).fromRed() .cmp(a.sqr().mul(a)), 0); assert.equal(a.toRed(m).redPow(new BN(4)).fromRed() .cmp(a.sqr().sqr()), 0); assert.equal(a.toRed(m).redPow(new BN(8)).fromRed() .cmp(a.sqr().sqr().sqr()), 0); assert.equal(a.toRed(m).redPow(new BN(9)).fromRed() .cmp(a.sqr().sqr().sqr().mul(a)), 0); assert.equal(a.toRed(m).redPow(new BN(17)).fromRed() .cmp(a.sqr().sqr().sqr().sqr().mul(a)), 0); assert.equal( a.toRed(m).redPow(new BN('deadbeefabbadead', 16)).fromRed() .toString(16), '3aa0e7e304e320b68ef61592bcb00341866d6fa66e11a4d6'); }); it('should sqrtm numbers', function () { var p = new BN(263); var m = fn(p); var q = new BN(11).toRed(m); var qr = q.redSqrt(); assert.equal(qr.redSqr().cmp(q), 0); qr = q.redSqrt(); assert.equal(qr.redSqr().cmp(q), 0); p = new BN( 'fffffffffffffffffffffffffffffffeffffffffffffffff', 16); m = fn(p); q = new BN(13).toRed(m); qr = q.redSqrt(true, p); assert.equal(qr.redSqr().cmp(q), 0); qr = q.redSqrt(false, p); assert.equal(qr.redSqr().cmp(q), 0); // Tonelli-shanks p = new BN(13); m = fn(p); q = new BN(10).toRed(m); assert.equal(q.redSqrt().fromRed().toString(10), '7'); }); it('should invm numbers', function () { var p = new BN(257); var m = fn(p); var a = new BN(3).toRed(m); var b = a.redInvm(); assert.equal(a.redMul(b).fromRed().toString(16), '1'); }); it('should invm numbers (regression)', function () { var p = new BN( 'ffffffff00000001000000000000000000000000ffffffffffffffffffffffff', 16); var a = new BN( 'e1d969b8192fbac73ea5b7921896d6a2263d4d4077bb8e5055361d1f7f8163f3', 16); var m = fn(p); a = a.toRed(m); assert.equal(a.redInvm().fromRed().negative, 0); }); it('should imul numbers', function () { var p = new BN( 'fffffffffffffffffffffffffffffffeffffffffffffffff', 16); var m = fn(p); var a = new BN('deadbeefabbadead', 16); var b = new BN('abbadeadbeefdead', 16); var c = a.mul(b).mod(p); assert.equal(a.toRed(m).redIMul(b.toRed(m)).fromRed().toString(16), c.toString(16)); }); it('should pow(base, 0) == 1', function () { var base = new BN(256).toRed(BN.red('k256')); var exponent = new BN(0); var result = base.redPow(exponent); assert.equal(result.toString(), '1'); }); it('should shl numbers', function () { var base = new BN(256).toRed(BN.red('k256')); var result = base.redShl(1); assert.equal(result.toString(), '512'); }); it('should reduce when converting to red', function () { var p = new BN(257); var m = fn(p); var a = new BN(5).toRed(m); assert.doesNotThrow(function () { var b = a.redISub(new BN(512).toRed(m)); b.redISub(new BN(512).toRed(m)); }); }); it('redNeg and zero value', function () { var a = new BN(0).toRed(BN.red('k256')).redNeg(); assert.equal(a.isZero(), true); }); it('should not allow modulus <= 1', function () { assert.throws(function () { BN.red(new BN(0)); }, /^Error: modulus must be greater than 1$/); assert.throws(function () { BN.red(new BN(1)); }, /^Error: modulus must be greater than 1$/); assert.doesNotThrow(function () { BN.red(new BN(2)); }); }); }); } testMethod('Plain', BN.red); testMethod('Montgomery', BN.mont); describe('Pseudo-Mersenne Primes', function () { it('should reduce numbers mod k256', function () { var p = BN._prime('k256'); assert.equal(p.ireduce(new BN(0xdead)).toString(16), 'dead'); assert.equal(p.ireduce(new BN('deadbeef', 16)).toString(16), 'deadbeef'); var num = new BN( 'fedcba9876543210fedcba9876543210dead' + 'fedcba9876543210fedcba9876543210dead', 16); var exp = num.mod(p.p).toString(16); assert.equal(p.ireduce(num).toString(16), exp); var regr = new BN( 'f7e46df64c1815962bf7bc9c56128798' + '3f4fcef9cb1979573163b477eab93959' + '335dfb29ef07a4d835d22aa3b6797760' + '70a8b8f59ba73d56d01a79af9', 16); exp = regr.mod(p.p).toString(16); assert.equal(p.ireduce(regr).toString(16), exp); }); it('should not fail to invm number mod k256', function () { var regr2 = new BN( '6c150c4aa9a8cf1934485d40674d4a7cd494675537bda36d49405c5d2c6f496f', 16); regr2 = regr2.toRed(BN.red('k256')); assert.equal(regr2.redInvm().redMul(regr2).fromRed().cmpn(1), 0); }); it('should correctly square the number', function () { var p = BN._prime('k256').p; var red = BN.red('k256'); var n = new BN( '9cd8cb48c3281596139f147c1364a3ed' + 'e88d3f310fdb0eb98c924e599ca1b3c9', 16); var expected = n.sqr().mod(p); var actual = n.toRed(red).redSqr().fromRed(); assert.equal(actual.toString(16), expected.toString(16)); }); it('redISqr should return right result', function () { var n = new BN('30f28939', 16); var actual = n.toRed(BN.red('k256')).redISqr().fromRed(); assert.equal(actual.toString(16), '95bd93d19520eb1'); }); }); it('should avoid 4.1.0 regresion', function () { function bits2int (obits, q) { var bits = new BN(obits); var shift = (obits.length << 3) - q.bitLength(); if (shift > 0) { bits.ishrn(shift); } return bits; } var t = Buffer.from('aff1651e4cd6036d57aa8b2a05ccf1a9d5a40166340ecbbdc55' + 'be10b568aa0aa3d05ce9a2fcec9df8ed018e29683c6051cb83e' + '46ce31ba4edb045356a8d0d80b', 'hex'); var g = new BN( '5c7ff6b06f8f143fe8288433493e4769c4d988ace5be25a0e24809670' + '716c613d7b0cee6932f8faa7c44d2cb24523da53fbe4f6ec3595892d1' + 'aa58c4328a06c46a15662e7eaa703a1decf8bbb2d05dbe2eb956c142a' + '338661d10461c0d135472085057f3494309ffa73c611f78b32adbb574' + '0c361c9f35be90997db2014e2ef5aa61782f52abeb8bd6432c4dd097b' + 'c5423b285dafb60dc364e8161f4a2a35aca3a10b1c4d203cc76a470a3' + '3afdcbdd92959859abd8b56e1725252d78eac66e71ba9ae3f1dd24871' + '99874393cd4d832186800654760e1e34c09e4d155179f9ec0dc4473f9' + '96bdce6eed1cabed8b6f116f7ad9cf505df0f998e34ab27514b0ffe7', 16); var p = new BN( '9db6fb5951b66bb6fe1e140f1d2ce5502374161fd6538df1648218642' + 'f0b5c48c8f7a41aadfa187324b87674fa1822b00f1ecf8136943d7c55' + '757264e5a1a44ffe012e9936e00c1d3e9310b01c7d179805d3058b2a9' + 'f4bb6f9716bfe6117c6b5b3cc4d9be341104ad4a80ad6c94e005f4b99' + '3e14f091eb51743bf33050c38de235567e1b34c3d6a5c0ceaa1a0f368' + '213c3d19843d0b4b09dcb9fc72d39c8de41f1bf14d4bb4563ca283716' + '21cad3324b6a2d392145bebfac748805236f5ca2fe92b871cd8f9c36d' + '3292b5509ca8caa77a2adfc7bfd77dda6f71125a7456fea153e433256' + 'a2261c6a06ed3693797e7995fad5aabbcfbe3eda2741e375404ae25b', 16); var q = new BN('f2c3119374ce76c9356990b465374a17f23f9ed35089bd969f61c6dde' + '9998c1f', 16); var k = bits2int(t, q); var expectedR = '89ec4bb1400eccff8e7d9aa515cd1de7803f2daff09693ee7fd1353e' + '90a68307'; var r = g.toRed(BN.mont(p)).redPow(k).fromRed().mod(q); assert.equal(r.toString(16), expectedR); }); it('K256.split for 512 bits number should return equal numbers', function () { var red = BN.red('k256'); var input = new BN(1).iushln(512).subn(1); assert.equal(input.bitLength(), 512); var output = new BN(0); red.prime.split(input, output); assert.equal(input.cmp(output), 0); }); it('imod should change host object', function () { var red = BN.red(new BN(13)); var a = new BN(2).toRed(red); var b = new BN(7).toRed(red); var c = a.redIMul(b); assert.equal(a.toNumber(), 1); assert.equal(c.toNumber(), 1); }); }); bn.js-5.2.0/test/utils-test.js000066400000000000000000000344261401525734400162000ustar00rootroot00000000000000/* global describe, it */ var assert = require('assert').strict; var BN = require('../').BN; describe('BN.js/Utils', function () { describe('.toString()', function () { describe('binary padding', function () { it('should have a length of 256', function () { var a = new BN(0); assert.equal(a.toString(2, 256).length, 256); }); }); describe('hex padding', function () { it('should have length of 8 from leading 15', function () { var a = new BN('ffb9602', 16); assert.equal(a.toString('hex', 2).length, 8); }); it('should have length of 8 from leading zero', function () { var a = new BN('fb9604', 16); assert.equal(a.toString('hex', 8).length, 8); }); it('should have length of 8 from leading zeros', function () { var a = new BN(0); assert.equal(a.toString('hex', 8).length, 8); }); it('should have length of 64 from leading 15', function () { var a = new BN( 'ffb96ff654e61130ba8422f0debca77a0ea74ae5ea8bca9b54ab64aabf01003', 16); assert.equal(a.toString('hex', 2).length, 64); }); it('should have length of 64 from leading zero', function () { var a = new BN( 'fb96ff654e61130ba8422f0debca77a0ea74ae5ea8bca9b54ab64aabf01003', 16); assert.equal(a.toString('hex', 64).length, 64); }); }); }); describe('.isNeg()', function () { it('should return true for negative numbers', function () { assert.equal(new BN(-1).isNeg(), true); assert.equal(new BN(1).isNeg(), false); assert.equal(new BN(0).isNeg(), false); assert.equal(new BN('-0', 10).isNeg(), false); }); }); describe('.isOdd()', function () { it('should return true for odd numbers', function () { assert.equal(new BN(0).isOdd(), false); assert.equal(new BN(1).isOdd(), true); assert.equal(new BN(2).isOdd(), false); assert.equal(new BN('-0', 10).isOdd(), false); assert.equal(new BN('-1', 10).isOdd(), true); assert.equal(new BN('-2', 10).isOdd(), false); }); }); describe('.isEven()', function () { it('should return true for even numbers', function () { assert.equal(new BN(0).isEven(), true); assert.equal(new BN(1).isEven(), false); assert.equal(new BN(2).isEven(), true); assert.equal(new BN('-0', 10).isEven(), true); assert.equal(new BN('-1', 10).isEven(), false); assert.equal(new BN('-2', 10).isEven(), true); }); }); describe('.isZero()', function () { it('should return true for zero', function () { assert.equal(new BN(0).isZero(), true); assert.equal(new BN(1).isZero(), false); assert.equal(new BN(0xffffffff).isZero(), false); }); }); describe('.bitLength()', function () { it('should return proper bitLength', function () { assert.equal(new BN(0).bitLength(), 0); assert.equal(new BN(0x1).bitLength(), 1); assert.equal(new BN(0x2).bitLength(), 2); assert.equal(new BN(0x3).bitLength(), 2); assert.equal(new BN(0x4).bitLength(), 3); assert.equal(new BN(0x8).bitLength(), 4); assert.equal(new BN(0x10).bitLength(), 5); assert.equal(new BN(0x100).bitLength(), 9); assert.equal(new BN(0x123456).bitLength(), 21); assert.equal(new BN('123456789', 16).bitLength(), 33); assert.equal(new BN('8023456789', 16).bitLength(), 40); }); }); describe('.byteLength()', function () { it('should return proper byteLength', function () { assert.equal(new BN(0).byteLength(), 0); assert.equal(new BN(0x1).byteLength(), 1); assert.equal(new BN(0x2).byteLength(), 1); assert.equal(new BN(0x3).byteLength(), 1); assert.equal(new BN(0x4).byteLength(), 1); assert.equal(new BN(0x8).byteLength(), 1); assert.equal(new BN(0x10).byteLength(), 1); assert.equal(new BN(0x100).byteLength(), 2); assert.equal(new BN(0x123456).byteLength(), 3); assert.equal(new BN('123456789', 16).byteLength(), 5); assert.equal(new BN('8023456789', 16).byteLength(), 5); }); }); describe('.toArray()', function () { it('should return [ 0 ] for `0`', function () { var n = new BN(0); assert.deepEqual(n.toArray('be'), [0]); assert.deepEqual(n.toArray('le'), [0]); }); it('should zero pad to desired lengths', function () { var n = new BN(0x123456); assert.deepEqual(n.toArray('be', 5), [0x00, 0x00, 0x12, 0x34, 0x56]); assert.deepEqual(n.toArray('le', 5), [0x56, 0x34, 0x12, 0x00, 0x00]); }); it('should throw when naturally larger than desired length', function () { var n = new BN(0x123456); assert.throws(function () { n.toArray('be', 2); }, /^Error: byte array longer than desired length$/); }); }); describe('.toBuffer', function () { it('should return proper Buffer', function () { var n = new BN(0x123456); assert.equal(n.toBuffer('be', 5).toString('hex'), '0000123456'); assert.deepEqual(n.toBuffer('le', 5).toString('hex'), '5634120000'); var s = '211e1566be78319bb949470577c2d4ac7e800a90d5104379478d8039451a8efe'; for (var i = 1; i <= s.length; i++) { var slice = (i % 2 === 0 ? '' : '0') + s.slice(0, i); var bn = new BN(slice, 16); assert.equal(bn.toBuffer('be').toString('hex'), slice); assert.equal(bn.toBuffer('le').toString('hex'), Buffer.from(slice, 'hex').reverse().toString('hex')); } }); }); describe('.toNumber()', function () { it('should return proper Number if below the limit', function () { assert.deepEqual(new BN(0x123456).toNumber(), 0x123456); assert.deepEqual(new BN(0x3ffffff).toNumber(), 0x3ffffff); assert.deepEqual(new BN(0x4000000).toNumber(), 0x4000000); assert.deepEqual(new BN(0x10000000000000).toNumber(), 0x10000000000000); assert.deepEqual(new BN(0x10040004004000).toNumber(), 0x10040004004000); assert.deepEqual(new BN(-0x123456).toNumber(), -0x123456); assert.deepEqual(new BN(-0x3ffffff).toNumber(), -0x3ffffff); assert.deepEqual(new BN(-0x4000000).toNumber(), -0x4000000); assert.deepEqual(new BN(-0x10000000000000).toNumber(), -0x10000000000000); assert.deepEqual(new BN(-0x10040004004000).toNumber(), -0x10040004004000); }); it('should throw when number exceeds 53 bits', function () { var n = new BN(1).iushln(54); assert.throws(function () { n.toNumber(); }, /^Error: Number can only safely store up to 53 bits$/); }); }); describe('.zeroBits()', function () { it('should return proper zeroBits', function () { assert.equal(new BN(0).zeroBits(), 0); assert.equal(new BN(0x1).zeroBits(), 0); assert.equal(new BN(0x2).zeroBits(), 1); assert.equal(new BN(0x3).zeroBits(), 0); assert.equal(new BN(0x4).zeroBits(), 2); assert.equal(new BN(0x8).zeroBits(), 3); assert.equal(new BN(0x10).zeroBits(), 4); assert.equal(new BN(0x100).zeroBits(), 8); assert.equal(new BN(0x1000000).zeroBits(), 24); assert.equal(new BN(0x123456).zeroBits(), 1); }); }); describe('.toJSON', function () { it('should return hex string', function () { assert.equal(new BN(0x123).toJSON(), '0123'); }); it('should be padded to multiple of 2 bytes for interop', function () { assert.equal(new BN(0x1).toJSON(), '01'); }); }); describe('.cmpn', function () { it('should return -1, 0, 1 correctly', function () { assert.equal(new BN(42).cmpn(42), 0); assert.equal(new BN(42).cmpn(43), -1); assert.equal(new BN(42).cmpn(41), 1); assert.equal(new BN(0x3fffffe).cmpn(0x3fffffe), 0); assert.equal(new BN(0x3fffffe).cmpn(0x3ffffff), -1); assert.equal(new BN(0x3fffffe).cmpn(0x3fffffd), 1); assert.throws(function () { new BN(0x3fffffe).cmpn(0x4000000); }, /^Error: Number is too big$/); assert.equal(new BN(42).cmpn(-42), 1); assert.equal(new BN(-42).cmpn(42), -1); assert.equal(new BN(-42).cmpn(-42), 0); assert.equal(1 / new BN(-42).cmpn(-42), Infinity); }); }); describe('.cmp', function () { it('should return -1, 0, 1 correctly', function () { assert.equal(new BN(42).cmp(new BN(42)), 0); assert.equal(new BN(42).cmp(new BN(43)), -1); assert.equal(new BN(42).cmp(new BN(41)), 1); assert.equal(new BN(0x3fffffe).cmp(new BN(0x3fffffe)), 0); assert.equal(new BN(0x3fffffe).cmp(new BN(0x3ffffff)), -1); assert.equal(new BN(0x3fffffe).cmp(new BN(0x3fffffd)), 1); assert.equal(new BN(0x3fffffe).cmp(new BN(0x4000000)), -1); assert.equal(new BN(42).cmp(new BN(-42)), 1); assert.equal(new BN(-42).cmp(new BN(42)), -1); assert.equal(new BN(-42).cmp(new BN(-42)), 0); assert.equal(1 / new BN(-42).cmp(new BN(-42)), Infinity); }); }); describe('comparison shorthands', function () { it('.gtn greater than', function () { assert.equal(new BN(3).gtn(2), true); assert.equal(new BN(3).gtn(3), false); assert.equal(new BN(3).gtn(4), false); }); it('.gt greater than', function () { assert.equal(new BN(3).gt(new BN(2)), true); assert.equal(new BN(3).gt(new BN(3)), false); assert.equal(new BN(3).gt(new BN(4)), false); }); it('.gten greater than or equal', function () { assert.equal(new BN(3).gten(3), true); assert.equal(new BN(3).gten(2), true); assert.equal(new BN(3).gten(4), false); }); it('.gte greater than or equal', function () { assert.equal(new BN(3).gte(new BN(3)), true); assert.equal(new BN(3).gte(new BN(2)), true); assert.equal(new BN(3).gte(new BN(4)), false); }); it('.ltn less than', function () { assert.equal(new BN(2).ltn(3), true); assert.equal(new BN(2).ltn(2), false); assert.equal(new BN(2).ltn(1), false); }); it('.lt less than', function () { assert.equal(new BN(2).lt(new BN(3)), true); assert.equal(new BN(2).lt(new BN(2)), false); assert.equal(new BN(2).lt(new BN(1)), false); }); it('.lten less than or equal', function () { assert.equal(new BN(3).lten(3), true); assert.equal(new BN(3).lten(2), false); assert.equal(new BN(3).lten(4), true); }); it('.lte less than or equal', function () { assert.equal(new BN(3).lte(new BN(3)), true); assert.equal(new BN(3).lte(new BN(2)), false); assert.equal(new BN(3).lte(new BN(4)), true); }); it('.eqn equal', function () { assert.equal(new BN(3).eqn(3), true); assert.equal(new BN(3).eqn(2), false); assert.equal(new BN(3).eqn(4), false); }); it('.eq equal', function () { assert.equal(new BN(3).eq(new BN(3)), true); assert.equal(new BN(3).eq(new BN(2)), false); assert.equal(new BN(3).eq(new BN(4)), false); }); }); describe('.fromTwos', function () { it('should convert from two\'s complement to negative number', function () { assert.equal(new BN('00000000', 16).fromTwos(32).toNumber(), 0); assert.equal(new BN('00000001', 16).fromTwos(32).toNumber(), 1); assert.equal(new BN('7fffffff', 16).fromTwos(32).toNumber(), 2147483647); assert.equal(new BN('80000000', 16).fromTwos(32).toNumber(), -2147483648); assert.equal(new BN('f0000000', 16).fromTwos(32).toNumber(), -268435456); assert.equal(new BN('f1234567', 16).fromTwos(32).toNumber(), -249346713); assert.equal(new BN('ffffffff', 16).fromTwos(32).toNumber(), -1); assert.equal(new BN('fffffffe', 16).fromTwos(32).toNumber(), -2); assert.equal(new BN('fffffffffffffffffffffffffffffffe', 16) .fromTwos(128).toNumber(), -2); assert.equal(new BN('ffffffffffffffffffffffffffffffff' + 'fffffffffffffffffffffffffffffffe', 16).fromTwos(256).toNumber(), -2); assert.equal(new BN('ffffffffffffffffffffffffffffffff' + 'ffffffffffffffffffffffffffffffff', 16).fromTwos(256).toNumber(), -1); assert.equal( new BN('7fffffffffffffffffffffffffffffff' + 'ffffffffffffffffffffffffffffffff', 16).fromTwos(256).toString(10), new BN('5789604461865809771178549250434395392663499' + '2332820282019728792003956564819967', 10).toString(10)); assert.equal( new BN('80000000000000000000000000000000' + '00000000000000000000000000000000', 16).fromTwos(256).toString(10), new BN('-578960446186580977117854925043439539266349' + '92332820282019728792003956564819968', 10).toString(10)); }); }); describe('.toTwos', function () { it('should convert from negative number to two\'s complement', function () { assert.equal(new BN(0).toTwos(32).toString(16), '0'); assert.equal(new BN(1).toTwos(32).toString(16), '1'); assert.equal(new BN(2147483647).toTwos(32).toString(16), '7fffffff'); assert.equal(new BN('-2147483648', 10).toTwos(32).toString(16), '80000000'); assert.equal(new BN('-268435456', 10).toTwos(32).toString(16), 'f0000000'); assert.equal(new BN('-249346713', 10).toTwos(32).toString(16), 'f1234567'); assert.equal(new BN('-1', 10).toTwos(32).toString(16), 'ffffffff'); assert.equal(new BN('-2', 10).toTwos(32).toString(16), 'fffffffe'); assert.equal(new BN('-2', 10).toTwos(128).toString(16), 'fffffffffffffffffffffffffffffffe'); assert.equal(new BN('-2', 10).toTwos(256).toString(16), 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe'); assert.equal(new BN('-1', 10).toTwos(256).toString(16), 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'); assert.equal( new BN('5789604461865809771178549250434395392663' + '4992332820282019728792003956564819967', 10).toTwos(256).toString(16), '7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'); assert.equal( new BN('-578960446186580977117854925043439539266' + '34992332820282019728792003956564819968', 10).toTwos(256).toString(16), '8000000000000000000000000000000000000000000000000000000000000000'); }); }); describe('.isBN', function () { it('should return true for BN', function () { assert.equal(BN.isBN(new BN()), true); }); it('should return false for everything else', function () { assert.equal(BN.isBN(1), false); assert.equal(BN.isBN([]), false); assert.equal(BN.isBN({}), false); }); }); }); bn.js-5.2.0/util/000077500000000000000000000000001401525734400135125ustar00rootroot00000000000000bn.js-5.2.0/util/genCombMulTo.js000066400000000000000000000037521401525734400164120ustar00rootroot00000000000000'use strict'; // NOTE: This could be potentionally used to generate loop-less multiplications function genCombMulTo (alen, blen) { var len = alen + blen - 1; var src = [ 'var a = self.words;', 'var b = num.words;', 'var o = out.words;', 'var c = 0;', 'var lo;', 'var mid;', 'var hi;' ]; for (var i = 0; i < alen; i++) { src.push('var a' + i + ' = a[' + i + '] | 0;'); src.push('var al' + i + ' = a' + i + ' & 0x1fff;'); src.push('var ah' + i + ' = a' + i + ' >>> 13;'); } for (i = 0; i < blen; i++) { src.push('var b' + i + ' = b[' + i + '] | 0;'); src.push('var bl' + i + ' = b' + i + ' & 0x1fff;'); src.push('var bh' + i + ' = b' + i + ' >>> 13;'); } src.push(''); src.push('out.negative = self.negative ^ num.negative;'); src.push('out.length = ' + len + ';'); for (var k = 0; k < len; k++) { var minJ = Math.max(0, k - alen + 1); var maxJ = Math.min(k, blen - 1); src.push('/* k = ' + k + ' */'); src.push('var w' + k + ' = c;'); src.push('c = 0;'); for (var j = minJ; j <= maxJ; j++) { i = k - j; src.push('lo = Math.imul(al' + i + ', bl' + j + ');'); src.push('mid = Math.imul(al' + i + ', bh' + j + ');'); src.push('mid = (mid + Math.imul(ah' + i + ', bl' + j + ')) | 0;'); src.push('hi = Math.imul(ah' + i + ', bh' + j + ');'); src.push('w' + k + ' = (w' + k + ' + lo) | 0;'); src.push('w' + k + ' = (w' + k + ' + ((mid & 0x1fff) << 13)) | 0;'); src.push('c = (c + hi) | 0;'); src.push('c = (c + (mid >>> 13)) | 0;'); src.push('c = (c + (w' + k + ' >>> 26)) | 0;'); src.push('w' + k + ' &= 0x3ffffff;'); } } // Store in separate step for better memory access for (k = 0; k < len; k++) { src.push('o[' + k + '] = w' + k + ';'); } src.push('if (c !== 0) {'); src.push(' o[' + k + '] = c;'); src.push(' out.length++;'); src.push('}'); src.push('return out;'); return src.join('\n'); } console.log(genCombMulTo(10, 10)); bn.js-5.2.0/util/genCombMulTo10.js000066400000000000000000000040751401525734400165520ustar00rootroot00000000000000'use strict'; function genCombMulTo (alen, blen) { var len = alen + blen - 1; var src = [ 'var a = self.words;', 'var b = num.words;', 'var o = out.words;', 'var c = 0;', 'var lo;', 'var mid;', 'var hi;' ]; for (var i = 0; i < alen; i++) { src.push('var a' + i + ' = a[' + i + '] | 0;'); src.push('var al' + i + ' = a' + i + ' & 0x1fff;'); src.push('var ah' + i + ' = a' + i + ' >>> 13;'); } for (i = 0; i < blen; i++) { src.push('var b' + i + ' = b[' + i + '] | 0;'); src.push('var bl' + i + ' = b' + i + ' & 0x1fff;'); src.push('var bh' + i + ' = b' + i + ' >>> 13;'); } src.push(''); src.push('out.negative = self.negative ^ num.negative;'); src.push('out.length = ' + len + ';'); for (var k = 0; k < len; k++) { var minJ = Math.max(0, k - alen + 1); var maxJ = Math.min(k, blen - 1); src.push('/* k = ' + k + ' */'); src.push('lo = Math.imul(al' + (k - minJ) + ', bl' + minJ + ');'); src.push('mid = Math.imul(al' + (k - minJ) + ', bh' + minJ + ');'); src.push('mid = (mid + Math.imul(ah' + (k - minJ) + ', bl' + minJ + ')) | 0;'); src.push('hi = Math.imul(ah' + (k - minJ) + ', bh' + minJ + ');'); for (var j = minJ + 1; j <= maxJ; j++) { i = k - j; src.push('lo = (lo + Math.imul(al' + i + ', bl' + j + ')) | 0;'); src.push('mid = (mid + Math.imul(al' + i + ', bh' + j + ')) | 0;'); src.push('mid = (mid + Math.imul(ah' + i + ', bl' + j + ')) | 0;'); src.push('hi = (hi + Math.imul(ah' + i + ', bh' + j + ')) | 0;'); } src.push('var w' + k + ' = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;'); src.push('c = (((hi + (mid >>> 13)) | 0) + (w' + k + ' >>> 26)) | 0;'); src.push('w' + k + ' &= 0x3ffffff;'); } // Store in separate step for better memory access for (k = 0; k < len; k++) { src.push('o[' + k + '] = w' + k + ';'); } src.push('if (c !== 0) {'); src.push(' o[' + k + '] = c;'); src.push(' out.length++;'); src.push('}'); src.push('return out;'); return src.join('\n'); } console.log(genCombMulTo(10, 10));