11//! Extended private key operations according to BIP-32
2- use std:: convert:: TryInto ;
32
43use super :: {
54 derivation_path:: { ChildIndex , ChildIndexError , DerivationPath } ,
@@ -27,14 +26,23 @@ type HmacSha512 = Hmac<Sha512>;
2726
2827/// Extended secret key
2928/// implemented according to BIP-32
30- #[ derive( PartialEq , Eq , Debug , Clone ) ]
29+ #[ derive( PartialEq , Eq , Clone ) ]
3130pub struct ExtSecretKey {
32- /// The secret key
33- private_input : DlogProverInput ,
31+ private_input : Wscalar ,
3432 chain_code : ChainCode ,
3533 derivation_path : DerivationPath ,
3634}
3735
36+ impl std:: fmt:: Debug for ExtSecretKey {
37+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
38+ f. debug_struct ( "ExtSecretKey" )
39+ . field ( "private_input" , & "*****" ) // disable debug output for secret key to prevent key leakage in logs
40+ . field ( "chain_code" , & self . chain_code )
41+ . field ( "derivation_path" , & self . derivation_path )
42+ . finish ( )
43+ }
44+ }
45+
3846/// Extended secret key errors
3947#[ derive( Error , PartialEq , Eq , Debug , Clone ) ]
4048pub enum ExtSecretKeyError {
@@ -65,8 +73,8 @@ impl ExtSecretKey {
6573 chain_code : ChainCode ,
6674 derivation_path : DerivationPath ,
6775 ) -> Result < Self , ExtSecretKeyError > {
68- let private_input = DlogProverInput :: from_bytes ( & secret_key_bytes )
69- . ok_or ( ExtSecretKeyError :: ScalarEncodingError ) ?;
76+ let private_input =
77+ Wscalar :: from_bytes ( & secret_key_bytes ) . ok_or ( ExtSecretKeyError :: ScalarEncodingError ) ?;
7078 Ok ( Self {
7179 private_input,
7280 chain_code,
@@ -81,7 +89,7 @@ impl ExtSecretKey {
8189
8290 /// Returns secret key
8391 pub fn secret_key ( & self ) -> SecretKey {
84- self . private_input . clone ( ) . into ( )
92+ DlogProverInput :: new ( self . private_input . clone ( ) ) . into ( )
8593 }
8694
8795 /// Byte representation of the underlying scalar
@@ -91,7 +99,7 @@ impl ExtSecretKey {
9199
92100 /// Public image associated with the private input
93101 pub fn public_image ( & self ) -> ProveDlog {
94- self . private_input . public_image ( )
102+ DlogProverInput :: new ( self . private_input . clone ( ) ) . public_image ( )
95103 }
96104
97105 /// Public image bytes in SEC-1 encoded & compressed format
@@ -102,12 +110,11 @@ impl ExtSecretKey {
102110 /// The extended public key associated with this secret key
103111 pub fn public_key ( & self ) -> Result < ExtPubKey , ExtSecretKeyError > {
104112 #[ allow( clippy:: unwrap_used) ]
105- Ok ( ExtPubKey :: new (
106- // unwrap is safe as it is used on an Infallible result type
107- self . public_image_bytes ( ) ?. try_into ( ) . unwrap ( ) ,
108- self . chain_code ,
109- self . derivation_path . clone ( ) ,
110- ) ?)
113+ Ok ( ExtPubKey {
114+ public_key : * self . public_image ( ) . h ,
115+ chain_code : self . chain_code ,
116+ derivation_path : self . derivation_path . clone ( ) ,
117+ } )
111118 }
112119
113120 /// Derive a child extended secret key using the provided index
@@ -126,16 +133,14 @@ impl ExtSecretKey {
126133 let mac_bytes = mac. finalize ( ) . into_bytes ( ) ;
127134 let mut secret_key_bytes = [ 0 ; SecretKeyBytes :: LEN ] ;
128135 secret_key_bytes. copy_from_slice ( & mac_bytes[ ..32 ] ) ;
129- if let Some ( dlog_prover ) = DlogProverInput :: from_bytes ( & secret_key_bytes) {
136+ if let Some ( wscalar ) = Wscalar :: from_bytes ( & secret_key_bytes) {
130137 // parse256(IL) + kpar (mod n).
131138 // via https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions
132- let child_secret_key: DlogProverInput = Wscalar :: from (
133- dlog_prover
134- . w
139+ let child_secret_key = Wscalar :: from (
140+ wscalar
135141 . as_scalar_ref ( )
136- . add ( self . private_input . w . as_scalar_ref ( ) ) ,
137- )
138- . into ( ) ;
142+ . add ( self . private_input . as_scalar_ref ( ) ) ,
143+ ) ;
139144 if child_secret_key. is_zero ( ) {
140145 // ki == 0 case of:
141146 // > In case parse256(IL) ≥ n or ki = 0, the resulting key is invalid, and one
0 commit comments