From 923266672b0bea269921918785ad5d7570c049a4 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 21 Sep 2015 16:34:25 +1000 Subject: [PATCH 1/4] HDNode: add sign/verify --- src/hdnode.js | 8 +++++++ test/hdnode.js | 62 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/hdnode.js b/src/hdnode.js index bf84c45..33eb67c 100644 --- a/src/hdnode.js +++ b/src/hdnode.js @@ -149,6 +149,14 @@ HDNode.prototype.neutered = function () { return neutered } +HDNode.prototype.sign = function (hash) { + return this.keyPair.sign(hash) +} + +HDNode.prototype.verify = function (hash, signature) { + return this.keyPair.verify(hash, signature) +} + HDNode.prototype.toBase58 = function (__isPrivate) { if (__isPrivate !== undefined) throw new TypeError('Unsupported argument in 2.0.0') diff --git a/test/hdnode.js b/test/hdnode.js index c7ab317..a2e17d7 100644 --- a/test/hdnode.js +++ b/test/hdnode.js @@ -101,6 +101,51 @@ describe('HDNode', function () { }) }) + describe('ECPair wrappers', function () { + var keyPair, hd, hash + + beforeEach(function () { + keyPair = ECPair.makeRandom() + hash = new Buffer(32) + + var chainCode = new Buffer(32) + hd = new HDNode(keyPair, chainCode) + }) + + describe('getAddress', function () { + it('wraps keyPair.getAddress', sinon.test(function () { + this.mock(keyPair).expects('getAddress') + .once().withArgs().returns('foobar') + + assert.strictEqual(hd.getAddress(), 'foobar') + })) + }) + + describe('sign', function () { + it('wraps keyPair.sign', sinon.test(function () { + this.mock(keyPair).expects('sign') + .once().withArgs(hash).returns('signed') + + assert.strictEqual(hd.sign(hash), 'signed') + })) + }) + + describe('verify', function () { + var signature + + beforeEach(function () { + signature = hd.sign(hash) + }) + + it('wraps keyPair.verify', sinon.test(function () { + this.mock(keyPair).expects('verify') + .once().withArgs(hash, signature).returns('verified') + + assert.strictEqual(hd.verify(hash, signature), 'verified') + })) + }) + }) + describe('toBase58', function () { fixtures.valid.forEach(function (f) { it('exports ' + f.master.base58 + ' (public) correctly', function () { @@ -173,23 +218,6 @@ describe('HDNode', function () { }) }) - describe('getAddress', function () { - var hd - - beforeEach(function () { - var f = fixtures.valid[0] - - hd = HDNode.fromBase58(f.master.base58, NETWORKS_LIST) - }) - - it('wraps ECPair.getAddress', sinon.test(function () { - this.mock(hd.keyPair).expects('getAddress') - .once().returns('foobar') - - assert.strictEqual(hd.getAddress(), 'foobar') - })) - }) - describe('neutered', function () { var f = fixtures.valid[0] From 57d0ea84a241ce3582e232b7d8bb622437f7e67f Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 21 Sep 2015 16:44:53 +1000 Subject: [PATCH 2/4] HDNode: adds getPublicKeyBuffer --- src/hdnode.js | 4 ++++ test/hdnode.js | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/src/hdnode.js b/src/hdnode.js index 33eb67c..576dff0 100644 --- a/src/hdnode.js +++ b/src/hdnode.js @@ -136,6 +136,10 @@ HDNode.prototype.getFingerprint = function () { return this.getIdentifier().slice(0, 4) } +HDNode.prototype.getPublicKeyBuffer = function () { + return this.keyPair.getPublicKeyBuffer() +} + HDNode.prototype.neutered = function () { var neuteredKeyPair = new ECPair(null, this.keyPair.Q, { network: this.keyPair.network diff --git a/test/hdnode.js b/test/hdnode.js index a2e17d7..da0b697 100644 --- a/test/hdnode.js +++ b/test/hdnode.js @@ -121,6 +121,15 @@ describe('HDNode', function () { })) }) + describe('getPublicKeyBuffer', function () { + it('wraps keyPair.getPublicKeyBuffer', sinon.test(function () { + this.mock(keyPair).expects('getPublicKeyBuffer') + .once().withArgs().returns('pubKeyBuffer') + + assert.strictEqual(hd.getPublicKeyBuffer(), 'pubKeyBuffer') + })) + }) + describe('sign', function () { it('wraps keyPair.sign', sinon.test(function () { this.mock(keyPair).expects('sign') From daafb9794e60a7329c7d5825fceab71e17f6f0a7 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 21 Sep 2015 17:37:21 +1000 Subject: [PATCH 3/4] ECPair/HDNode: adds getNetwork --- src/ecpair.js | 4 ++++ src/hdnode.js | 4 ++++ test/ecpair.js | 11 +++++++++++ test/hdnode.js | 9 +++++++++ 4 files changed, 28 insertions(+) diff --git a/src/ecpair.js b/src/ecpair.js index 701b6df..17d19e1 100644 --- a/src/ecpair.js +++ b/src/ecpair.js @@ -105,6 +105,10 @@ ECPair.prototype.getAddress = function () { return bs58check.encode(payload) } +ECPair.prototype.getNetwork = function () { + return this.network +} + ECPair.prototype.getPublicKeyBuffer = function () { return this.Q.getEncoded(this.compressed) } diff --git a/src/hdnode.js b/src/hdnode.js index 576dff0..80ae630 100644 --- a/src/hdnode.js +++ b/src/hdnode.js @@ -136,6 +136,10 @@ HDNode.prototype.getFingerprint = function () { return this.getIdentifier().slice(0, 4) } +HDNode.prototype.getNetwork = function () { + return this.keyPair.getNetwork() +} + HDNode.prototype.getPublicKeyBuffer = function () { return this.keyPair.getPublicKeyBuffer() } diff --git a/test/ecpair.js b/test/ecpair.js index 2421f5f..b7edbd0 100644 --- a/test/ecpair.js +++ b/test/ecpair.js @@ -167,6 +167,17 @@ describe('ECPair', function () { }) }) + describe('getNetwork', function () { + fixtures.valid.forEach(function (f) { + it('returns ' + f.network + ' for ' + f.WIF, function () { + var network = NETWORKS[f.network] + var keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST) + + assert.strictEqual(keyPair.getNetwork(), network) + }) + }) + }) + describe('ecdsa wrappers', function () { var keyPair, hash diff --git a/test/hdnode.js b/test/hdnode.js index da0b697..afa9887 100644 --- a/test/hdnode.js +++ b/test/hdnode.js @@ -121,6 +121,15 @@ describe('HDNode', function () { })) }) + describe('getNetwork', function () { + it('wraps keyPair.getNetwork', sinon.test(function () { + this.mock(keyPair).expects('getNetwork') + .once().withArgs().returns('network') + + assert.strictEqual(hd.getNetwork(), 'network') + })) + }) + describe('getPublicKeyBuffer', function () { it('wraps keyPair.getPublicKeyBuffer', sinon.test(function () { this.mock(keyPair).expects('getPublicKeyBuffer') From b048ccb55f8f5d084831d4d5aceabbe21a24a07c Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Mon, 21 Sep 2015 17:41:45 +1000 Subject: [PATCH 4/4] CHANGELOG: add 'added' notes --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2ce073..08dded2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# 2.1.0 + +From this release users should use the HDNode directly (compared to accessing `.keyPair`) when performing ECDSA operations such as `sign` or `verify`. +Ideally you shoud not have to directly access `HDNode` internals for general usage, as it can often be confusing and error prone. + +__added__ +- `ECPair.prototype.getNetwork` +- `HDNode.prototype.getNetwork`, wraps the underyling keyPair's `getNetwork` method +- `HDNode.prototype.getPublicKeyBuffer`, wraps the underyling keyPair's `getPublicKeyBuffer` method +- `HDNode.prototype.sign`, wraps the underlying keyPair's `sign` method +- `HDNode.prototype.verify`, wraps the underlying keyPair's `verify` method + + # 2.0.0 In this release we have strived to simplify the API, [using native types](https://github.com/bitcoinjs/bitcoinjs-lib/issues/407) wherevever possible to encourage cross-compatibility with other open source community modules.