diff --git a/lib/crypto/ecdsa.js b/lib/crypto/ecdsa.js index a47845d..2b1081e 100644 --- a/lib/crypto/ecdsa.js +++ b/lib/crypto/ecdsa.js @@ -1,7 +1,6 @@ 'use strict'; var BN = require('./bn'); -var BufferReader = require('../encoding/bufferreader'); var Point = require('./point'); var Signature = require('./signature'); var PublicKey = require('../publickey'); diff --git a/lib/publickey.js b/lib/publickey.js index fba8b05..25bc52d 100644 --- a/lib/publickey.js +++ b/lib/publickey.js @@ -1,12 +1,12 @@ 'use strict'; -var _ = require('lodash'); var Address = require('./address'); var BN = require('./crypto/bn'); var Point = require('./crypto/point'); var JSUtil = require('./util/js'); var Network = require('./networks'); var _ = require('lodash'); +var $ = require('./util/preconditions'); /** * Instantiate a PublicKey from a 'PrivateKey', 'Point', 'string', 'Buffer'. @@ -34,9 +34,9 @@ var PublicKey = function PublicKey(data, extra) { if (!(this instanceof PublicKey)) { return new PublicKey(data, extra); } - if (!data) { - throw new TypeError('First argument is required, please include public key data.'); - } + + $.checkArgument(data, new TypeError('First argument is required, please include public key data.')); + if (data instanceof PublicKey) { // Return copy, but as it's an immutable object, return same argument return data; @@ -62,7 +62,7 @@ var PublicKey = function PublicKey(data, extra) { } else { throw new TypeError('First argument is an unrecognized data format.'); } - + // validation info.point.validate(); @@ -93,7 +93,8 @@ var PublicKey = function PublicKey(data, extra) { * @private */ PublicKey._isPrivateKey = function(param) { - return param && param.constructor && param.constructor.name && param.constructor.name === 'PrivateKey'; + var PrivateKey = require('./privatekey'); + return param instanceof PrivateKey; }; /** @@ -126,10 +127,9 @@ PublicKey._isJSON = function(json) { * @private */ PublicKey._transformPrivateKey = function(privkey) { + $.checkArgument(PublicKey._isPrivateKey(privkey), + new TypeError('Must be an instance of PrivateKey')); var info = {}; - if (!PublicKey._isPrivateKey(privkey)) { - throw new TypeError('Must be an instance of PrivateKey'); - } info.point = Point.getG().mul(privkey.bn); info.compressed = privkey.compressed; info.network = privkey.network; @@ -145,10 +145,8 @@ PublicKey._transformPrivateKey = function(privkey) { * @private */ PublicKey._transformDER = function(buf, strict) { + $.checkArgument(PublicKey._isBuffer(buf), new TypeError('Must be a hex buffer of DER encoded public key')); var info = {}; - if (!PublicKey._isBuffer(buf)) { - throw new TypeError('Must be a hex buffer of DER encoded public key'); - } strict = _.isUndefined(strict) ? true : strict; @@ -192,10 +190,9 @@ PublicKey._transformDER = function(buf, strict) { * @private */ PublicKey._transformX = function(odd, x) { + $.checkArgument(typeof odd === 'boolean', + new TypeError('Must specify whether y is odd or not (true or false)')); var info = {}; - if (typeof odd !== 'boolean') { - throw new TypeError('Must specify whether y is odd or not (true or false)'); - } info.point = Point.fromX(odd, x); return info; }; @@ -207,10 +204,8 @@ PublicKey._transformX = function(odd, x) { * @returns {PublicKey} A new valid instance of PublicKey */ PublicKey.fromJSON = function(json) { - if (!PublicKey._isJSON(json)) { - throw new TypeError('Must be a valid JSON string or plain object'); - } - + $.checkArgument(PublicKey._isJSON(json), + new TypeError('Must be a valid JSON string or plain object')); return new PublicKey(json); }; @@ -240,9 +235,7 @@ PublicKey._transformJSON = function(json) { * @returns {PublicKey} A new valid instance of PublicKey */ PublicKey.fromPrivateKey = function(privkey) { - if (!PublicKey._isPrivateKey(privkey)) { - throw new TypeError('Must be an instance of PrivateKey'); - } + $.checkArgument(PublicKey._isPrivateKey(privkey), new TypeError('Must be an instance of PrivateKey')); var info = PublicKey._transformPrivateKey(privkey); return new PublicKey(info.point, { compressed: info.compressed, @@ -256,10 +249,9 @@ PublicKey.fromPrivateKey = function(privkey) { * @param {bool} [strict] - if set to false, will loosen some conditions * @returns {PublicKey} A new valid instance of PublicKey */ -PublicKey.fromBuffer = function(buf, strict) { - if (!PublicKey._isBuffer(buf)) { - throw new TypeError('Must be a hex buffer of DER encoded public key'); - } +PublicKey.fromDER = PublicKey.fromBuffer = function(buf, strict) { + $.checkArgument(PublicKey._isBuffer(buf), + new TypeError('Must be a hex buffer of DER encoded public key')); var info = PublicKey._transformDER(buf, strict); return new PublicKey(info.point, { compressed: info.compressed @@ -274,28 +266,13 @@ PublicKey.fromBuffer = function(buf, strict) { * @returns {PublicKey} A new valid instance of PublicKey */ PublicKey.fromPoint = function(point, compressed) { - if (!(point instanceof Point)) { - throw new TypeError('First argument must be an instance of Point.'); - } + $.checkArgument(point instanceof Point, + new TypeError('First argument must be an instance of Point.')); return new PublicKey(point, { compressed: compressed }); }; -/** - * Instantiate a PublicKey from a DER Buffer - * - * @param {Buffer} buf - A DER Buffer - * @param {bool} [strict] - if set to false, will loosen some conditions - * @returns {PublicKey} A new valid instance of PublicKey - */ -PublicKey.fromDER = function(buf, strict) { - var info = PublicKey._transformDER(buf, strict); - return new PublicKey(info.point, { - compressed: info.compressed - }); -}; - /** * Instantiate a PublicKey from a DER hex encoded string * diff --git a/lib/script.js b/lib/script.js index 4b374eb..073be1d 100644 --- a/lib/script.js +++ b/lib/script.js @@ -268,7 +268,7 @@ Script.prototype.isScriptHashOut = function() { return (buf.length === 23 && buf[0] === Opcode.OP_HASH160 && buf[1] === 0x14 && - buf[22] === Opcode.OP_EQUAL); + buf[buf.length - 1] === Opcode.OP_EQUAL); }; /** @@ -526,7 +526,9 @@ Script.buildMultisigOut = function(pubkeys, m, opts) { opts = opts || {}; var s = new Script(); s.add(Opcode.smallInt(m)); - pubkeys = _.map(pubkeys, function(pubkey) { return PublicKey(pubkey); }); + pubkeys = _.map(pubkeys, function(pubkey) { + return PublicKey(pubkey); + }); var sorted = pubkeys; if (!opts.noSorting) { sorted = _.sortBy(pubkeys, function(pubkey) { @@ -552,7 +554,7 @@ Script.buildMultisigOut = function(pubkeys, m, opts) { * @param {boolean=false} opts.noSorting don't sort the given public keys before creating the script * @param {Script=} opts.cachedMultisig don't recalculate the redeemScript * - * @returns Script + * @returns Script */ Script.buildP2SHMultisigIn = function(pubkeys, threshold, signatures, opts) { opts = opts || {}; diff --git a/test/crypto/signature.js b/test/crypto/signature.js index 7954c23..f9f3da5 100644 --- a/test/crypto/signature.js +++ b/test/crypto/signature.js @@ -41,7 +41,7 @@ describe('Signature', function() { blank, blank ]); - var sig = new Signature.fromCompact(compressed); + var sig = Signature.fromCompact(compressed); sig.r.cmp(0).should.equal(0); sig.s.cmp(0).should.equal(0); }); @@ -53,7 +53,7 @@ describe('Signature', function() { var buf = new Buffer('3044022075fc517e541bd54769c080b64397e32161c850f6c1b2b67a5c433affbb3e62770220729e85cc46ffab881065ec07694220e71d4df9b2b8c8fd12c3122cf3a5efbcf2', 'hex'); it('should parse this DER format signature', function() { - var sig = new Signature.fromDER(buf); + var sig = Signature.fromDER(buf); sig.r.toBuffer({ size: 32 }).toString('hex').should.equal('75fc517e541bd54769c080b64397e32161c850f6c1b2b67a5c433affbb3e6277'); @@ -69,7 +69,7 @@ describe('Signature', function() { var buf = new Buffer('3044022075fc517e541bd54769c080b64397e32161c850f6c1b2b67a5c433affbb3e62770220729e85cc46ffab881065ec07694220e71d4df9b2b8c8fd12c3122cf3a5efbcf2', 'hex'); it('should parse this DER format signature in hex', function() { - var sig = new Signature.fromString(buf.toString('hex')); + var sig = Signature.fromString(buf.toString('hex')); sig.r.toBuffer({ size: 32 }).toString('hex').should.equal('75fc517e541bd54769c080b64397e32161c850f6c1b2b67a5c433affbb3e6277'); diff --git a/test/script.js b/test/script.js index 50c2fec..0de98b9 100644 --- a/test/script.js +++ b/test/script.js @@ -18,7 +18,7 @@ describe('Script', function() { it('should parse this buffer containing an OP code', function() { var buf = new Buffer(1); - buf[0] = Opcode('OP_0').toNumber(); + buf[0] = Opcode.OP_0; var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); script.chunks[0].opcodenum.should.equal(buf[0]); @@ -26,7 +26,7 @@ describe('Script', function() { it('should parse this buffer containing another OP code', function() { var buf = new Buffer(1); - buf[0] = Opcode('OP_CHECKMULTISIG').toNumber(); + buf[0] = Opcode.OP_CHECKMULTISIG; var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); script.chunks[0].opcodenum.should.equal(buf[0]); @@ -41,7 +41,7 @@ describe('Script', function() { it('should parse this buffer containing OP_PUSHDATA1 and three bytes of data', function() { var buf = new Buffer([0, 0, 1, 2, 3]); - buf[0] = Opcode('OP_PUSHDATA1').toNumber(); + buf[0] = Opcode.OP_PUSHDATA1; buf.writeUInt8(3, 1); var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); @@ -50,7 +50,7 @@ describe('Script', function() { it('should parse this buffer containing OP_PUSHDATA2 and three bytes of data', function() { var buf = new Buffer([0, 0, 0, 1, 2, 3]); - buf[0] = Opcode('OP_PUSHDATA2').toNumber(); + buf[0] = Opcode.OP_PUSHDATA2; buf.writeUInt16LE(3, 1); var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); @@ -59,7 +59,7 @@ describe('Script', function() { it('should parse this buffer containing OP_PUSHDATA4 and three bytes of data', function() { var buf = new Buffer([0, 0, 0, 0, 0, 1, 2, 3]); - buf[0] = Opcode('OP_PUSHDATA4').toNumber(); + buf[0] = Opcode.OP_PUSHDATA4; buf.writeUInt16LE(3, 1); var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); @@ -68,10 +68,10 @@ describe('Script', function() { it('should parse this buffer an OP code, data, and another OP code', function() { var buf = new Buffer([0, 0, 0, 0, 0, 0, 1, 2, 3, 0]); - buf[0] = Opcode('OP_0').toNumber(); - buf[1] = Opcode('OP_PUSHDATA4').toNumber(); + buf[0] = Opcode.OP_0; + buf[1] = Opcode.OP_PUSHDATA4; buf.writeUInt16LE(3, 2); - buf[buf.length - 1] = Opcode('OP_0').toNumber(); + buf[buf.length - 1] = Opcode.OP_0; var script = Script.fromBuffer(buf); script.chunks.length.should.equal(3); script.chunks[0].opcodenum.should.equal(buf[0]); @@ -85,7 +85,7 @@ describe('Script', function() { it('should output this buffer containing an OP code', function() { var buf = new Buffer(1); - buf[0] = Opcode('OP_0').toNumber(); + buf[0] = Opcode.OP_0; var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); script.chunks[0].opcodenum.should.equal(buf[0]); @@ -94,7 +94,7 @@ describe('Script', function() { it('should output this buffer containing another OP code', function() { var buf = new Buffer(1); - buf[0] = Opcode('OP_CHECKMULTISIG').toNumber(); + buf[0] = Opcode.OP_CHECKMULTISIG; var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); script.chunks[0].opcodenum.should.equal(buf[0]); @@ -111,7 +111,7 @@ describe('Script', function() { it('should output this buffer containing OP_PUSHDATA1 and three bytes of data', function() { var buf = new Buffer([0, 0, 1, 2, 3]); - buf[0] = Opcode('OP_PUSHDATA1').toNumber(); + buf[0] = Opcode.OP_PUSHDATA1; buf.writeUInt8(3, 1); var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); @@ -121,7 +121,7 @@ describe('Script', function() { it('should output this buffer containing OP_PUSHDATA2 and three bytes of data', function() { var buf = new Buffer([0, 0, 0, 1, 2, 3]); - buf[0] = Opcode('OP_PUSHDATA2').toNumber(); + buf[0] = Opcode.OP_PUSHDATA2; buf.writeUInt16LE(3, 1); var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); @@ -131,7 +131,7 @@ describe('Script', function() { it('should output this buffer containing OP_PUSHDATA4 and three bytes of data', function() { var buf = new Buffer([0, 0, 0, 0, 0, 1, 2, 3]); - buf[0] = Opcode('OP_PUSHDATA4').toNumber(); + buf[0] = Opcode.OP_PUSHDATA4; buf.writeUInt16LE(3, 1); var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); @@ -141,10 +141,10 @@ describe('Script', function() { it('should output this buffer an OP code, data, and another OP code', function() { var buf = new Buffer([0, 0, 0, 0, 0, 0, 1, 2, 3, 0]); - buf[0] = Opcode('OP_0').toNumber(); - buf[1] = Opcode('OP_PUSHDATA4').toNumber(); + buf[0] = Opcode.OP_0; + buf[1] = Opcode.OP_PUSHDATA4; buf.writeUInt16LE(3, 2); - buf[buf.length - 1] = Opcode('OP_0').toNumber(); + buf[buf.length - 1] = Opcode.OP_0; var script = Script.fromBuffer(buf); script.chunks.length.should.equal(3); script.chunks[0].opcodenum.should.equal(buf[0]); @@ -175,10 +175,10 @@ describe('Script', function() { it('should output this buffer an OP code, data, and another OP code', function() { var buf = new Buffer([0, 0, 0, 0, 0, 0, 1, 2, 3, 0]); - buf[0] = Opcode('OP_0').toNumber(); - buf[1] = Opcode('OP_PUSHDATA4').toNumber(); + buf[0] = Opcode.OP_0; + buf[1] = Opcode.OP_PUSHDATA4; buf.writeUInt16LE(3, 2); - buf[buf.length - 1] = Opcode('OP_0').toNumber(); + buf[buf.length - 1] = Opcode.OP_0; var script = Script.fromBuffer(buf); script.chunks.length.should.equal(3); script.chunks[0].opcodenum.should.equal(buf[0]); @@ -352,7 +352,7 @@ describe('Script', function() { Script().add(1000).toString().should.equal('0x03e8'); Script().add('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG'); Script().add('OP_1').add('OP_2').toString().should.equal('OP_1 OP_2'); - Script().add(new Opcode('OP_CHECKMULTISIG')).toString().should.equal('OP_CHECKMULTISIG'); + Script().add(Opcode.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG'); Script().add(Opcode.map.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG'); }); @@ -390,7 +390,7 @@ describe('Script', function() { }); it('should work for no data OP_RETURN', function() { - Script().add(Opcode('OP_RETURN')).add(new Buffer('')).toString().should.equal('OP_RETURN 0'); + Script().add(Opcode.OP_RETURN).add(new Buffer('')).toString().should.equal('OP_RETURN 0'); }); });