@@ -64,7 +64,7 @@ impl Label for H256 {
64
64
fn len ( ) -> usize { 32 }
65
65
66
66
fn store ( & self , target : & mut [ u8 ] ) {
67
- self . copy_to ( & mut target[ 0 ..32 ] ) ;
67
+ ( & mut target[ 0 ..32 ] ) . copy_from_slice ( self . as_bytes ( ) ) ;
68
68
}
69
69
}
70
70
@@ -180,7 +180,7 @@ impl ExtendedKeyPair {
180
180
pub fn with_seed ( seed : & [ u8 ] ) -> Result < ExtendedKeyPair , DerivationError > {
181
181
let ( master_key, chain_code) = derivation:: seed_pair ( seed) ;
182
182
Ok ( ExtendedKeyPair :: with_secret (
183
- Secret :: from_unsafe_slice ( & * master_key) . map_err ( |_| DerivationError :: InvalidSeed ) ?,
183
+ Secret :: from_unsafe_slice ( master_key. as_bytes ( ) ) . map_err ( |_| DerivationError :: InvalidSeed ) ?,
184
184
chain_code,
185
185
) )
186
186
}
@@ -208,12 +208,13 @@ impl ExtendedKeyPair {
208
208
// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
209
209
mod derivation {
210
210
use parity_crypto:: hmac;
211
- use ethereum_types:: { U256 , U512 , H512 , H256 } ;
211
+ use ethereum_types:: { BigEndianHash , U256 , U512 , H512 , H256 } ;
212
212
use secp256k1:: key:: { SecretKey , PublicKey } ;
213
213
use SECP256K1 ;
214
214
use keccak;
215
215
use math:: curve_order;
216
216
use super :: { Label , Derivation } ;
217
+ use std:: convert:: TryInto ;
217
218
218
219
#[ derive( Debug ) ]
219
220
pub enum Error {
@@ -237,18 +238,18 @@ mod derivation {
237
238
}
238
239
239
240
fn hmac_pair ( data : & [ u8 ] , private_key : H256 , chain_code : H256 ) -> ( H256 , H256 ) {
240
- let private: U256 = private_key. into ( ) ;
241
+ let private: U256 = private_key. into_uint ( ) ;
241
242
242
243
// produces 512-bit derived hmac (I)
243
- let skey = hmac:: SigKey :: sha512 ( & * chain_code) ;
244
+ let skey = hmac:: SigKey :: sha512 ( chain_code. as_bytes ( ) ) ;
244
245
let i_512 = hmac:: sign ( & skey, & data[ ..] ) ;
245
246
246
247
// left most 256 bits are later added to original private key
247
- let hmac_key: U256 = H256 :: from_slice ( & i_512[ 0 ..32 ] ) . into ( ) ;
248
+ let hmac_key: U256 = H256 :: from_slice ( & i_512[ 0 ..32 ] ) . into_uint ( ) ;
248
249
// right most 256 bits are new chain code for later derivations
249
- let next_chain_code = H256 :: from ( & i_512[ 32 ..64 ] ) ;
250
+ let next_chain_code = H256 :: from_slice ( & i_512[ 32 ..64 ] ) ;
250
251
251
- let child_key = private_add ( hmac_key, private) . into ( ) ;
252
+ let child_key = BigEndianHash :: from_uint ( & private_add ( hmac_key, private) ) ;
252
253
( child_key, next_chain_code)
253
254
}
254
255
@@ -257,7 +258,7 @@ mod derivation {
257
258
fn private_soft < T > ( private_key : H256 , chain_code : H256 , index : T ) -> ( H256 , H256 ) where T : Label {
258
259
let mut data = vec ! [ 0u8 ; 33 + T :: len( ) ] ;
259
260
260
- let sec_private = SecretKey :: from_slice ( & SECP256K1 , & * private_key)
261
+ let sec_private = SecretKey :: from_slice ( & SECP256K1 , private_key. as_bytes ( ) )
261
262
. expect ( "Caller should provide valid private key" ) ;
262
263
let sec_public = PublicKey :: from_secret_key ( & SECP256K1 , & sec_private)
263
264
. expect ( "Caller should provide valid private key" ) ;
@@ -276,7 +277,7 @@ mod derivation {
276
277
// corresponding public keys of the original and derived private keys
277
278
fn private_hard < T > ( private_key : H256 , chain_code : H256 , index : T ) -> ( H256 , H256 ) where T : Label {
278
279
let mut data: Vec < u8 > = vec ! [ 0u8 ; 33 + T :: len( ) ] ;
279
- let private: U256 = private_key. into ( ) ;
280
+ let private: U256 = private_key. into_uint ( ) ;
280
281
281
282
// 0x00 (padding) -- private_key -- index
282
283
// 0 -- 1..33 -- 33..end
@@ -293,9 +294,8 @@ mod derivation {
293
294
294
295
// todo: surely can be optimized
295
296
fn modulo ( u1 : U512 , u2 : U256 ) -> U256 {
296
- let dv = u1 / U512 :: from ( u2) ;
297
- let md = u1 - ( dv * U512 :: from ( u2) ) ;
298
- md. into ( )
297
+ let m = u1 % U512 :: from ( u2) ;
298
+ m. try_into ( ) . expect ( "U512 modulo U256 should fit into U256; qed" )
299
299
}
300
300
301
301
pub fn public < T > ( public_key : H512 , chain_code : H256 , derivation : Derivation < T > ) -> Result < ( H512 , H256 ) , Error > where T : Label {
@@ -306,7 +306,7 @@ mod derivation {
306
306
307
307
let mut public_sec_raw = [ 0u8 ; 65 ] ;
308
308
public_sec_raw[ 0 ] = 4 ;
309
- public_sec_raw[ 1 ..65 ] . copy_from_slice ( & * public_key) ;
309
+ public_sec_raw[ 1 ..65 ] . copy_from_slice ( public_key. as_bytes ( ) ) ;
310
310
let public_sec = PublicKey :: from_slice ( & SECP256K1 , & public_sec_raw) . map_err ( |_| Error :: InvalidPoint ) ?;
311
311
let public_serialized = public_sec. serialize_vec ( & SECP256K1 , true ) ;
312
312
@@ -317,15 +317,15 @@ mod derivation {
317
317
index. store ( & mut data[ 33 ..( 33 + T :: len ( ) ) ] ) ;
318
318
319
319
// HMAC512SHA produces [derived private(256); new chain code(256)]
320
- let skey = hmac:: SigKey :: sha512 ( & * chain_code) ;
320
+ let skey = hmac:: SigKey :: sha512 ( chain_code. as_bytes ( ) ) ;
321
321
let i_512 = hmac:: sign ( & skey, & data[ ..] ) ;
322
322
323
- let new_private = H256 :: from ( & i_512[ 0 ..32 ] ) ;
324
- let new_chain_code = H256 :: from ( & i_512[ 32 ..64 ] ) ;
323
+ let new_private = H256 :: from_slice ( & i_512[ 0 ..32 ] ) ;
324
+ let new_chain_code = H256 :: from_slice ( & i_512[ 32 ..64 ] ) ;
325
325
326
326
// Generated private key can (extremely rarely) be out of secp256k1 key field
327
- if curve_order ( ) <= new_private. clone ( ) . into ( ) { return Err ( Error :: MissingIndex ) ; }
328
- let new_private_sec = SecretKey :: from_slice ( & SECP256K1 , & * new_private)
327
+ if curve_order ( ) <= new_private. into_uint ( ) { return Err ( Error :: MissingIndex ) ; }
328
+ let new_private_sec = SecretKey :: from_slice ( & SECP256K1 , new_private. as_bytes ( ) )
329
329
. expect ( "Private key belongs to the field [0..CURVE_ORDER) (checked above); So initializing can never fail; qed" ) ;
330
330
let mut new_public = PublicKey :: from_secret_key ( & SECP256K1 , & new_private_sec)
331
331
. expect ( "Valid private key produces valid public key" ) ;
@@ -337,7 +337,7 @@ mod derivation {
337
337
let serialized = new_public. serialize_vec ( & SECP256K1 , false ) ;
338
338
339
339
Ok ( (
340
- H512 :: from ( & serialized[ 1 ..65 ] ) ,
340
+ H512 :: from_slice ( & serialized[ 1 ..65 ] ) ,
341
341
new_chain_code,
342
342
) )
343
343
}
@@ -348,18 +348,18 @@ mod derivation {
348
348
349
349
pub fn chain_code ( secret : H256 ) -> H256 {
350
350
// 10,000 rounds of sha3
351
- let mut running_sha3 = sha3 ( & * secret) ;
352
- for _ in 0 ..99999 { running_sha3 = sha3 ( & * running_sha3) ; }
351
+ let mut running_sha3 = sha3 ( secret. as_bytes ( ) ) ;
352
+ for _ in 0 ..99999 { running_sha3 = sha3 ( running_sha3. as_bytes ( ) ) ; }
353
353
running_sha3
354
354
}
355
355
356
356
pub fn point ( secret : H256 ) -> Result < H512 , Error > {
357
- let sec = SecretKey :: from_slice ( & SECP256K1 , & * secret)
357
+ let sec = SecretKey :: from_slice ( & SECP256K1 , secret. as_bytes ( ) )
358
358
. map_err ( |_| Error :: InvalidPoint ) ?;
359
359
let public_sec = PublicKey :: from_secret_key ( & SECP256K1 , & sec)
360
360
. map_err ( |_| Error :: InvalidPoint ) ?;
361
361
let serialized = public_sec. serialize_vec ( & SECP256K1 , false ) ;
362
- Ok ( H512 :: from ( & serialized[ 1 ..65 ] ) )
362
+ Ok ( H512 :: from_slice ( & serialized[ 1 ..65 ] ) )
363
363
}
364
364
365
365
pub fn seed_pair ( seed : & [ u8 ] ) -> ( H256 , H256 ) {
@@ -378,12 +378,13 @@ mod tests {
378
378
use super :: { ExtendedSecret , ExtendedPublic , ExtendedKeyPair } ;
379
379
use secret:: Secret ;
380
380
use std:: str:: FromStr ;
381
- use ethereum_types:: { H128 , H256 } ;
381
+ use ethereum_types:: { H128 , H256 , H512 } ;
382
382
use super :: { derivation, Derivation } ;
383
383
384
384
fn master_chain_basic ( ) -> ( H256 , H256 ) {
385
385
let seed = H128 :: from_str ( "000102030405060708090a0b0c0d0e0f" )
386
386
. expect ( "Seed should be valid H128" )
387
+ . as_bytes ( )
387
388
. to_vec ( ) ;
388
389
389
390
derivation:: seed_pair ( & * seed)
@@ -399,35 +400,47 @@ mod tests {
399
400
#[ test]
400
401
fn smoky ( ) {
401
402
let secret = Secret :: from_str ( "a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65" ) . unwrap ( ) ;
402
- let extended_secret = ExtendedSecret :: with_code ( secret. clone ( ) , 0u64 . into ( ) ) ;
403
+ let extended_secret = ExtendedSecret :: with_code ( secret. clone ( ) , H256 :: zero ( ) ) ;
403
404
404
405
// hardened
405
406
assert_eq ! ( & * * extended_secret. as_raw( ) , & * secret) ;
406
- assert_eq ! ( & * * extended_secret. derive( 2147483648 . into( ) ) . as_raw( ) , & "0927453daed47839608e414a3738dfad10aed17c459bbd9ab53f89b026c834b6" . into( ) ) ;
407
- assert_eq ! ( & * * extended_secret. derive( 2147483649 . into( ) ) . as_raw( ) , & "44238b6a29c6dcbe9b401364141ba11e2198c289a5fed243a1c11af35c19dc0f" . into( ) ) ;
407
+ assert_eq ! (
408
+ * * extended_secret. derive( 2147483648 . into( ) ) . as_raw( ) ,
409
+ H256 :: from_str( "0927453daed47839608e414a3738dfad10aed17c459bbd9ab53f89b026c834b6" ) . unwrap( ) ,
410
+ ) ;
411
+ assert_eq ! (
412
+ * * extended_secret. derive( 2147483649 . into( ) ) . as_raw( ) ,
413
+ H256 :: from_str( "44238b6a29c6dcbe9b401364141ba11e2198c289a5fed243a1c11af35c19dc0f" ) . unwrap( ) ,
414
+ ) ;
408
415
409
416
// normal
410
- assert_eq ! ( & * * extended_secret. derive( 0 . into( ) ) . as_raw( ) , & "bf6a74e3f7b36fc4c96a1e12f31abc817f9f5904f5a8fc27713163d1f0b713f6" . into ( ) ) ;
411
- assert_eq ! ( & * * extended_secret. derive( 1 . into( ) ) . as_raw( ) , & "bd4fca9eb1f9c201e9448c1eecd66e302d68d4d313ce895b8c134f512205c1bc" . into ( ) ) ;
412
- assert_eq ! ( & * * extended_secret. derive( 2 . into( ) ) . as_raw( ) , & "86932b542d6cab4d9c65490c7ef502d89ecc0e2a5f4852157649e3251e2a3268" . into ( ) ) ;
417
+ assert_eq ! ( * * extended_secret. derive( 0 . into( ) ) . as_raw( ) , H256 :: from_str ( "bf6a74e3f7b36fc4c96a1e12f31abc817f9f5904f5a8fc27713163d1f0b713f6" ) . unwrap ( ) ) ;
418
+ assert_eq ! ( * * extended_secret. derive( 1 . into( ) ) . as_raw( ) , H256 :: from_str ( "bd4fca9eb1f9c201e9448c1eecd66e302d68d4d313ce895b8c134f512205c1bc" ) . unwrap ( ) ) ;
419
+ assert_eq ! ( * * extended_secret. derive( 2 . into( ) ) . as_raw( ) , H256 :: from_str ( "86932b542d6cab4d9c65490c7ef502d89ecc0e2a5f4852157649e3251e2a3268" ) . unwrap ( ) ) ;
413
420
414
421
let extended_public = ExtendedPublic :: from_secret ( & extended_secret) . expect ( "Extended public should be created" ) ;
415
422
let derived_public = extended_public. derive ( 0 . into ( ) ) . expect ( "First derivation of public should succeed" ) ;
416
- assert_eq ! ( & * derived_public. public( ) , & "f7b3244c96688f92372bfd4def26dc4151529747bab9f188a4ad34e141d47bd66522ff048bc6f19a0a4429b04318b1a8796c000265b4fa200dae5f6dda92dd94" . into( ) ) ;
423
+ assert_eq ! (
424
+ * derived_public. public( ) ,
425
+ H512 :: from_str( "f7b3244c96688f92372bfd4def26dc4151529747bab9f188a4ad34e141d47bd66522ff048bc6f19a0a4429b04318b1a8796c000265b4fa200dae5f6dda92dd94" ) . unwrap( ) ,
426
+ ) ;
417
427
418
428
let keypair = ExtendedKeyPair :: with_secret (
419
429
Secret :: from_str ( "a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65" ) . unwrap ( ) ,
420
- 064 . into ( ) ,
430
+ H256 :: from_low_u64_be ( 64 ) ,
431
+ ) ;
432
+ assert_eq ! (
433
+ * * keypair. derive( 2147483648u32 . into( ) ) . expect( "Derivation of keypair should succeed" ) . secret( ) . as_raw( ) ,
434
+ H256 :: from_str( "edef54414c03196557cf73774bc97a645c9a1df2164ed34f0c2a78d1375a930c" ) . unwrap( ) ,
421
435
) ;
422
- assert_eq ! ( & * * keypair. derive( 2147483648u32 . into( ) ) . expect( "Derivation of keypair should succeed" ) . secret( ) . as_raw( ) , & "edef54414c03196557cf73774bc97a645c9a1df2164ed34f0c2a78d1375a930c" . into( ) ) ;
423
436
}
424
437
425
438
#[ test]
426
439
fn h256_soft_match ( ) {
427
440
let secret = Secret :: from_str ( "a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65" ) . unwrap ( ) ;
428
441
let derivation_secret = H256 :: from_str ( "51eaf04f9dbbc1417dc97e789edd0c37ecda88bac490434e367ea81b71b7b015" ) . unwrap ( ) ;
429
442
430
- let extended_secret = ExtendedSecret :: with_code ( secret. clone ( ) , 0u64 . into ( ) ) ;
443
+ let extended_secret = ExtendedSecret :: with_code ( secret. clone ( ) , H256 :: zero ( ) ) ;
431
444
let extended_public = ExtendedPublic :: from_secret ( & extended_secret) . expect ( "Extended public should be created" ) ;
432
445
433
446
let derived_secret0 = extended_secret. derive ( Derivation :: Soft ( derivation_secret) ) ;
@@ -442,15 +455,18 @@ mod tests {
442
455
fn h256_hard ( ) {
443
456
let secret = Secret :: from_str ( "a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65" ) . unwrap ( ) ;
444
457
let derivation_secret = H256 :: from_str ( "51eaf04f9dbbc1417dc97e789edd0c37ecda88bac490434e367ea81b71b7b015" ) . unwrap ( ) ;
445
- let extended_secret = ExtendedSecret :: with_code ( secret. clone ( ) , 1u64 . into ( ) ) ;
458
+ let extended_secret = ExtendedSecret :: with_code ( secret. clone ( ) , H256 :: from_low_u64_be ( 1 ) ) ;
446
459
447
- assert_eq ! ( & * * extended_secret. derive( Derivation :: Hard ( derivation_secret) ) . as_raw( ) , & "2bc2d696fb744d77ff813b4a1ef0ad64e1e5188b622c54ba917acc5ebc7c5486" . into( ) ) ;
460
+ assert_eq ! (
461
+ * * extended_secret. derive( Derivation :: Hard ( derivation_secret) ) . as_raw( ) ,
462
+ H256 :: from_str( "2bc2d696fb744d77ff813b4a1ef0ad64e1e5188b622c54ba917acc5ebc7c5486" ) . unwrap( ) ,
463
+ ) ;
448
464
}
449
465
450
466
#[ test]
451
467
fn match_ ( ) {
452
468
let secret = Secret :: from_str ( "a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65" ) . unwrap ( ) ;
453
- let extended_secret = ExtendedSecret :: with_code ( secret. clone ( ) , 1 . into ( ) ) ;
469
+ let extended_secret = ExtendedSecret :: with_code ( secret. clone ( ) , H256 :: from_low_u64_be ( 1 ) ) ;
454
470
let extended_public = ExtendedPublic :: from_secret ( & extended_secret) . expect ( "Extended public should be created" ) ;
455
471
456
472
let derived_secret0 = extended_secret. derive ( 0 . into ( ) ) ;
@@ -465,6 +481,7 @@ mod tests {
465
481
fn test_seeds ( ) {
466
482
let seed = H128 :: from_str ( "000102030405060708090a0b0c0d0e0f" )
467
483
. expect ( "Seed should be valid H128" )
484
+ . as_bytes ( )
468
485
. to_vec ( ) ;
469
486
470
487
// private key from bitcoin test vector
0 commit comments