@@ -6,8 +6,7 @@ var typeForce = require('typeforce')
66var networks = require ( './networks' )
77
88var BigInteger = require ( 'bigi' )
9- var ECKey = require ( './eckey' )
10- var ECPubKey = require ( './ecpubkey' )
9+ var ECPair = require ( './ecpair' )
1110
1211var ecurve = require ( 'ecurve' )
1312var curve = ecurve . getCurveByName ( 'secp256k1' )
@@ -24,32 +23,19 @@ function findBIP32NetworkByVersion (version) {
2423 assert ( false , 'Could not find network for ' + version . toString ( 16 ) )
2524}
2625
27- function HDNode ( K , chainCode , network ) {
28- network = network || networks . bitcoin
29-
26+ function HDNode ( keyPair , chainCode ) {
27+ typeForce ( 'ECPair' , keyPair )
3028 typeForce ( 'Buffer' , chainCode )
3129
3230 assert . equal ( chainCode . length , 32 , 'Expected chainCode length of 32, got ' + chainCode . length )
33- assert ( network . bip32 , 'Unknown BIP32 constants for network' )
31+ assert ( 'bip32' in keyPair . network , 'Unknown BIP32 constants for network' )
32+ assert . equal ( keyPair . compressed , true , 'BIP32 only allows compressed keyPairs' )
3433
34+ this . keyPair = keyPair
3535 this . chainCode = chainCode
3636 this . depth = 0
3737 this . index = 0
3838 this . parentFingerprint = 0x00000000
39- this . network = network
40-
41- if ( K instanceof BigInteger ) {
42- this . privKey = new ECKey ( K , true )
43- this . pubKey = this . privKey . pub
44- } else if ( K instanceof ECKey ) {
45- assert ( K . pub . compressed , 'ECKey must be compressed' )
46- this . privKey = K
47- } else if ( K instanceof ECPubKey ) {
48- assert ( K . compressed , 'ECPubKey must be compressed' )
49- this . pubKey = K
50- } else {
51- this . pubKey = new ECPubKey ( K , true )
52- }
5339}
5440
5541HDNode . MASTER_SECRET = new Buffer ( 'Bitcoin seed' )
@@ -67,10 +53,13 @@ HDNode.fromSeedBuffer = function (seed, network) {
6753 var IR = I . slice ( 32 )
6854
6955 // In case IL is 0 or >= n, the master key is invalid
70- // This is handled by `new ECKey` in the HDNode constructor
56+ // This is handled by the ECPair constructor
7157 var pIL = BigInteger . fromBuffer ( IL )
58+ var keyPair = new ECPair ( pIL , null , {
59+ network : network
60+ } )
7261
73- return new HDNode ( pIL , IR , network )
62+ return new HDNode ( keyPair , IR )
7463}
7564
7665HDNode . fromSeedHex = function ( hex , network ) {
@@ -108,14 +97,17 @@ HDNode.fromBase58 = function (string, network) {
10897
10998 // 32 bytes: the chain code
11099 var chainCode = buffer . slice ( 13 , 45 )
111- var data , hd
100+ var data , keyPair
112101
113102 // 33 bytes: private key data (0x00 + k)
114103 if ( version === network . bip32 . private ) {
115104 assert . strictEqual ( buffer . readUInt8 ( 45 ) , 0x00 , 'Invalid private key' )
116105 data = buffer . slice ( 46 , 78 )
117106 var d = BigInteger . fromBuffer ( data )
118- hd = new HDNode ( d , chainCode , network )
107+
108+ keyPair = new ECPair ( d , null , {
109+ network : network
110+ } )
119111
120112 // 33 bytes: public key data (0x02 + X or 0x03 + X)
121113 } else {
@@ -127,9 +119,12 @@ HDNode.fromBase58 = function (string, network) {
127119 // If not, the extended public key is invalid.
128120 curve . validate ( Q )
129121
130- hd = new HDNode ( Q , chainCode , network )
122+ keyPair = new ECPair ( null , Q , {
123+ network : network
124+ } )
131125 }
132126
127+ var hd = new HDNode ( keyPair , chainCode )
133128 hd . depth = depth
134129 hd . index = index
135130 hd . parentFingerprint = parentFingerprint
@@ -138,19 +133,23 @@ HDNode.fromBase58 = function (string, network) {
138133}
139134
140135HDNode . prototype . getIdentifier = function ( ) {
141- return bcrypto . hash160 ( this . pubKey . toBuffer ( ) )
136+ return bcrypto . hash160 ( this . keyPair . getPublicKeyBuffer ( ) )
142137}
143138
144139HDNode . prototype . getFingerprint = function ( ) {
145140 return this . getIdentifier ( ) . slice ( 0 , 4 )
146141}
147142
148143HDNode . prototype . getAddress = function ( ) {
149- return this . pubKey . getAddress ( this . network )
144+ return this . keyPair . getAddress ( )
150145}
151146
152147HDNode . prototype . neutered = function ( ) {
153- var neutered = new HDNode ( this . pubKey . Q , this . chainCode , this . network )
148+ var neuteredKeyPair = new ECPair ( null , this . keyPair . Q , {
149+ network : this . keyPair . network
150+ } )
151+
152+ var neutered = new HDNode ( neuteredKeyPair , this . chainCode )
154153 neutered . depth = this . depth
155154 neutered . index = this . index
156155 neutered . parentFingerprint = this . parentFingerprint
@@ -162,7 +161,8 @@ HDNode.prototype.toBase58 = function (__isPrivate) {
162161 assert . strictEqual ( __isPrivate , undefined , 'Unsupported argument in 2.0.0' )
163162
164163 // Version
165- var version = this . privKey ? this . network . bip32 . private : this . network . bip32 . public
164+ var network = this . keyPair . network
165+ var version = this . keyPair . d ? network . bip32 . private : network . bip32 . public
166166 var buffer = new Buffer ( HDNode . LENGTH )
167167
168168 // 4 bytes: version bytes
@@ -182,16 +182,16 @@ HDNode.prototype.toBase58 = function (__isPrivate) {
182182 // 32 bytes: the chain code
183183 this . chainCode . copy ( buffer , 13 )
184184
185- // 33 bytes: the private key, or
186- if ( this . privKey ) {
185+ // 33 bytes: the public key or private key data
186+ if ( this . keyPair . d ) {
187187 // 0x00 + k for private keys
188188 buffer . writeUInt8 ( 0 , 45 )
189- this . privKey . d . toBuffer ( 32 ) . copy ( buffer , 46 )
189+ this . keyPair . d . toBuffer ( 32 ) . copy ( buffer , 46 )
190190
191191 // 33 bytes: the public key
192192 } else {
193193 // X9.62 encoding for public keys
194- this . pubKey . toBuffer ( ) . copy ( buffer , 45 )
194+ this . keyPair . getPublicKeyBuffer ( ) . copy ( buffer , 45 )
195195 }
196196
197197 return base58check . encode ( buffer )
@@ -207,11 +207,11 @@ HDNode.prototype.derive = function (index) {
207207
208208 // Hardened child
209209 if ( isHardened ) {
210- assert ( this . privKey , 'Could not derive hardened child key' )
210+ assert ( this . keyPair . d , 'Could not derive hardened child key' )
211211
212212 // data = 0x00 || ser256(kpar) || ser32(index)
213213 data = Buffer . concat ( [
214- this . privKey . d . toBuffer ( 33 ) ,
214+ this . keyPair . d . toBuffer ( 33 ) ,
215215 indexBuffer
216216 ] )
217217
@@ -220,7 +220,7 @@ HDNode.prototype.derive = function (index) {
220220 // data = serP(point(kpar)) || ser32(index)
221221 // = serP(Kpar) || ser32(index)
222222 data = Buffer . concat ( [
223- this . pubKey . toBuffer ( ) ,
223+ this . keyPair . getPublicKeyBuffer ( ) ,
224224 indexBuffer
225225 ] )
226226 }
@@ -237,32 +237,37 @@ HDNode.prototype.derive = function (index) {
237237 }
238238
239239 // Private parent key -> private child key
240- var hd
241- if ( this . privKey ) {
240+ var derivedKeyPair
241+ if ( this . keyPair . d ) {
242242 // ki = parse256(IL) + kpar (mod n)
243- var ki = pIL . add ( this . privKey . d ) . mod ( curve . n )
243+ var ki = pIL . add ( this . keyPair . d ) . mod ( curve . n )
244244
245245 // In case ki == 0, proceed with the next value for i
246246 if ( ki . signum ( ) === 0 ) {
247247 return this . derive ( index + 1 )
248248 }
249249
250- hd = new HDNode ( ki , IR , this . network )
250+ derivedKeyPair = new ECPair ( ki , null , {
251+ network : this . keyPair . network
252+ } )
251253
252254 // Public parent key -> public child key
253255 } else {
254256 // Ki = point(parse256(IL)) + Kpar
255257 // = G*IL + Kpar
256- var Ki = curve . G . multiply ( pIL ) . add ( this . pubKey . Q )
258+ var Ki = curve . G . multiply ( pIL ) . add ( this . keyPair . Q )
257259
258260 // In case Ki is the point at infinity, proceed with the next value for i
259261 if ( curve . isInfinity ( Ki ) ) {
260262 return this . derive ( index + 1 )
261263 }
262264
263- hd = new HDNode ( Ki , IR , this . network )
265+ derivedKeyPair = new ECPair ( null , Ki , {
266+ network : this . keyPair . network
267+ } )
264268 }
265269
270+ var hd = new HDNode ( derivedKeyPair , IR )
266271 hd . depth = this . depth + 1
267272 hd . index = index
268273 hd . parentFingerprint = this . getFingerprint ( ) . readUInt32BE ( 0 )
0 commit comments