From 98c42c200b77e0bb8c35556736101187f1e2a1b3 Mon Sep 17 00:00:00 2001 From: Chris Clark Date: Wed, 14 Oct 2015 12:17:55 -0700 Subject: [PATCH] Specify messages as hex and fix bug in ed25519 signing --- packages/ripple-keypairs/.travis.yml | 7 ------- packages/ripple-keypairs/README.md | 8 ++++---- packages/ripple-keypairs/circle.yml | 3 +++ packages/ripple-keypairs/package.json | 2 +- packages/ripple-keypairs/src/index.js | 11 +++++++---- packages/ripple-keypairs/test/api-test.js | 14 ++++++++++---- packages/ripple-keypairs/test/fixtures/api.json | 2 +- 7 files changed, 26 insertions(+), 21 deletions(-) delete mode 100644 packages/ripple-keypairs/.travis.yml create mode 100644 packages/ripple-keypairs/circle.yml diff --git a/packages/ripple-keypairs/.travis.yml b/packages/ripple-keypairs/.travis.yml deleted file mode 100644 index d006b190..00000000 --- a/packages/ripple-keypairs/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: node_js -node_js: -- '0.12' -script: -- npm test --coverage -- npm run-script codecov -- npm run-script lint diff --git a/packages/ripple-keypairs/README.md b/packages/ripple-keypairs/README.md index 88bfe1f8..3ff1f651 100644 --- a/packages/ripple-keypairs/README.md +++ b/packages/ripple-keypairs/README.md @@ -17,14 +17,14 @@ deriveKeypair(seed: string) -> {privateKey: string, publicKey: string} Derive a public and private key from a seed. The keys are represented as 33-byte hexadecimal strings. ``` -sign(message: string, privateKey: string) -> string +sign(messageHex: string, privateKey: string) -> string ``` -Sign an arbitrary message with a private key. Returns the signature as a hexadecimal string. +Sign an arbitrary hex-encoded message with a private key. Returns the signature as a hexadecimal string. ``` -verify(message: string, signature: string, publicKey: string) -> boolean +verify(messageHex: string, signature: string, publicKey: string) -> boolean ``` -Verify a signature for a given message and public key. Returns true if the signature is valid, false otherwise. +Verify a signature for a given hex-encoded message and public key. Returns true if the signature is valid, false otherwise. ``` deriveAddress(publicKey: string) -> string diff --git a/packages/ripple-keypairs/circle.yml b/packages/ripple-keypairs/circle.yml new file mode 100644 index 00000000..1ef2b5e5 --- /dev/null +++ b/packages/ripple-keypairs/circle.yml @@ -0,0 +1,3 @@ +machine: + node: + version: 0.12.0 diff --git a/packages/ripple-keypairs/package.json b/packages/ripple-keypairs/package.json index 264f0484..da8d2428 100644 --- a/packages/ripple-keypairs/package.json +++ b/packages/ripple-keypairs/package.json @@ -1,6 +1,6 @@ { "name": "ripple-keypairs", - "version": "0.9.0", + "version": "0.10.0", "description": "ripple key pairs", "files": [ "distrib/npm/*", diff --git a/packages/ripple-keypairs/src/index.js b/packages/ripple-keypairs/src/index.js index 4b9e039c..e2465a7c 100644 --- a/packages/ripple-keypairs/src/index.js +++ b/packages/ripple-keypairs/src/index.js @@ -52,6 +52,9 @@ const ed25519 = { return {privateKey, publicKey}; }, sign: function(message, privateKey) { + // caution: Ed25519.sign interprets all strings as hex, stripping + // any non-hex characters without warning + assert(Array.isArray(message), 'message must be array of octets'); return bytesToHex(Ed25519.sign( message, hexToBytes(privateKey).slice(1)).toBytes()); }, @@ -78,14 +81,14 @@ function getAlgorithmFromKey(key) { 'ed25519' : 'ecdsa-secp256k1'; } -function sign(message, privateKey) { +function sign(messageHex, privateKey) { const algorithm = getAlgorithmFromKey(privateKey); - return select(algorithm).sign(message, privateKey); + return select(algorithm).sign(hexToBytes(messageHex), privateKey); } -function verify(message, signature, publicKey) { +function verify(messageHex, signature, publicKey) { const algorithm = getAlgorithmFromKey(publicKey); - return select(algorithm).verify(message, signature, publicKey); + return select(algorithm).verify(hexToBytes(messageHex), signature, publicKey); } function deriveAddressFromBytes(publicKeyBytes) { diff --git a/packages/ripple-keypairs/test/api-test.js b/packages/ripple-keypairs/test/api-test.js index d246dcef..b5793afe 100644 --- a/packages/ripple-keypairs/test/api-test.js +++ b/packages/ripple-keypairs/test/api-test.js @@ -53,7 +53,9 @@ describe('api', () => { it('sign - secp256k1', () => { const privateKey = fixtures.secp256k1.keypair.privateKey; - const signature = api.sign(fixtures.secp256k1.message, privateKey); + const message = fixtures.secp256k1.message; + const messageHex = (new Buffer(message, 'utf8')).toString('hex'); + const signature = api.sign(messageHex, privateKey); assert.strictEqual(signature, fixtures.secp256k1.signature); }); @@ -61,12 +63,15 @@ describe('api', () => { const signature = fixtures.secp256k1.signature; const publicKey = fixtures.secp256k1.keypair.publicKey; const message = fixtures.secp256k1.message; - assert(api.verify(message, signature, publicKey)); + const messageHex = (new Buffer(message, 'utf8')).toString('hex'); + assert(api.verify(messageHex, signature, publicKey)); }); it('sign - ed25519', () => { const privateKey = fixtures.ed25519.keypair.privateKey; - const signature = api.sign(fixtures.ed25519.message, privateKey); + const message = fixtures.ed25519.message; + const messageHex = (new Buffer(message, 'utf8')).toString('hex'); + const signature = api.sign(messageHex, privateKey); assert.strictEqual(signature, fixtures.ed25519.signature); }); @@ -74,7 +79,8 @@ describe('api', () => { const signature = fixtures.ed25519.signature; const publicKey = fixtures.ed25519.keypair.publicKey; const message = fixtures.ed25519.message; - assert(api.verify(message, signature, publicKey)); + const messageHex = (new Buffer(message, 'utf8')).toString('hex'); + assert(api.verify(messageHex, signature, publicKey)); }); it('deriveNodeAddress', () => { diff --git a/packages/ripple-keypairs/test/fixtures/api.json b/packages/ripple-keypairs/test/fixtures/api.json index 0ae8ee8a..60975fd1 100644 --- a/packages/ripple-keypairs/test/fixtures/api.json +++ b/packages/ripple-keypairs/test/fixtures/api.json @@ -17,6 +17,6 @@ }, "address": "rLUEXYuLiQptky37CqLcm9USQpPiz5rkpD", "message": "test message", - "signature": "D9AB88033EFAFFBADF3AF5854885A0B42DAA91B94B64B10EB1C1BE376C0F452A93F31B13CEF00049FB36317B2E9E5ADBAD38040E71C17B01F01A2FB3EA30CD0F" + "signature": "CB199E1BFD4E3DAA105E4832EEDFA36413E1F44205E4EFB9E27E826044C21E3E2E848BBC8195E8959BADF887599B7310AD1B7047EF11B682E0D068F73749750E" } }