From cdd4df3cb394392c1911c9ba1a249c1885219e93 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Thu, 5 Feb 2015 11:06:32 -0300 Subject: [PATCH 1/3] Use standard precondition checks --- lib/message.js | 32 ++++++++++++++++++-------------- package.json | 3 ++- test/message.js | 4 ++-- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/lib/message.js b/lib/message.js index d370fc7..d020181 100644 --- a/lib/message.js +++ b/lib/message.js @@ -1,6 +1,7 @@ 'use strict'; var bitcore = require('bitcore'); +var _ = require('lodash'); var PrivateKey = bitcore.PrivateKey; var PublicKey = bitcore.PublicKey; var Address = bitcore.Address; @@ -9,20 +10,19 @@ var ECDSA = bitcore.crypto.ECDSA; var Signature = bitcore.crypto.Signature; var sha256sha256 = bitcore.crypto.Hash.sha256sha256; var JSUtil = bitcore.util.js; +var $ = bitcore.util.preconditions; /** - * Will construct a new message to sign and verify. - * + * constructs a new message to sign and verify. + * * @param {String} message * @returns {Message} */ var Message = function Message(message) { if (!(this instanceof Message)) { return new Message(message); - } - if (typeof message !== 'string') { - throw new TypeError('First argument should be a string'); } + $.checkArgument(_.isString(message), new TypeError('First argument should be a string')); this.message = message; return this; @@ -40,9 +40,8 @@ Message.prototype.magicHash = function magicHash() { }; Message.prototype._sign = function _sign(privateKey) { - if (!(privateKey instanceof PrivateKey)) { - throw new TypeError('First argument should be an instance of PrivateKey'); - } + $.checkArgument(privateKey instanceof PrivateKey, + new TypeError('First argument should be an instance of PrivateKey')); var hash = this.magicHash(); var ecdsa = new ECDSA(); ecdsa.hashbuf = hash; @@ -55,7 +54,7 @@ Message.prototype._sign = function _sign(privateKey) { /** * Will sign a message with a given bitcoin private key. - * + * * @param {PrivateKey} privateKey - An instance of PrivateKey * @returns {String} A base64 encoded compact signature */ @@ -82,12 +81,18 @@ Message.prototype._verify = function _verify(publicKey, signature) { /** * Will return a boolean of the signature is valid for a given bitcoin address. * If it isn't the specific reason is accessible via the "error" member. - * - * @param {String} bitcoinAddress - A bitcoin address + * + * @param {Address|String} bitcoinAddress - A bitcoin address * @param {String} signatureString - A base64 encoded compact signature * @returns {Boolean} */ Message.prototype.verify = function verify(bitcoinAddress, signatureString) { + $.checkArgument(bitcoinAddress); + $.checkArgument(signatureString && _.isString(signatureString)); + + if (_.isString(bitcoinAddress)) { + bitcoinAddress = Address.fromString(bitcoinAddress); + } var signature = Signature.fromCompact(new Buffer(signatureString, 'base64')); // recover the public key @@ -96,11 +101,10 @@ Message.prototype.verify = function verify(bitcoinAddress, signatureString) { ecdsa.sig = signature; var publicKey = ecdsa.toPublicKey(); - var expectedAddress = Address.fromString(bitcoinAddress); - var signatureAddress = Address.fromPublicKey(publicKey, expectedAddress.network); + var signatureAddress = Address.fromPublicKey(publicKey, bitcoinAddress.network); // check that the recovered address and specified address match - if (expectedAddress.toString() !== signatureAddress.toString()) { + if (bitcoinAddress.toString() !== signatureAddress.toString()) { this.error = 'The signature did not match the message digest'; return false; } diff --git a/package.json b/package.json index 422912b..460b6aa 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "url": "https://github.com/bitpay/bitcore-message.git" }, "dependencies": { - "bitcore": "^0.9.4" + "bitcore": "^0.9.4", + "lodash": "^3.1.0" }, "devDependencies": { "bitcore-build": "bitpay/bitcore-build", diff --git a/test/message.js b/test/message.js index 6143b8e..6632bce 100644 --- a/test/message.js +++ b/test/message.js @@ -26,7 +26,7 @@ describe('Message', function() { it('will error with incorrect message type', function() { expect(function(){ return new Message(new Date()); - }).to.throw(TypeError); + }).to.throw('First argument should be a string'); }); it('will instantiate without "new"', function() { @@ -49,7 +49,7 @@ describe('Message', function() { expect(function(){ var message3 = new Message(text); return message3.sign('not a private key'); - }).to.throw(TypeError); + }).to.throw('First argument should be an instance of PrivateKey'); }); it('can verify a message with signature', function() { From d632bbb4cd4cab991b26c6b77d46f68ae605f4af Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Thu, 5 Feb 2015 11:09:30 -0300 Subject: [PATCH 2/3] add Address parameter test --- test/message.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/message.js b/test/message.js index 6632bce..6a2f48c 100644 --- a/test/message.js +++ b/test/message.js @@ -5,6 +5,7 @@ var expect = chai.expect; var should = chai.should(); var bitcore = require('bitcore'); +var Address = bitcore.Address; var Signature = bitcore.crypto.Signature; var Message = require('../'); @@ -24,7 +25,7 @@ describe('Message', function() { var publicKey = privateKey.toPublicKey(); it('will error with incorrect message type', function() { - expect(function(){ + expect(function() { return new Message(new Date()); }).to.throw('First argument should be a string'); }); @@ -46,7 +47,7 @@ describe('Message', function() { }); it('sign will error with incorrect private key argument', function() { - expect(function(){ + expect(function() { var message3 = new Message(text); return message3.sign('not a private key'); }).to.throw('First argument should be an instance of PrivateKey'); @@ -65,14 +66,14 @@ describe('Message', function() { }); it('verify will error with incorrect public key argument', function() { - expect(function(){ + expect(function() { var message6 = new Message(text); return message6._verify('not a public key', signature); }).to.throw(TypeError); }); it('verify will error with incorrect signature argument', function() { - expect(function(){ + expect(function() { var message7 = new Message(text); return message7._verify(publicKey, 'not a signature'); }).to.throw(TypeError); @@ -146,5 +147,10 @@ describe('Message', function() { }); + it('accepts Address for verification', function() { + var verified = Message(text) + .verify(new Address(address), signatureString); + verified.should.equal(true); + }); }); From 549a6c2116d6c201f8ef91d808ab9cad5e77804b Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Thu, 5 Feb 2015 11:53:13 -0300 Subject: [PATCH 3/3] remove extra Error --- lib/message.js | 12 ++++-------- test/message.js | 4 ++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/message.js b/lib/message.js index d020181..f9433c6 100644 --- a/lib/message.js +++ b/lib/message.js @@ -22,7 +22,7 @@ var Message = function Message(message) { if (!(this instanceof Message)) { return new Message(message); } - $.checkArgument(_.isString(message), new TypeError('First argument should be a string')); + $.checkArgument(_.isString(message), 'First argument should be a string'); this.message = message; return this; @@ -41,7 +41,7 @@ Message.prototype.magicHash = function magicHash() { Message.prototype._sign = function _sign(privateKey) { $.checkArgument(privateKey instanceof PrivateKey, - new TypeError('First argument should be an instance of PrivateKey')); + 'First argument should be an instance of PrivateKey'); var hash = this.magicHash(); var ecdsa = new ECDSA(); ecdsa.hashbuf = hash; @@ -64,12 +64,8 @@ Message.prototype.sign = function sign(privateKey) { }; Message.prototype._verify = function _verify(publicKey, signature) { - if (!(publicKey instanceof PublicKey)) { - throw new TypeError('First argument should be an instance of PublicKey'); - } - if (!(signature instanceof Signature)) { - throw new TypeError('Second argument should be an instance of Signature'); - } + $.checkArgument(publicKey instanceof PublicKey, 'First argument should be an instance of PublicKey'); + $.checkArgument(signature instanceof Signature, 'Second argument should be an instance of Signature'); var hash = this.magicHash(); var verified = ECDSA.verify(hash, signature, publicKey); if (!verified) { diff --git a/test/message.js b/test/message.js index 6a2f48c..7a51985 100644 --- a/test/message.js +++ b/test/message.js @@ -69,14 +69,14 @@ describe('Message', function() { expect(function() { var message6 = new Message(text); return message6._verify('not a public key', signature); - }).to.throw(TypeError); + }).to.throw('First argument should be an instance of PublicKey'); }); it('verify will error with incorrect signature argument', function() { expect(function() { var message7 = new Message(text); return message7._verify(publicKey, 'not a signature'); - }).to.throw(TypeError); + }).to.throw('Second argument should be an instance of Signature'); }); it('verify will correctly identify a bad signature', function() {