diff --git a/lib/crypto/bn.js b/lib/crypto/bn.js index 885f81a64..0ffa9874b 100644 --- a/lib/crypto/bn.js +++ b/lib/crypto/bn.js @@ -1,18 +1,9 @@ 'use strict'; -var _BN = require('bn.js'); +var BN = require('bn.js'); var $ = require('../util/preconditions'); var _ = require('lodash'); -var BN = function BN(n, base) { - if (!(this instanceof BN)) { - return new BN(n, base); - } - _BN.apply(this, arguments); -}; - -BN.prototype = _BN.prototype; - var reversebuf = function(buf) { var buf2 = new Buffer(buf.length); for (var i = 0; i < buf.length; i++) { @@ -26,10 +17,6 @@ BN.fromNumber = function(n) { return BN(n); }; -BN.prototype.toNumber = function() { - return parseInt(this.toString(10), 10); -}; - BN.fromString = function(str) { $.checkArgument(_.isString(str)); return BN(str); @@ -44,19 +31,37 @@ BN.fromBuffer = function(buf, opts) { return bn; }; -BN.trim = function(buf, natlen) { - return buf.slice(natlen - buf.length, buf.length); +/** + * Instantiate a BigNumber from a "signed magnitude buffer" + * (a buffer where the most significant bit represents the sign (0 = positive, -1 = negative)) + */ +BN.fromSM = function(buf, opts) { + var ret; + if (buf.length === 0) { + return BN.fromBuffer(new Buffer([0])); + } + + var endian = 'big'; + if (opts) { + endian = opts.endian; + } + if (endian === 'little') { + buf = reversebuf(buf); + } + + if (buf[0] & 0x80) { + buf[0] = buf[0] & 0x7f; + ret = BN.fromBuffer(buf); + ret.neg().copy(ret); + } else { + ret = BN.fromBuffer(buf); + } + return ret; }; -BN.pad = function(buf, natlen, size) { - var rbuf = new Buffer(size); - for (var i = 0; i < buf.length; i++) { - rbuf[rbuf.length - 1 - i] = buf[buf.length - 1 - i]; - } - for (i = 0; i < size - natlen; i++) { - rbuf[i] = 0; - } - return rbuf; + +BN.prototype.toNumber = function() { + return parseInt(this.toString(10), 10); }; BN.prototype.toBuffer = function(opts) { @@ -85,32 +90,6 @@ BN.prototype.toBuffer = function(opts) { return buf; }; -// signed magnitude buffer -// most significant bit represents sign (0 = positive, -1 = negative) -BN.fromSM = function(buf, opts) { - var ret; - if (buf.length === 0) { - return BN.fromBuffer(new Buffer([0])); - } - - var endian = 'big'; - if (opts) { - endian = opts.endian; - } - if (endian === 'little') { - buf = reversebuf(buf); - } - - if (buf[0] & 0x80) { - buf[0] = buf[0] & 0x7f; - ret = BN.fromBuffer(buf); - ret.neg().copy(ret); - } else { - ret = BN.fromBuffer(buf); - } - return ret; -}; - BN.prototype.toSMBigEndian = function() { var buf; if (this.cmp(0) === -1) { @@ -132,6 +111,7 @@ BN.prototype.toSMBigEndian = function() { } return buf; }; + BN.prototype.toSM = function(opts) { var endian = opts ? opts.endian : 'big'; var buf = this.toSMBigEndian(); @@ -142,10 +122,13 @@ BN.prototype.toSM = function(opts) { return buf; }; -// This is analogous to the constructor for CScriptNum in bitcoind. Many ops in -// bitcoind's script interpreter use CScriptNum, which is not really a proper -// bignum. Instead, an error is thrown if trying to input a number bigger than -// 4 bytes. We copy that behavior here. +/** + * Create a BN from a "ScriptNum": + * This is analogous to the constructor for CScriptNum in bitcoind. Many ops in + * bitcoind's script interpreter use CScriptNum, which is not really a proper + * bignum. Instead, an error is thrown if trying to input a number bigger than + * 4 bytes. We copy that behavior here. + */ BN.fromScriptNumBuffer = function(buf, fRequireMinimal) { var nMaxNumSize = 4; $.checkArgument(buf.length <= nMaxNumSize, new Error('script number overflow')); @@ -172,29 +155,18 @@ BN.fromScriptNumBuffer = function(buf, fRequireMinimal) { }); }; -// The corollary to the above, with the notable exception that we do not throw -// an error if the output is larger than four bytes. (Which can happen if -// performing a numerical operation that results in an overflow to more than 4 -// bytes). +/** + * The corollary to the above, with the notable exception that we do not throw + * an error if the output is larger than four bytes. (Which can happen if + * performing a numerical operation that results in an overflow to more than 4 + * bytes). + */ BN.prototype.toScriptNumBuffer = function() { return this.toSM({ endian: 'little' }); }; -var decorate = function decorate(name) { - BN.prototype['_' + name] = BN.prototype[name]; - var f = function(b) { - if (typeof b === 'string') { - b = new BN(b); - } else if (typeof b === 'number') { - b = new BN(b.toString()); - } - return this['_' + name](b); - }; - BN.prototype[name] = f; -}; - BN.prototype.gt = function(b) { return this.cmp(b) > 0; }; @@ -203,13 +175,19 @@ BN.prototype.lt = function(b) { return this.cmp(b) < 0; }; -decorate('add'); -decorate('sub'); -decorate('mul'); -decorate('mod'); -decorate('div'); -decorate('cmp'); -decorate('gt'); -decorate('lt'); +BN.trim = function(buf, natlen) { + return buf.slice(natlen - buf.length, buf.length); +}; + +BN.pad = function(buf, natlen, size) { + var rbuf = new Buffer(size); + for (var i = 0; i < buf.length; i++) { + rbuf[rbuf.length - 1 - i] = buf[buf.length - 1 - i]; + } + for (i = 0; i < size - natlen; i++) { + rbuf[i] = 0; + } + return rbuf; +}; module.exports = BN;