@@ -14,11 +14,16 @@ use secp256k1::Secp256k1;
14
14
use secp256k1;
15
15
16
16
use crypto:: hkdf:: { hkdf_extract, hkdf_expand} ;
17
+ use crypto:: digest:: Digest ;
17
18
18
19
use util:: sha2:: Sha256 ;
19
20
use util:: logger:: Logger ;
21
+ use util:: rng;
22
+ use util:: byte_utils;
20
23
24
+ use std:: time:: { SystemTime , UNIX_EPOCH } ;
21
25
use std:: sync:: Arc ;
26
+ use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
22
27
23
28
/// When on-chain outputs are created by rust-lightning an event is generated which informs the
24
29
/// user thereof. This enum describes the format of the output and provides the OutPoint.
@@ -39,7 +44,7 @@ pub enum SpendableOutputDescriptor {
39
44
DynamicOutput {
40
45
/// Outpoint spendable by user wallet
41
46
outpoint : OutPoint ,
42
- /// local_delayedkey = delayed_payment_basepoint_secret + SHA256(per_commitment_point || delayed_payment_basepoint
47
+ /// local_delayedkey = delayed_payment_basepoint_secret + SHA256(per_commitment_point || delayed_payment_basepoint)
43
48
local_delayedkey : SecretKey ,
44
49
/// witness redeemScript encumbering output
45
50
witness_script : Script ,
@@ -137,6 +142,7 @@ pub struct KeysManager {
137
142
destination_script : Script ,
138
143
shutdown_pubkey : PublicKey ,
139
144
channel_master_key : ExtendedPrivKey ,
145
+ channel_child_index : AtomicUsize ,
140
146
141
147
logger : Arc < Logger > ,
142
148
}
@@ -169,6 +175,7 @@ impl KeysManager {
169
175
destination_script,
170
176
shutdown_pubkey,
171
177
channel_master_key,
178
+ channel_child_index : AtomicUsize :: new ( 0 ) ,
172
179
173
180
logger,
174
181
}
@@ -192,11 +199,25 @@ impl KeysInterface for KeysManager {
192
199
}
193
200
194
201
fn get_channel_keys ( & self , _inbound : bool ) -> ChannelKeys {
195
- let channel_pubkey = ExtendedPubKey :: from_private ( & self . secp_ctx , & self . channel_master_key ) ;
196
- let mut seed = [ 0 ; 32 ] ;
197
- for ( arr, slice) in seed. iter_mut ( ) . zip ( ( & channel_pubkey. public_key . serialize ( ) [ 0 ..32 ] ) . iter ( ) ) {
198
- * arr = * slice;
199
- }
202
+ // We only seriously intend to rely on the channel_master_key for true secure
203
+ // entropy, everything else just ensures uniqueness. We generally don't expect
204
+ // all clients to have non-broken RNGs here, so we also include the current
205
+ // time as a fallback to get uniqueness.
206
+ let mut sha = Sha256 :: new ( ) ;
207
+
208
+ let mut seed = [ 0u8 ; 32 ] ;
209
+ rng:: fill_bytes ( & mut seed[ ..] ) ;
210
+ sha. input ( & seed) ;
211
+
212
+ let now = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . expect ( "Time went backwards" ) ;
213
+ sha. input ( & byte_utils:: be32_to_array ( now. subsec_nanos ( ) ) ) ;
214
+ sha. input ( & byte_utils:: be64_to_array ( now. as_secs ( ) ) ) ;
215
+
216
+ let child_ix = self . channel_child_index . fetch_add ( 1 , Ordering :: AcqRel ) ;
217
+ let child_privkey = self . channel_master_key . ckd_priv ( & self . secp_ctx , ChildNumber :: from_hardened_idx ( child_ix as u32 ) ) . expect ( "Your RNG is busted" ) ;
218
+ sha. input ( & child_privkey. secret_key [ ..] ) ;
219
+
220
+ sha. result ( & mut seed) ;
200
221
ChannelKeys :: new_from_seed ( & seed)
201
222
}
202
223
}
0 commit comments