1
1
//! Extended private key operations according to BIP-32
2
- use core:: convert:: TryInto ;
3
-
4
2
use super :: {
5
3
derivation_path:: { ChildIndex , ChildIndexError , DerivationPath } ,
6
4
ext_pub_key:: ExtPubKey ,
@@ -28,14 +26,23 @@ type HmacSha512 = Hmac<Sha512>;
28
26
29
27
/// Extended secret key
30
28
/// implemented according to BIP-32
31
- #[ derive( PartialEq , Eq , Debug , Clone ) ]
29
+ #[ derive( PartialEq , Eq , Clone ) ]
32
30
pub struct ExtSecretKey {
33
- /// The secret key
34
- private_input : DlogProverInput ,
31
+ private_input : Wscalar ,
35
32
chain_code : ChainCode ,
36
33
derivation_path : DerivationPath ,
37
34
}
38
35
36
+ impl core:: fmt:: Debug for ExtSecretKey {
37
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: 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
+
39
46
/// Extended secret key errors
40
47
#[ derive( Error , PartialEq , Eq , Debug , Clone ) ]
41
48
pub enum ExtSecretKeyError {
@@ -66,8 +73,8 @@ impl ExtSecretKey {
66
73
chain_code : ChainCode ,
67
74
derivation_path : DerivationPath ,
68
75
) -> Result < Self , ExtSecretKeyError > {
69
- let private_input = DlogProverInput :: from_bytes ( & secret_key_bytes )
70
- . ok_or ( ExtSecretKeyError :: ScalarEncodingError ) ?;
76
+ let private_input =
77
+ Wscalar :: from_bytes ( & secret_key_bytes ) . ok_or ( ExtSecretKeyError :: ScalarEncodingError ) ?;
71
78
Ok ( Self {
72
79
private_input,
73
80
chain_code,
@@ -82,7 +89,7 @@ impl ExtSecretKey {
82
89
83
90
/// Returns secret key
84
91
pub fn secret_key ( & self ) -> SecretKey {
85
- self . private_input . clone ( ) . into ( )
92
+ DlogProverInput :: new ( self . private_input . clone ( ) ) . into ( )
86
93
}
87
94
88
95
/// Byte representation of the underlying scalar
@@ -92,7 +99,7 @@ impl ExtSecretKey {
92
99
93
100
/// Public image associated with the private input
94
101
pub fn public_image ( & self ) -> ProveDlog {
95
- self . private_input . public_image ( )
102
+ DlogProverInput :: new ( self . private_input . clone ( ) ) . public_image ( )
96
103
}
97
104
98
105
/// Public image bytes in SEC-1 encoded & compressed format
@@ -103,12 +110,11 @@ impl ExtSecretKey {
103
110
/// The extended public key associated with this secret key
104
111
pub fn public_key ( & self ) -> Result < ExtPubKey , ExtSecretKeyError > {
105
112
#[ allow( clippy:: unwrap_used) ]
106
- Ok ( ExtPubKey :: new (
107
- // unwrap is safe as it is used on an Infallible result type
108
- self . public_image_bytes ( ) ?. try_into ( ) . unwrap ( ) ,
109
- self . chain_code ,
110
- self . derivation_path . clone ( ) ,
111
- ) ?)
113
+ Ok ( ExtPubKey {
114
+ public_key : * self . public_image ( ) . h ,
115
+ chain_code : self . chain_code ,
116
+ derivation_path : self . derivation_path . clone ( ) ,
117
+ } )
112
118
}
113
119
114
120
/// Derive a child extended secret key using the provided index
@@ -127,16 +133,14 @@ impl ExtSecretKey {
127
133
let mac_bytes = mac. finalize ( ) . into_bytes ( ) ;
128
134
let mut secret_key_bytes = [ 0 ; SecretKeyBytes :: LEN ] ;
129
135
secret_key_bytes. copy_from_slice ( & mac_bytes[ ..32 ] ) ;
130
- if let Some ( dlog_prover ) = DlogProverInput :: from_bytes ( & secret_key_bytes) {
136
+ if let Some ( wscalar ) = Wscalar :: from_bytes ( & secret_key_bytes) {
131
137
// parse256(IL) + kpar (mod n).
132
138
// via https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions
133
- let child_secret_key: DlogProverInput = Wscalar :: from (
134
- dlog_prover
135
- . w
139
+ let child_secret_key = Wscalar :: from (
140
+ wscalar
136
141
. as_scalar_ref ( )
137
- . add ( self . private_input . w . as_scalar_ref ( ) ) ,
138
- )
139
- . into ( ) ;
142
+ . add ( self . private_input . as_scalar_ref ( ) ) ,
143
+ ) ;
140
144
if child_secret_key. is_zero ( ) {
141
145
// ki == 0 case of:
142
146
// > In case parse256(IL) ≥ n or ki = 0, the resulting key is invalid, and one
0 commit comments