From 0b022554276165a308adf2ec1488c7233af9041e Mon Sep 17 00:00:00 2001 From: mike belshe Date: Sun, 5 Oct 2014 21:06:55 -0700 Subject: [PATCH] Fix BIP32 encoding error when private key starts with zeroes. Reviewers: ben Reviewed By: ben Subscribers: ben Differential Revision: http://phabricator.bitgo.com/D149 --- src/bitcoin/bip32.js | 7 ++++++- test/bitcoin/bip32.js | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/bitcoin/bip32.js b/src/bitcoin/bip32.js index 32d5a6d7a4..5a17181180 100644 --- a/src/bitcoin/bip32.js +++ b/src/bitcoin/bip32.js @@ -181,7 +181,12 @@ BIP32.prototype.build_extended_private_key = function() { // Private key this.extended_private_key.push(0); - this.extended_private_key = this.extended_private_key.concat(this.eckey.priv.toByteArrayUnsigned()); + var keyBytes = this.eckey.priv.toByteArrayUnsigned(); + // We converted from a BigInteger back to an array. Be careful to pad to 32 bytes for bip32 extended key. + while (keyBytes.length < 32) { + keyBytes.unshift(0); + } + this.extended_private_key = this.extended_private_key.concat(keyBytes); } BIP32.prototype.extended_private_key_string = function(format) { diff --git a/test/bitcoin/bip32.js b/test/bitcoin/bip32.js index 4deef57c3b..e8c8fcb93c 100644 --- a/test/bitcoin/bip32.js +++ b/test/bitcoin/bip32.js @@ -192,4 +192,37 @@ describe('BIP32', function() { Bitcoin.setNetwork('testnet'); }); + it("initFromSeed reconstruction", function () { + var seeds = [ + 'd2c282451514b98ae77d479472287336be45d00a55617d65296f4695d7e11251', + '33646e512afdd33e66ee5c5809227698cfaf83a90654baf13c6f3b8e3cba1b7b', + 'db7ab7e74208ba688de7fea5e82b578dcf14a1ea5e66373d8799743511442626', + '03e09ff37b11cd310019e730b669916fbc94ba8df3741128195d66ae3b3f8460' + ]; + + seeds.forEach(function(seed) { + var key = new Bitcoin.BIP32().initFromSeed(seed); + var xpub = key.extended_public_key_string(); + var xprv = key.extended_private_key_string(); + + var fromPrivate = new Bitcoin.BIP32(key.extended_private_key_string()); + assert.equal(fromPrivate.extended_public_key_string(), xpub, "xpub ok"); + assert.equal(fromPrivate.extended_private_key_string(), xprv, "xprv ok"); + + var fromPublic = new Bitcoin.BIP32(key.extended_public_key_string()); + assert.equal(fromPublic.extended_public_key_string(), xpub, "xpub ok from xpub"); + + var derivedKey = key.derive('m/100'); + xpub = derivedKey.extended_public_key_string(); + xprv = derivedKey.extended_private_key_string(); + + var fromPrivate = new Bitcoin.BIP32(derivedKey.extended_private_key_string()); + assert.equal(fromPrivate.extended_public_key_string(), xpub, "derived xpub ok"); + assert.equal(fromPrivate.extended_private_key_string(), xprv, "derived xprv ok"); + + var fromPublic = new Bitcoin.BIP32(derivedKey.extended_public_key_string()); + assert.equal(fromPublic.extended_public_key_string(), xpub, "derived xpub from xpub ok"); + }); + }); + });