Browse Source

make bignum interface backwards compatible

- fix cmp, mul, div, add, mod, sub functions to take numbers and strings
- fix Point class to use common folder correctly
patch-2
Ryan X. Charles 11 years ago
parent
commit
af1d754bd8
  1. 1364
      browser/testdata.js
  2. 33
      lib/Point.js
  3. 74
      lib/browser/Bignum.js
  4. 45
      lib/browser/Point.js
  5. 46
      lib/common/Point.js
  6. 5
      test/test.Bignum.browser.js
  7. 10
      test/test.TransactionBuilder.js
  8. 8
      test/test.misc.js
  9. 8
      util/util.js

1364
browser/testdata.js

File diff suppressed because one or more lines are too long

33
lib/Point.js

@ -3,13 +3,7 @@
var bignum = require('bignum');
var CPPKey = require('bindings')('KeyModule').Key;
var assert = require('assert');
//a point on the secp256k1 curve
//x and y are bignums
var Point = function(x, y) {
this.x = x;
this.y = y;
};
var Point = require('./common/Point');
Point.add = function(p1, p2) {
var u1 = p1.toUncompressedPubKey();
@ -24,29 +18,4 @@ Point.multiply = function(p1, x) {
return Point.fromUncompressedPubKey(pubKey);
};
//convert the public key of a Key into a Point
Point.fromUncompressedPubKey = function(pubkey) {
var point = new Point();
point.x = bignum.fromBuffer(pubkey.slice(1, 33), {
size: 32
});
point.y = bignum.fromBuffer(pubkey.slice(33, 65), {
size: 32
});
return point;
};
//convert the Point into the Key containing a compressed public key
Point.prototype.toUncompressedPubKey = function() {
var xbuf = this.x.toBuffer({
size: 32
});
var ybuf = this.y.toBuffer({
size: 32
});
var prefix = new Buffer([0x04]);
var pubkey = Buffer.concat([prefix, xbuf, ybuf]);
return pubkey;
};
module.exports = (Point);

74
lib/browser/Bignum.js

@ -1,8 +1,6 @@
var bnjs = require('bn.js');
var _bnjs = require('bn.js');
var _bnjs = bnjs;
bnjs = function bnjs_extended(n) {
var bnjs = function bnjs_extended(n) {
if (!(this instanceof bnjs_extended)) {
return new bnjs(n);
}
@ -75,15 +73,79 @@ bnjs.prototype.toBuffer = function(opts) {
return buf;
};
bnjs.prototype._add = _bnjs.prototype.add;
bnjs.prototype.add = function(b) {
if (typeof b === 'number')
b = b.toString();
if (typeof b === 'number' || typeof b === 'string')
b = new _bnjs(b);
return this._add(b);
};
bnjs.prototype._sub = _bnjs.prototype.sub;
bnjs.prototype.sub = function(b) {
if (typeof b === 'number')
b = b.toString();
if (typeof b === 'number' || typeof b === 'string')
b = new _bnjs(b);
return this._sub(b);
};
bnjs.prototype._mul = _bnjs.prototype.mul;
bnjs.prototype.mul = function(b) {
if (typeof b === 'number')
b = b.toString();
if (typeof b === 'number' || typeof b === 'string')
b = new _bnjs(b);
return this._mul(b);
};
bnjs.prototype._mod = _bnjs.prototype.mod;
bnjs.prototype.mod = function(b) {
if (typeof b === 'number')
b = b.toString();
if (typeof b === 'number' || typeof b === 'string')
b = new _bnjs(b);
return this._mod(b);
};
bnjs.prototype._div = _bnjs.prototype.div;
bnjs.prototype.div = function(b) {
if (typeof b === 'number')
b = b.toString();
if (typeof b === 'number' || typeof b === 'string')
b = new _bnjs(b);
return this._div(b);
};
bnjs.prototype._cmp = _bnjs.prototype.cmp;
bnjs.prototype.cmp = function(b) {
if (typeof b === 'number')
b = b.toString();
if (typeof b === 'number' || typeof b === 'string')
b = new _bnjs(b);
return this._cmp(b);
};
bnjs.prototype.gt = function(b) {
if (typeof b === 'number')
b = new bnjs(b);
b = b.toString();
if (typeof b === 'number' || typeof b === 'string')
b = new _bnjs(b);
return this.cmp(b) > 0;
};
bnjs.prototype.lt = function(b) {
if (typeof b === 'number')
b = new bnjs(b);
b = b.toString();
if (typeof b === 'number' || typeof b === 'string')
b = new _bnjs(b);
return this.cmp(b) < 0;
};

45
lib/browser/Point.js

@ -4,13 +4,7 @@ var Key = require('./Key');
var bignum = require('bignum');
var assert = require('assert');
var elliptic = require('elliptic');
//a point on the secp256k1 curve
//x and y are bignums
var Point = function(x, y) {
this.x = x;
this.y = y;
};
var Point = require('../common/Point');
Point.add = function(p1, p2) {
var ec = elliptic.curves.secp256k1;
@ -30,41 +24,4 @@ Point.multiply = function(p1, xbuf) {
return p;
};
//convert the public key of a Key into a Point
Point.fromUncompressedPubKey = function(pubkey) {
var point = new Point();
point.x = bignum.fromBuffer((new Buffer(pubkey)).slice(1, 33), {
size: 32
});
point.y = bignum.fromBuffer((new Buffer(pubkey)).slice(33, 65), {
size: 32
});
return point;
};
//convert the Point into the Key containing a compressed public key
Point.prototype.toUncompressedPubKey = function() {
var xbuf = this.x.toBuffer({
size: 32
});
var ybuf = this.y.toBuffer({
size: 32
});
var prefix = new Buffer([0x04]);
var pub = Buffer.concat([prefix, xbuf, ybuf]);
return pub;
};
Point.prototype.toCompressedPubKey = function() {
var xbuf = this.x.toBuffer({size: 32});
var ybuf = this.y.toBuffer({size: 32});
if (ybuf[ybuf.length-1] % 2) { //odd
var pub = Buffer.concat([new Buffer([3]), xbuf]);
}
else { //even
var pub = Buffer.concat([new Buffer([2]), xbuf]);
}
return pub;
};
module.exports = (Point);

46
lib/common/Point.js

@ -0,0 +1,46 @@
var bignum = require('bignum');
//x and y are both bignums
var Point = function(x, y) {
this.x = x;
this.y = y;
};
//convert the public key of a Key into a Point
Point.fromUncompressedPubKey = function(pubkey) {
var point = new Point();
point.x = bignum.fromBuffer(pubkey.slice(1, 33), {
size: 32
});
point.y = bignum.fromBuffer(pubkey.slice(33, 65), {
size: 32
});
return point;
};
//convert the Point into the Key containing a compressed public key
Point.prototype.toUncompressedPubKey = function() {
var xbuf = this.x.toBuffer({
size: 32
});
var ybuf = this.y.toBuffer({
size: 32
});
var prefix = new Buffer([0x04]);
var pubkey = Buffer.concat([prefix, xbuf, ybuf]);
return pubkey;
};
Point.prototype.toCompressedPubKey = function() {
var xbuf = this.x.toBuffer({size: 32});
var ybuf = this.y.toBuffer({size: 32});
if (ybuf[ybuf.length-1] % 2) { //odd
var pub = Buffer.concat([new Buffer([3]), xbuf]);
}
else { //even
var pub = Buffer.concat([new Buffer([2]), xbuf]);
}
return pub;
};
module.exports = Point;

5
test/test.Bignum.browser.js

@ -19,6 +19,11 @@ if (typeof process == 'undefined' || typeof process.versions == 'undefined') {
should.exist(bn);
bn.toString().should.equal('50');
});
it('should parse this number', function() {
var bn = new Bignum(999970000);
bn.toString().should.equal('999970000');
});
describe('#add', function() {

10
test/test.TransactionBuilder.js

@ -191,7 +191,7 @@ describe('TransactionBuilder', function() {
tx.ins.length.should.equal(2);
tx.outs.length.should.equal(2);
util.valueToBigInt(tx.outs[0].v).cmp(new bignum(8000000)).should.equal(0);
util.valueToBigInt(tx.outs[0].v).cmp(8000000).should.equal(0);
// remainder is 0.0299 here because unspent select utxos in order
//util.valueToBigInt(tx.outs[1].v).cmp(new bignum(2990000)).should.equal(0);
@ -440,7 +440,7 @@ describe('TransactionBuilder', function() {
parseInt(b.remainderSat.toString()).should.equal(parseInt(9.9997 * util.COIN));
util.valueToBigInt(tx.outs[N].v).cmp(new bignum(999970000)).should.equal(0);
util.valueToBigInt(tx.outs[N].v).cmp(999970000).should.equal(0);
tx.isComplete().should.equal(false);
});
@ -477,7 +477,7 @@ describe('TransactionBuilder', function() {
// 101 * 0.01 = 1.01BTC; + 0.0004 fee = 1.0104btc
// remainder = 11.0101-1.0104 = 9.9997
parseInt(b.remainderSat.toString()).should.equal(parseInt(0.0097 * util.COIN));
util.valueToBigInt(tx.outs[N].v).cmp(new bignum(970000)).should.equal(0);
util.valueToBigInt(tx.outs[N].v).cmp(970000).should.equal(0);
tx.isComplete().should.equal(false);
});
@ -859,10 +859,10 @@ describe('TransactionBuilder', function() {
tx.ins.length.should.equal(2);
tx.outs.length.should.equal(2);
util.valueToBigInt(tx.outs[0].v).cmp(new bignum(8000000)).should.equal(0);
util.valueToBigInt(tx.outs[0].v).cmp(8000000).should.equal(0);
// remainder is 0.0299 here because unspent select utxos in order
util.valueToBigInt(tx.outs[1].v).cmp(new bignum(2990000)).should.equal(0);
util.valueToBigInt(tx.outs[1].v).cmp(2990000).should.equal(0);
});
it('#toObj #fromObj roundtrip, step signatures p2sh/p2pubkeyhash', function() {

8
test/test.misc.js

@ -84,13 +84,13 @@ describe('Miscelaneous stuff', function() {
should.exist(bitcore.Bignum);
});
it('should create a bignum from string', function() {
var n = new bignum('9832087987979879879879879879879879879879879879');
var n = bignum('9832087987979879879879879879879879879879879879');
should.exist(n);
});
it('should perform basic math operations for bignum', function() {
var b = new bignum('782910138827292261791972728324982')
.sub(new bignum('182373273283402171237474774728373'))
.div(new bignum(13));
var b = bignum('782910138827292261791972728324982')
.sub('182373273283402171237474774728373')
.div(13);
b.toNumber().should.equal(46195143503376160811884457968969);
});

8
util/util.js

@ -224,7 +224,7 @@ exports.intToBufferSM = function(v) {
v = new bignum(v);
}
var b, c;
var cmp = v.cmp(new bignum(0));
var cmp = v.cmp(0);
if (cmp > 0) {
b = v.toBuffer();
c = padSign(b);
@ -292,7 +292,7 @@ function padFrac(frac) {
}
function parseFullValue(res) {
return new bignum(res[1]).mul(new bignum('100000000')).add(new bignum(padFrac(res[2])));
return new bignum(res[1]).mul('100000000').add(new bignum(padFrac(res[2])));
}
function parseFracValue(res) {
@ -300,7 +300,7 @@ function parseFracValue(res) {
}
function parseWholeValue(res) {
return new bignum(res[1]).mul(new bignum('100000000'));
return new bignum(res[1]).mul('100000000');
}
exports.parseValue = function parseValue(valueStr) {
@ -368,7 +368,7 @@ var decodeDiffBits = exports.decodeDiffBits = function(diffBits, asBigInt) {
var mov = 8 * ((diffBits >>> 24) - 3);
while (mov-- > 0)
target = target.mul(new bignum(2));
target = target.mul(2);
if (asBigInt) {
return target;

Loading…
Cancel
Save