From 73a973359b82dab1dc52b439838c9e3dbe8de78f Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Thu, 5 Feb 2015 17:24:48 -0300 Subject: [PATCH] Fix invocations to binary operations called on numbers --- lib/blockheader.js | 2 +- lib/crypto/bn.js | 6 +++++- lib/crypto/ecdsa.js | 8 ++++---- lib/crypto/point.js | 6 +++--- lib/crypto/signature.js | 4 ++-- lib/privatekey.js | 2 +- lib/script/interpreter.js | 14 +++++++------- lib/transaction/transaction.js | 6 +++--- test/crypto/bn.js | 2 +- test/crypto/ecdsa.js | 10 +++++----- test/crypto/point.js | 6 +++--- test/crypto/signature.js | 4 ++-- test/encoding/bufferreader.js | 6 +++--- test/encoding/bufferwriter.js | 12 ++++++------ test/encoding/varint.js | 6 +++--- test/privatekey.js | 8 ++++---- test/publickey.js | 2 +- test/script/interpreter.js | 10 +++++----- 18 files changed, 59 insertions(+), 55 deletions(-) diff --git a/lib/blockheader.js b/lib/blockheader.js index cf5d0d6e6..c18482150 100644 --- a/lib/blockheader.js +++ b/lib/blockheader.js @@ -198,7 +198,7 @@ BlockHeader.prototype.getTargetDifficulty = function getTargetDifficulty(info) { var target = new BN(this.bits & 0xffffff); var mov = 8 * ((this.bits >>> 24) - 3); while (mov-- > 0) { - target = target.mul(2); + target = target.mul(new BN(2)); } return target; }; diff --git a/lib/crypto/bn.js b/lib/crypto/bn.js index 7f26ea614..a1d381c81 100644 --- a/lib/crypto/bn.js +++ b/lib/crypto/bn.js @@ -12,6 +12,10 @@ var reversebuf = function(buf) { return buf2; }; +BN.Zero = new BN(0); +BN.One = new BN(1); +BN.Minus1 = new BN(-1); + BN.fromNumber = function(n) { $.checkArgument(_.isNumber(n)); return new BN(n); @@ -92,7 +96,7 @@ BN.prototype.toBuffer = function(opts) { BN.prototype.toSMBigEndian = function() { var buf; - if (this.cmp(0) === -1) { + if (this.cmp(BN.Zero) === -1) { buf = this.neg().toBuffer(); if (buf[0] & 0x80) { buf = Buffer.concat([new Buffer([0x80]), buf]); diff --git a/lib/crypto/ecdsa.js b/lib/crypto/ecdsa.js index 42fa7749e..5f2c207d2 100644 --- a/lib/crypto/ecdsa.js +++ b/lib/crypto/ecdsa.js @@ -66,7 +66,7 @@ ECDSA.prototype.randomK = function() { var k; do { k = BN.fromBuffer(Random.getRandomBuffer(32)); - } while (!(k.lt(N) && k.gt(0))); + } while (!(k.lt(N) && k.gt(BN.Zero))); this.k = k; return this; }; @@ -97,7 +97,7 @@ ECDSA.prototype.deterministicK = function(badrs) { var N = Point.getN(); // also explained in 3.2, we must ensure T is in the proper range (0, N) - for (var i = 0; i < badrs || !(T.lt(N) && T.gt(0)); i++) { + for (var i = 0; i < badrs || !(T.lt(N) && T.gt(BN.Zero)); i++) { k = Hash.sha256hmac(Buffer.concat([v, new Buffer([0x00])]), k); v = Hash.sha256hmac(v, k); v = Hash.sha256hmac(v, k); @@ -164,7 +164,7 @@ ECDSA.prototype.sigError = function() { var r = this.sig.r; var s = this.sig.s; - if (!(r.gt(0) && r.lt(Point.getN())) || !(s.gt(0) && s.lt(Point.getN()))) { + if (!(r.gt(BN.Zero) && r.lt(Point.getN())) || !(s.gt(BN.Zero) && s.lt(Point.getN()))) { return 'r and s not in range'; } @@ -212,7 +212,7 @@ ECDSA.prototype._findSignature = function(d, e) { Q = G.mul(k); r = Q.x.mod(N); s = k.invm(N).mul(e.add(d.mul(r))).mod(N); - } while (r.cmp(0) <= 0 || s.cmp(0) <= 0); + } while (r.cmp(BN.Zero) <= 0 || s.cmp(BN.Zero) <= 0); s = ECDSA.toLowS(s); return { diff --git a/lib/crypto/point.js b/lib/crypto/point.js index c5307cf13..2e4b9d1d7 100644 --- a/lib/crypto/point.js +++ b/lib/crypto/point.js @@ -102,7 +102,7 @@ Point.prototype.validate = function validate() { throw new Error('Point cannot be equal to Infinity'); } - if (this.getX().cmp(0) === 0 || this.getY().cmp(0) === 0){ + if (this.getX().cmp(BN.Zero) === 0 || this.getY().cmp(BN.Zero) === 0){ throw new Error('Invalid x,y value for curve, cannot equal 0.'); } @@ -112,8 +112,8 @@ Point.prototype.validate = function validate() { throw new Error('Invalid y value for curve.'); } - var xValidRange = (this.getX().gt(-1) && this.getX().lt(Point.getN())); - var yValidRange = (this.getY().gt(-1) && this.getY().lt(Point.getN())); + var xValidRange = (this.getX().gt(BN.Minus1) && this.getX().lt(Point.getN())); + var yValidRange = (this.getY().gt(BN.Minus1) && this.getY().lt(Point.getN())); if ( !xValidRange || !yValidRange ) { throw new Error('Point does not lie on the curve'); diff --git a/lib/crypto/signature.js b/lib/crypto/signature.js index 2ca0b3340..463b48ca1 100644 --- a/lib/crypto/signature.js +++ b/lib/crypto/signature.js @@ -264,8 +264,8 @@ Signature.isTxDER = function(buf) { * See also BIP 62, "low S values in signatures" */ Signature.prototype.hasLowS = function() { - if (this.s.lt(1) || - this.s.gt(BN('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0'))) { + if (this.s.lt(new BN(1)) || + this.s.gt(new BN('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0'))) { return false; } return true; diff --git a/lib/privatekey.js b/lib/privatekey.js index 488828508..149274778 100644 --- a/lib/privatekey.js +++ b/lib/privatekey.js @@ -47,7 +47,7 @@ var PrivateKey = function PrivateKey(data, network) { var info = this._classifyArguments(data, network); // validation - if (!info.bn || info.bn.cmp(0) === 0){ + if (!info.bn || info.bn.cmp(new BN(0)) === 0){ throw new TypeError('Number can not be equal to zero, undefined, null or false'); } if (!info.bn.lt(Point.getN())) { diff --git a/lib/script/interpreter.js b/lib/script/interpreter.js index dcc0f19e5..2b4b49f2c 100644 --- a/lib/script/interpreter.js +++ b/lib/script/interpreter.js @@ -803,24 +803,24 @@ Interpreter.prototype.step = function() { bn = BN.fromScriptNumBuffer(buf, fRequireMinimal); switch (opcodenum) { case Opcode.OP_1ADD: - bn = bn.add(1); + bn = bn.add(BN.One); break; case Opcode.OP_1SUB: - bn = bn.sub(1); + bn = bn.sub(BN.One); break; case Opcode.OP_NEGATE: bn = bn.neg(); break; case Opcode.OP_ABS: - if (bn.cmp(0) < 0) { + if (bn.cmp(BN.Zero) < 0) { bn = bn.neg(); } break; case Opcode.OP_NOT: - bn = new BN((bn.cmp(0) === 0) + 0); + bn = new BN((bn.cmp(BN.Zero) === 0) + 0); break; case Opcode.OP_0NOTEQUAL: - bn = new BN((bn.cmp(0) !== 0) + 0); + bn = new BN((bn.cmp(BN.Zero) !== 0) + 0); break; //default: assert(!'invalid opcode'); break; // TODO: does this ever occur? } @@ -863,11 +863,11 @@ Interpreter.prototype.step = function() { // case Opcode.OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; case Opcode.OP_BOOLAND: - bn = new BN(((bn1.cmp(0) !== 0) && (bn2.cmp(0) !== 0)) + 0); + bn = new BN(((bn1.cmp(BN.Zero) !== 0) && (bn2.cmp(BN.Zero) !== 0)) + 0); break; // case Opcode.OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; case Opcode.OP_BOOLOR: - bn = new BN(((bn1.cmp(0) !== 0) || (bn2.cmp(0) !== 0)) + 0); + bn = new BN(((bn1.cmp(BN.Zero) !== 0) || (bn2.cmp(BN.Zero) !== 0)) + 0); break; // case Opcode.OP_NUMEQUAL: bn = (bn1 == bn2); break; case Opcode.OP_NUMEQUAL: diff --git a/lib/transaction/transaction.js b/lib/transaction/transaction.js index d4930406e..a3ddb1c25 100644 --- a/lib/transaction/transaction.js +++ b/lib/transaction/transaction.js @@ -731,14 +731,14 @@ Transaction.prototype.verify = function() { for (var i = 0; i < this.outputs.length; i++) { var txout = this.outputs[i]; var valuebn = txout._satoshisBN; - if (valuebn.lt(0)) { + if (valuebn.lt(BN.Zero)) { return 'transaction txout ' + i + ' negative'; } - if (valuebn.gt(BN(Transaction.MAX_MONEY, 10))) { + if (valuebn.gt(new BN(Transaction.MAX_MONEY, 10))) { return 'transaction txout ' + i + ' greater than MAX_MONEY'; } valueoutbn = valueoutbn.add(valuebn); - if (valueoutbn.gt(Transaction.MAX_MONEY)) { + if (valueoutbn.gt(new BN(Transaction.MAX_MONEY))) { return 'transaction txout ' + i + ' total output greater than MAX_MONEY'; } } diff --git a/test/crypto/bn.js b/test/crypto/bn.js index fe95014c2..a57260d4d 100644 --- a/test/crypto/bn.js +++ b/test/crypto/bn.js @@ -70,7 +70,7 @@ describe('BN', function() { describe('to/from ScriptNumBuffer', function() { [0, 1, 10, 256, 1000, 65536, 65537, -1, -1000, -65536, -65537].forEach(function(n) { it('rountrips correctly for ' + n, function() { - BN.fromScriptNumBuffer(BN(n).toScriptNumBuffer()).toNumber().should.equal(n); + BN.fromScriptNumBuffer(new BN(n).toScriptNumBuffer()).toNumber().should.equal(n); }); }); }); diff --git a/test/crypto/ecdsa.js b/test/crypto/ecdsa.js index c78a8876b..974a56a3a 100644 --- a/test/crypto/ecdsa.js +++ b/test/crypto/ecdsa.js @@ -83,7 +83,7 @@ describe('ECDSA', function() { it('should generate a random k that is (almost always) greater than this relatively small number', function() { ecdsa.randomK(); var k1 = ecdsa.k; - var k2 = new BN(Math.pow(2, 32)).mul(BN(Math.pow(2, 32))).mul(BN(Math.pow(2, 32))); + var k2 = new BN(Math.pow(2, 32)).mul(new BN(Math.pow(2, 32))).mul(new BN(Math.pow(2, 32))); k2.gt(k1).should.equal(false); }); @@ -110,7 +110,7 @@ describe('ECDSA', function() { // https://github.com/bitcoinjs/bitcoinjs-lib/blob/10630873ebaa42381c5871e20336fbfb46564ac8/test/fixtures/ecdsa.json#L6 var ecdsa = new ECDSA(); ecdsa.hashbuf = Hash.sha256(new Buffer('Everything should be made as simple as possible, but not simpler.')); - ecdsa.privkey = new Privkey(BN(1)); + ecdsa.privkey = new Privkey(new BN(1)); ecdsa.privkey2pubkey(); ecdsa.deterministicK(); ecdsa.k.toBuffer().toString('hex') @@ -175,7 +175,7 @@ describe('ECDSA', function() { it('should return an error if the signature is incorrect', function() { ecdsa.sig = Signature.fromString('3046022100e9915e6236695f093a4128ac2a956c40' + 'ed971531de2f4f41ba05fac7e2bd019c02210094e6a4a769cc7f2a8ab3db696c7cd8d56bcdbfff860a8c81de4bc6a798b90827'); - ecdsa.sig.r = ecdsa.sig.r.add(BN(1)); + ecdsa.sig.r = ecdsa.sig.r.add(new BN(1)); ecdsa.sigError().should.equal('Invalid signature'); }); @@ -248,7 +248,7 @@ describe('ECDSA', function() { it('should verify a valid signature, and unverify an invalid signature', function() { var sig = ECDSA.sign(ecdsa.hashbuf, ecdsa.privkey); ECDSA.verify(ecdsa.hashbuf, sig, ecdsa.pubkey).should.equal(true); - var fakesig = new Signature(sig.r.add(1), sig.s); + var fakesig = new Signature(sig.r.add(new BN(1)), sig.s); ECDSA.verify(ecdsa.hashbuf, fakesig, ecdsa.pubkey).should.equal(false); }); it('should work with big and little endian', function() { @@ -290,7 +290,7 @@ describe('ECDSA', function() { it('should validate invalid.sigError vector ' + i + ': ' + obj.description, function() { var ecdsa = ECDSA().set({ pubkey: Pubkey.fromPoint(point.fromX(true, 1)), - sig: new Signature(BN(obj.signature.r), new BN(obj.signature.s)), + sig: new Signature(new BN(obj.signature.r), new BN(obj.signature.s)), hashbuf: Hash.sha256(new Buffer(obj.message)) }); ecdsa.sigError().should.equal(obj.exception); diff --git a/test/crypto/point.js b/test/crypto/point.js index 1728939e1..b23423f92 100644 --- a/test/crypto/point.js +++ b/test/crypto/point.js @@ -78,7 +78,7 @@ describe('Point', function() { it('should accurately multiply g by 2', function() { var g = Point.getG(); - var b = g.mul(BN(2)); + var b = g.mul(new BN(2)); b.getX().toString().should.equal('8956589192654700423125292042593569236064414582962220983'+ '3684329913297188986597'); b.getY().toString().should.equal('1215839929969383032296780861271339863615536788704162817'+ @@ -88,7 +88,7 @@ describe('Point', function() { it('should accurately multiply g by n-1', function() { var g = Point.getG(); var n = Point.getN(); - var b = g.mul(n.sub(1)); + var b = g.mul(n.sub(new BN(1))); b.getX().toString().should.equal('55066263022277343669578718895168534326250603453777594175'+ '500187360389116729240'); b.getY().toString().should.equal('83121579216557378445487899878180864668798711284981320763'+ @@ -101,7 +101,7 @@ describe('Point', function() { it('should accurately multiply g by n+1', function() { var g = Point.getG(); var n = Point.getN(); - var b = g.mul(n.add(1)); + var b = g.mul(n.add(new BN(1))); b.getX().toString().should.equal('550662630222773436695787188951685343262506034537775941755'+ '00187360389116729240'); b.getY().toString().should.equal('326705100207588169780830851305070431844712733806592432759'+ diff --git a/test/crypto/signature.js b/test/crypto/signature.js index 62305f36c..809d9b906 100644 --- a/test/crypto/signature.js +++ b/test/crypto/signature.js @@ -47,8 +47,8 @@ describe('Signature', function() { blank ]); var sig = Signature.fromCompact(compressed); - sig.r.cmp(0).should.equal(0); - sig.s.cmp(0).should.equal(0); + sig.r.cmp(BN.Zero).should.equal(0); + sig.s.cmp(BN.Zero).should.equal(0); }); }); diff --git a/test/encoding/bufferreader.js b/test/encoding/bufferreader.js index f3e053267..97b0e8b6b 100644 --- a/test/encoding/bufferreader.js +++ b/test/encoding/bufferreader.js @@ -230,7 +230,7 @@ describe('BufferReader', function() { }); it('should read a 9 byte varint', function() { - var buf = BufferWriter().writeVarintBN(BN(Math.pow(2, 54).toString())).concat(); + var buf = BufferWriter().writeVarintBN(new BN(Math.pow(2, 54).toString())).concat(); var br = new BufferReader(buf); br.readVarintBuf().length.should.equal(9); }); @@ -259,7 +259,7 @@ describe('BufferReader', function() { }); it('should throw an error on a 9 byte varint over the javascript uint precision limit', function() { - var buf = BufferWriter().writeVarintBN(BN(Math.pow(2, 54).toString())).concat(); + var buf = BufferWriter().writeVarintBN(new BN(Math.pow(2, 54).toString())).concat(); var br = new BufferReader(buf); (function() { br.readVarintNum(); @@ -267,7 +267,7 @@ describe('BufferReader', function() { }); it('should not throw an error on a 9 byte varint not over the javascript uint precision limit', function() { - var buf = BufferWriter().writeVarintBN(BN(Math.pow(2, 53).toString())).concat(); + var buf = BufferWriter().writeVarintBN(new BN(Math.pow(2, 53).toString())).concat(); var br = new BufferReader(buf); (function() { br.readVarintNum(); diff --git a/test/encoding/bufferwriter.js b/test/encoding/bufferwriter.js index bc5bcc990..85ed3c158 100644 --- a/test/encoding/bufferwriter.js +++ b/test/encoding/bufferwriter.js @@ -106,7 +106,7 @@ describe('BufferWriter', function() { it('should write 1', function() { var bw = new BufferWriter(); - bw.writeUInt64BEBN(BN(1)).concat().toString('hex').should.equal('0000000000000001'); + bw.writeUInt64BEBN(new BN(1)).concat().toString('hex').should.equal('0000000000000001'); }); }); @@ -115,7 +115,7 @@ describe('BufferWriter', function() { it('should write 1', function() { var bw = new BufferWriter(); - bw.writeUInt64LEBN(BN(1)).concat().toString('hex').should.equal('0100000000000000'); + bw.writeUInt64LEBN(new BN(1)).concat().toString('hex').should.equal('0100000000000000'); }); }); @@ -161,25 +161,25 @@ describe('BufferWriter', function() { it('should write a 1 byte varint', function() { var bw = new BufferWriter(); - bw.writeVarintBN(BN(1)); + bw.writeVarintBN(new BN(1)); bw.concat().length.should.equal(1); }); it('should write a 3 byte varint', function() { var bw = new BufferWriter(); - bw.writeVarintBN(BN(1000)); + bw.writeVarintBN(new BN(1000)); bw.concat().length.should.equal(3); }); it('should write a 5 byte varint', function() { var bw = new BufferWriter(); - bw.writeVarintBN(BN(Math.pow(2, 16 + 1))); + bw.writeVarintBN(new BN(Math.pow(2, 16 + 1))); bw.concat().length.should.equal(5); }); it('should write a 9 byte varint', function() { var bw = new BufferWriter(); - bw.writeVarintBN(BN(Math.pow(2, 32 + 1))); + bw.writeVarintBN(new BN(Math.pow(2, 32 + 1))); bw.concat().length.should.equal(9); }); diff --git a/test/encoding/varint.js b/test/encoding/varint.js index 2ee6b2cd7..47e722c08 100644 --- a/test/encoding/varint.js +++ b/test/encoding/varint.js @@ -21,7 +21,7 @@ describe('Varint', function() { //various ways to use the constructor Varint(Varint(0).toBuffer()).toNumber().should.equal(0); Varint(0).toNumber().should.equal(0); - Varint(BN(0)).toNumber().should.equal(0); + Varint(new BN(0)).toNumber().should.equal(0); }); describe('#set', function() { @@ -80,7 +80,7 @@ describe('Varint', function() { describe('#fromBN', function() { it('should set a number', function() { - var varint = Varint().fromBN(BN(5)); + var varint = Varint().fromBN(new BN(5)); varint.toNumber().should.equal(5); }); @@ -109,7 +109,7 @@ describe('Varint', function() { it('should return a buffer', function() { var varint = Varint(5); - varint.toBN().toString().should.equal(BN(5).toString()); + varint.toBN().toString().should.equal(new BN(5).toString()); }); }); diff --git a/test/privatekey.js b/test/privatekey.js index 4450ffb5e..5751a3ad3 100644 --- a/test/privatekey.js +++ b/test/privatekey.js @@ -129,7 +129,7 @@ describe('PrivateKey', function() { it('should not be able to instantiate with unknown network', function() { expect(function() { - return new PrivateKey(BN(2), 'unknown'); + return new PrivateKey(new BN(2), 'unknown'); }).to.throw('Must specify the network ("livenet" or "testnet")'); }); @@ -288,7 +288,7 @@ describe('PrivateKey', function() { it('should set bn gt 0 and lt n, and should be compressed', function() { var privkey = PrivateKey.fromRandom(); - privkey.bn.gt(BN(0)).should.equal(true); + privkey.bn.gt(new BN(0)).should.equal(true); privkey.bn.lt(Point.getN()).should.equal(true); privkey.compressed.should.equal(true); }); @@ -336,7 +336,7 @@ describe('PrivateKey', function() { it('should convert this known PrivateKey to known PublicKey', function() { var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff'; var pubhex = '02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc'; - var privkey = new PrivateKey(BN(new Buffer(privhex, 'hex'))); + var privkey = new PrivateKey(new BN(new Buffer(privhex, 'hex'))); var pubkey = privkey.toPublicKey(); pubkey.toString().should.equal(pubhex); }); @@ -344,7 +344,7 @@ describe('PrivateKey', function() { it('should have a "publicKey" property', function() { var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff'; var pubhex = '02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc'; - var privkey = new PrivateKey(BN(new Buffer(privhex, 'hex'))); + var privkey = new PrivateKey(new BN(new Buffer(privhex, 'hex'))); privkey.publicKey.toString().should.equal(pubhex); }); diff --git a/test/publickey.js b/test/publickey.js index f778b5ca9..ffaed78a7 100644 --- a/test/publickey.js +++ b/test/publickey.js @@ -49,7 +49,7 @@ describe('PublicKey', function() { it('from a private key', function() { var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff'; var pubhex = '02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc'; - var privkey = new PrivateKey(BN(new Buffer(privhex, 'hex'))); + var privkey = new PrivateKey(new BN(new Buffer(privhex, 'hex'))); var pk = new PublicKey(privkey); pk.toString().should.equal(pubhex); }); diff --git a/test/script/interpreter.js b/test/script/interpreter.js index 3394c6807..5808a1836 100644 --- a/test/script/interpreter.js +++ b/test/script/interpreter.js @@ -46,7 +46,7 @@ Script.fromBitcoindString = function(str) { opcodenum = Opcode[opstr]; bw.writeUInt8(opcodenum); } else if (!isNaN(parseInt(token))) { - var script = Script().add(BN(token).toScriptNumBuffer()); + var script = Script().add(new BN(token).toScriptNumBuffer()); tbuf = script.toBuffer(); bw.write(tbuf); } else { @@ -77,21 +77,21 @@ describe('Interpreter', function() { describe('@castToBool', function() { it('should cast these bufs to bool correctly', function() { - Interpreter.castToBool(BN(0).toSM({ + Interpreter.castToBool(new BN(0).toSM({ endian: 'little' })).should.equal(false); Interpreter.castToBool(new Buffer('0080', 'hex')).should.equal(false); //negative 0 - Interpreter.castToBool(BN(1).toSM({ + Interpreter.castToBool(new BN(1).toSM({ endian: 'little' })).should.equal(true); - Interpreter.castToBool(BN(-1).toSM({ + Interpreter.castToBool(new BN(-1).toSM({ endian: 'little' })).should.equal(true); var buf = new Buffer('00', 'hex'); var bool = BN.fromSM(buf, { endian: 'little' - }).cmp(0) !== 0; + }).cmp(BN.Zero) !== 0; Interpreter.castToBool(buf).should.equal(bool); });