port message to common.js style and add tests
This commit is contained in:
parent
981203e982
commit
41f0027883
4 changed files with 59 additions and 24 deletions
28
src/ecdsa.js
28
src/ecdsa.js
|
@ -70,7 +70,7 @@ var ECDSA = {
|
|||
r = sig.r;
|
||||
s = sig.s;
|
||||
} else {
|
||||
throw "Invalid value for signature";
|
||||
throw new Error("Invalid value for signature");
|
||||
}
|
||||
|
||||
var Q;
|
||||
|
@ -79,7 +79,7 @@ var ECDSA = {
|
|||
} else if (util.isArray(pubkey)) {
|
||||
Q = ECPointFp.decodeFrom(ecparams.getCurve(), pubkey);
|
||||
} else {
|
||||
throw "Invalid format for pubkey value, must be byte array or ECPointFp";
|
||||
throw new Error("Invalid format for pubkey value, must be byte array or ECPointFp");
|
||||
}
|
||||
var e = BigInteger.fromByteArrayUnsigned(hash);
|
||||
|
||||
|
@ -176,14 +176,14 @@ var ECDSA = {
|
|||
|
||||
parseSigCompact: function (sig) {
|
||||
if (sig.length !== 65) {
|
||||
throw "Signature has the wrong length";
|
||||
throw new Error("Signature has the wrong length");
|
||||
}
|
||||
|
||||
// Signature is prefixed with a type byte storing three bits of
|
||||
// information.
|
||||
var i = sig[0] - 27;
|
||||
if (i < 0 || i > 7) {
|
||||
throw "Invalid signature type";
|
||||
throw new Error("Invalid signature type");
|
||||
}
|
||||
|
||||
var n = ecparams.getN();
|
||||
|
@ -253,10 +253,13 @@ var ECDSA = {
|
|||
|
||||
Q.validate();
|
||||
if (!ECDSA.verifyRaw(e, r, s, Q)) {
|
||||
throw "Pubkey recovery unsuccessful";
|
||||
throw new Error("Pubkey recovery unsuccessful");
|
||||
}
|
||||
|
||||
var pubKey = new Bitcoin.ECKey();
|
||||
// TODO (shtylman) this is stupid because this file and eckey
|
||||
// have circular dependencies
|
||||
var ECKey = require('./eckey');
|
||||
var pubKey = ECKey();
|
||||
pubKey.pub = Q;
|
||||
return pubKey;
|
||||
},
|
||||
|
@ -275,14 +278,13 @@ var ECDSA = {
|
|||
calcPubkeyRecoveryParam: function (address, r, s, hash)
|
||||
{
|
||||
for (var i = 0; i < 4; i++) {
|
||||
try {
|
||||
var pubkey = Bitcoin.ECDSA.recoverPubKey(r, s, hash, i);
|
||||
if (pubkey.getBitcoinAddress().toString() == address) {
|
||||
return i;
|
||||
}
|
||||
} catch (e) {}
|
||||
var pubkey = ECDSA.recoverPubKey(r, s, hash, i);
|
||||
if (pubkey.getBitcoinAddress().toString() == address) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw "Unable to find valid recovery factor";
|
||||
|
||||
throw new Error("Unable to find valid recovery factor");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ var endian = function (n) {
|
|||
module.exports = {
|
||||
Address: require('./address'),
|
||||
Key: require('./eckey'),
|
||||
Message: require('./message'),
|
||||
BigInteger: require('./jsbn/jsbn'),
|
||||
Script: require('./script'),
|
||||
Opcode: require('./opcode'),
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
/**
|
||||
* Implements Bitcoin's feature for signing arbitrary messages.
|
||||
*/
|
||||
/// Implements Bitcoin's feature for signing arbitrary messages.
|
||||
|
||||
var Crypto = require('./crypto-js/crypto');
|
||||
var ecdsa = require('./ecdsa');
|
||||
var conv = require('./convert');
|
||||
var util = require('./util');
|
||||
|
||||
var Message = {};
|
||||
|
||||
Message.magicPrefix = "Bitcoin Signed Message:\n";
|
||||
|
@ -10,9 +14,9 @@ Message.makeMagicMessage = function (message) {
|
|||
var messageBytes = Crypto.charenc.UTF8.stringToBytes(message);
|
||||
|
||||
var buffer = [];
|
||||
buffer = buffer.concat(Bitcoin.Util.numToVarInt(magicBytes.length));
|
||||
buffer = buffer.concat(util.numToVarInt(magicBytes.length));
|
||||
buffer = buffer.concat(magicBytes);
|
||||
buffer = buffer.concat(Bitcoin.Util.numToVarInt(messageBytes.length));
|
||||
buffer = buffer.concat(util.numToVarInt(messageBytes.length));
|
||||
buffer = buffer.concat(messageBytes);
|
||||
|
||||
return buffer;
|
||||
|
@ -28,10 +32,10 @@ Message.signMessage = function (key, message, compressed) {
|
|||
|
||||
var sig = key.sign(hash);
|
||||
|
||||
var obj = Bitcoin.ECDSA.parseSig(sig);
|
||||
var obj = ecdsa.parseSig(sig);
|
||||
|
||||
var address = key.getBitcoinAddress().toString();
|
||||
var i = Bitcoin.ECDSA.calcPubkeyRecoveryParam(address, obj.r, obj.s, hash);
|
||||
var i = ecdsa.calcPubkeyRecoveryParam(address, obj.r, obj.s, hash);
|
||||
|
||||
i += 27;
|
||||
if (compressed) i += 4;
|
||||
|
@ -45,17 +49,17 @@ Message.signMessage = function (key, message, compressed) {
|
|||
|
||||
sig = [i].concat(rBa).concat(sBa);
|
||||
|
||||
return Crypto.util.bytesToBase64(sig);
|
||||
return conv.bytesToBase64(sig);
|
||||
};
|
||||
|
||||
Message.verifyMessage = function (address, sig, message) {
|
||||
sig = Crypto.util.base64ToBytes(sig);
|
||||
sig = Bitcoin.ECDSA.parseSigCompact(sig);
|
||||
sig = conv.base64ToBytes(sig);
|
||||
sig = ecdsa.parseSigCompact(sig);
|
||||
|
||||
var hash = Message.getHash(message);
|
||||
|
||||
var isCompressed = !!(sig.i & 4);
|
||||
var pubKey = Bitcoin.ECDSA.recoverPubKey(sig.r, sig.s, hash, sig.i);
|
||||
var pubKey = ecdsa.recoverPubKey(sig.r, sig.s, hash, sig.i);
|
||||
|
||||
pubKey.setCompressed(isCompressed);
|
||||
|
||||
|
|
28
test/message.js
Normal file
28
test/message.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
var assert = require('assert');
|
||||
var Message = require('../').Message;
|
||||
var Key = require('../').Key;
|
||||
var hexToBytes = require('../').convert.hexToBytes;
|
||||
|
||||
var priv = '18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725';
|
||||
var addr = '16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM';
|
||||
var msg = 'foobar';
|
||||
|
||||
test('create', function() {
|
||||
var key = Key(hexToBytes(priv));
|
||||
assert.equal(key.getBitcoinAddress().toString(), addr);
|
||||
|
||||
var sig = Message.signMessage(key, msg);
|
||||
assert.ok(Message.verifyMessage(addr, sig, msg));
|
||||
// wrong message
|
||||
assert.ok(!Message.verifyMessage(addr, sig, 'not foobar'));
|
||||
// wrong address
|
||||
assert.ok(!Message.verifyMessage('1MsHWS1BnwMc3tLE8G35UXsS58fKipzB7a', sig, msg));
|
||||
});
|
||||
|
||||
test('incorrect signature', function() {
|
||||
// wrong signature
|
||||
var priv = '5HwoXVkHoRM8sL2KmNRS217n1g8mPPBomrY7yehCuXC1115WWsh';
|
||||
var key = Key(hexToBytes(priv));
|
||||
var sig = Message.signMessage(key, msg);
|
||||
assert.ok(!Message.verifyMessage(addr, sig, msg));
|
||||
});
|
Loading…
Reference in a new issue