From a4393c0657667e6e647fe3068724cb7d52ad08bc Mon Sep 17 00:00:00 2001 From: "Ryan X. Charles" Date: Sun, 23 Mar 2014 15:12:52 -0700 Subject: [PATCH] update BIP32 to be able to derive pubkeys ...using the new addCompressed interface in Key.js --- BIP32.js | 36 ++++++++++++++++++++++++++++-------- test/test.BIP32.js | 9 +++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/BIP32.js b/BIP32.js index 6bfc60d53..dac4c33d2 100644 --- a/BIP32.js +++ b/BIP32.js @@ -7,7 +7,7 @@ var crypto = require('crypto'); var networks = require('./networks'); var secp256k1_n = new bignum("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16); -var secp256k1_G = new bignum("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16); //x coordinate +var secp256k1_Gx = new bignum("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16); var BIP32 = function(bytes) { if (bytes == 'mainnet' || bytes == 'livenet') @@ -266,17 +266,37 @@ BIP32.prototype.derive_child = function(i) { var ir = hash.slice(32, 64); // Ki = (IL + kpar)*G = IL*G + Kpar - var pub = new bignum(this.eckey.public, {size: 32}); - var k = secp256k1_G.mul(il).add(pub); + var key = new Key(); + key.private = il.toBuffer({size: 32}); + key.regenerateSync(); + key.compressed = false; + var oldkey = new Key(); + oldkey.public = this.eckey.public; + oldkey.compressed = false; + var newpub = Key.addUncompressed(key.public, oldkey.public); - //compressed pubkey must start with 0x02 just like compressed G - var kbuf = Buffer.concat([new Buffer(0x02), k.toBuffer({size: 32})]); + var eckey = new Key(); + eckey.compressed = false; + eckey.public = newpub; + if (eckey.public === null) { + console.log('invalid public key'); + return this.derive_child(i+1); + } + eckey.compressed = true; + +/* + if (k.gt(secp256k1_n)) + return this.derive_child(i+1); +*/ ret = new BIP32(); - ret.chain_code = new Buffer(ir); + ret.chain_code = new Buffer(ir); - ret.eckey = new Key(); - ret.eckey.public = kbuf; + var eckey = new Key(); + eckey.compressed = false; + eckey.public = newpub; + eckey.compressed = true; + ret.eckey = eckey; ret.has_private_key = false; } diff --git a/test/test.BIP32.js b/test/test.BIP32.js index 95d7ae081..8ed1148a0 100644 --- a/test/test.BIP32.js +++ b/test/test.BIP32.js @@ -93,6 +93,15 @@ describe('BIP32', function() { child.extended_public_key_string().should.equal(vector1_m0h1_public); }); + it("should get m/0'/1 ext. public key from m/0' public key from test vector 1", function() { + var bip32 = new BIP32(vector1_m_private); + var child = bip32.derive("m/0'"); + var child_pub = new BIP32(child.extended_public_key_string()); + var child2 = child_pub.derive("m/1"); + should.exist(child2); + child2.extended_public_key_string().should.equal(vector1_m0h1_public); + }); + it("should get m/0'/1/2h ext. private key from test vector 1", function() { var bip32 = new BIP32(vector1_m_private); var child = bip32.derive("m/0'/1/2'");