2
0
mirror of synced 2025-02-24 12:08:10 +00:00

Added message signing to Wallet.

This commit is contained in:
Richard Moore 2017-10-19 02:52:55 -04:00
parent cb7e40a892
commit f5f2bf85c5
3 changed files with 66 additions and 2 deletions

View File

@ -39,7 +39,7 @@ Running Tests
# Test encrypting/decrypting JSON wallets and transaction parsing/signing
# - See tests/transactions.json.gz
# - See tests/wallets.json.gz
> ./node_modules/.bin/mocha test-wallet.js
> ./node_modules/.bin/mocha --timeout 100000 test-wallet.js
# This test case has not yet been migrated to mocha

View File

@ -3,7 +3,6 @@
var assert = require('assert');
var utils = require('./utils');
describe('Test Brain Wallets', function() {
var Wallet = require('../wallet/wallet');
@ -145,3 +144,31 @@ describe('Test Transaction Signing and Parsing', function() {
});
});
});
describe('Test Signing Messages', function() {
var Wallet = require('../wallet/wallet');
var tests = [
{
address: '0x14791697260E4c9A71f18484C9f997B308e59325',
message: 'hello world',
privateKey: '0x0123456789012345678901234567890123456789012345678901234567890123',
signature: '0xddd0a7290af9526056b4e35a077b9a11b513aa0028ec6c9880948544508f3c63265e99e47ad31bb2cab9646c504576b3abc6939a1710afc08cbf3034d73214b81c'
}
];
tests.forEach(function(test) {
it(('signs a message "' + test.message + '"'), function() {
var wallet = new Wallet(test.privateKey);
var signature = wallet.signMessage(test.message);
assert.equal(signature, test.signature, 'computes message signature');
});
});
tests.forEach(function(test) {
it(('verifies a message "' + test.message + '"'), function() {
var address = Wallet.verifyMessage(test.message, test.signature);
assert.equal(address, test.address, 'verifies message signature');
});
});
});

View File

@ -278,6 +278,43 @@ utils.defineProperty(Wallet.prototype, 'send', function(addressOrName, amountWei
});
});
// @TODO: this is starting to get used various places; move to utils?
function hexPad(value, length) {
while (value.length < 2 * length + 2) {
value = '0x0' + value.substring(2);
}
return value;
}
function getHash(message) {
var payload = utils.concat([
utils.toUtf8Bytes('\x19Ethereum Signed Message:\n'),
utils.toUtf8Bytes(String(message.length)),
utils.toUtf8Bytes(message)
]);
return utils.keccak256(payload);
}
utils.defineProperty(Wallet.prototype, 'signMessage', function(message) {
var signingKey = new SigningKey(this.privateKey);
var sig = signingKey.signDigest(getHash(message));
return (hexPad(sig.r) + hexPad(sig.s).substring(2) + (sig.recoveryParam ? '1c': '1b'));
});
utils.defineProperty(Wallet, 'verifyMessage', function(message, signature) {
signature = utils.hexlify(signature);
if (signature.length != 132) { throw new Error('invalid signature'); }
var digest = getHash(message);
var recoveryParam = parseInt(signature.substring(130), 16) - 27;
if (recoveryParam < 0) { throw new Error('invalid signature'); }
return SigningKey.recover(
digest,
signature.substring(0, 66),
'0x' + signature.substring(66, 130),
parseInt(signature.substring(130), 16) - 27
);
});
utils.defineProperty(Wallet.prototype, 'encrypt', function(password, options, progressCallback) {
if (typeof(options) === 'function' && !progressCallback) {