diff --git a/src/message.js b/src/message.js index 998c751..9582dec 100644 --- a/src/message.js +++ b/src/message.js @@ -5,33 +5,28 @@ var convert = require('./convert') var ecdsa = require('./ecdsa') var SHA256 = require('crypto-js/sha256') -var Message = {} +// FIXME: magicHash is incompatible with other magic messages +var magicBytes = convert.stringToBytes('Bitcoin Signed Message:\n') -Message.magicPrefix = "Bitcoin Signed Message:\n" - -Message.makeMagicMessage = function (message) { - var magicBytes = convert.stringToBytes(Message.magicPrefix) +function magicHash(message) { var messageBytes = convert.stringToBytes(message) - return [].concat( + var buffer = [].concat( convert.numToVarInt(magicBytes.length), magicBytes, convert.numToVarInt(messageBytes.length), messageBytes ) -} - -Message.getHash = function (message) { - var buffer = Message.makeMagicMessage(message) return convert.wordArrayToBytes(SHA256(SHA256(convert.bytesToWordArray(buffer)))) } -Message.signMessage = function (key, message) { - var hash = Message.getHash(message) +// TODO: parameterize compression instead of using ECKey.compressed +function sign(key, message) { + var hash = magicHash(message) var sig = key.sign(hash) var obj = ecdsa.parseSig(sig) - var i = ecdsa.calcPubkeyRecoveryParam(key, obj.r, obj.s, hash) + var i = ecdsa.calcPubkeyRecoveryParam(key.getPub(), obj.r, obj.s, hash) i += 27 if (key.compressed) { @@ -50,18 +45,21 @@ Message.signMessage = function (key, message) { return convert.bytesToHex(sig) } -Message.verifyMessage = function (address, sig, message) { +function verify(address, sig, message) { + address = new Address(address) sig = ecdsa.parseSigCompact(convert.hexToBytes(sig)) - var hash = Message.getHash(message) - var isCompressed = !!(sig.i & 4) + var hash = magicHash(message) + var pubKey = ecdsa.recoverPubKey(sig.r, sig.s, hash, sig.i) pubKey.compressed = isCompressed - // Compare address to expected address - address = new Address(address) - return address.toString() === pubKey.getAddress(address.version).toString() + return pubKey.getAddress(address.version).toString() === address.toString() } -module.exports = Message +module.exports = { + magicHash: magicHash, + sign: sign, + verify: verify +} diff --git a/test/message.js b/test/message.js index 6d6a07a..ef60c9c 100644 --- a/test/message.js +++ b/test/message.js @@ -5,17 +5,13 @@ var ECKey = require('../src/eckey').ECKey var testnet = require('../src/network.js').testnet.addressVersion describe('Message', function() { - var msg + var msg = 'vires is numeris' - beforeEach(function(){ - msg = 'vires is numeris' - }) - - describe('verifyMessage', function(){ + describe('verify', function(){ it('works for mainnet address, messaged signed with uncompressed key', function() { var addr = '16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM'; var sig = '1bc25ac0fb503abc9bad23f558742740fafaec1f52deaaf106b9759a5ce84c93921c4a669c5ec3dfeb7e2d7d177a2f49db407900874f6de2f701a4c16783776d8d' - assert.ok(Message.verifyMessage(addr, sig, msg)); + assert.ok(Message.verify(addr, sig, msg)); verifyNegativeCases(addr, sig, msg) }) @@ -23,47 +19,47 @@ describe('Message', function() { var addr = 'mgdnNWji2bXYSi7E9c1DQBSp64kCemaS7V' var sig = '1feece860e952253ddf465cd1c5aea76ab16287aee093be6f67d196c39f5075436f0407a4e50694e6956c06108fab8608debf9554d75e57c110f7c512a6eb15d0a' - assert(Message.verifyMessage(addr, sig, msg)) + assert(Message.verify(addr, sig, msg)) verifyNegativeCases(addr, sig, msg) }) function verifyNegativeCases(addr, sig, msg){ var wrongMsg = 'vires in numeris' - assert.ok(!Message.verifyMessage(addr, sig, wrongMsg)); + assert.ok(!Message.verify(addr, sig, wrongMsg)); var wrongAddress = new ECKey(null).getAddress() - assert.ok(!Message.verifyMessage(wrongAddress, sig, msg)); + assert.ok(!Message.verify(wrongAddress, sig, msg)); } }) - describe('signMessage', function() { + describe('sign', function() { describe('uncompressed key', function(){ it('works', function(){ var key = new ECKey(null) - var sig = Message.signMessage(key, msg); + var sig = Message.sign(key, msg); var addr = key.getAddress() - assert(Message.verifyMessage(addr, sig, msg)); + assert(Message.verify(addr, sig, msg)); }) }) describe('compressed key', function(){ it('works', function(){ var key = new ECKey(null, true) - var sig = Message.signMessage(key, msg); + var sig = Message.sign(key, msg); var addr = key.getAddress() - assert(Message.verifyMessage(addr, sig, msg)); + assert(Message.verify(addr, sig, msg)); }) }) describe('testnet address', function(){ it('works', function(){ var key = new ECKey(null) - var sig = Message.signMessage(key, msg); + var sig = Message.sign(key, msg); var addr = key.getAddress(testnet) - assert(Message.verifyMessage(addr, sig, msg)); + assert(Message.verify(addr, sig, msg)); }) }) })