|
|
@ -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])); |
|
|
|
} |
|
|
|
|
|
|
|
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]; |
|
|
|
var endian = 'big'; |
|
|
|
if (opts) { |
|
|
|
endian = opts.endian; |
|
|
|
} |
|
|
|
for (i = 0; i < size - natlen; i++) { |
|
|
|
rbuf[i] = 0; |
|
|
|
if (endian === 'little') { |
|
|
|
buf = reversebuf(buf); |
|
|
|
} |
|
|
|
return rbuf; |
|
|
|
|
|
|
|
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.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; |
|
|
|