Skip to content

Commit

Permalink
Merge pull request #2 from maraoz/standardize
Browse files Browse the repository at this point in the history
Use standard precondition checks
  • Loading branch information
eordano committed Feb 10, 2015
2 parents 0f882ec + 549a6c2 commit 3347622
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 29 deletions.
40 changes: 20 additions & 20 deletions lib/message.js
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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), 'First argument should be a string');
this.message = message;

return this;
Expand All @@ -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,
'First argument should be an instance of PrivateKey');
var hash = this.magicHash();
var ecdsa = new ECDSA();
ecdsa.hashbuf = hash;
Expand All @@ -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
*/
Expand All @@ -65,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) {
Expand All @@ -82,12 +77,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
Expand All @@ -96,11 +97,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;
}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
22 changes: 14 additions & 8 deletions test/message.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('../');

Expand All @@ -24,9 +25,9 @@ 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(TypeError);
}).to.throw('First argument should be a string');
});

it('will instantiate without "new"', function() {
Expand All @@ -46,10 +47,10 @@ 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(TypeError);
}).to.throw('First argument should be an instance of PrivateKey');
});

it('can verify a message with signature', function() {
Expand All @@ -65,17 +66,17 @@ 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);
}).to.throw('First argument should be an instance of PublicKey');
});

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);
}).to.throw('Second argument should be an instance of Signature');
});

it('verify will correctly identify a bad signature', function() {
Expand Down Expand Up @@ -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);
});

});

0 comments on commit 3347622

Please sign in to comment.