Skip to content

Commit 7e4b623

Browse files
committed
Randomize secp contexts for marginally better sidechannel resistance
1 parent 5aab4eb commit 7e4b623

File tree

6 files changed

+53
-27
lines changed

6 files changed

+53
-27
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,7 @@ impl<ChanSigner: ChannelKeys> Writeable for ChannelMonitor<ChanSigner> {
949949
}
950950

951951
impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
952-
pub(crate) fn new(keys: ChanSigner, shutdown_pubkey: &PublicKey,
952+
pub(crate) fn new(secp_ctx: Secp256k1<secp256k1::All>, keys: ChanSigner, shutdown_pubkey: &PublicKey,
953953
on_counterparty_tx_csv: u16, destination_script: &Script, funding_info: (OutPoint, Script),
954954
channel_parameters: &ChannelTransactionParameters,
955955
funding_redeemscript: Script, channel_value_satoshis: u64,
@@ -970,8 +970,6 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
970970
let channel_keys_id = keys.channel_keys_id();
971971
let holder_revocation_basepoint = keys.pubkeys().revocation_basepoint;
972972

973-
let secp_ctx = Secp256k1::new();
974-
975973
// block for Rust 1.34 compat
976974
let (holder_commitment_tx, current_holder_commitment_number) = {
977975
let trusted_tx = initial_holder_commitment_tx.trust();
@@ -992,7 +990,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
992990
};
993991

994992
let onchain_tx_handler =
995-
OnchainTxHandler::new(destination_script.clone(), keys, channel_parameters.clone(), initial_holder_commitment_tx);
993+
OnchainTxHandler::new(destination_script.clone(), keys,
994+
channel_parameters.clone(), initial_holder_commitment_tx, secp_ctx.clone());
996995

997996
let mut outputs_to_watch = HashMap::new();
998997
outputs_to_watch.insert(funding_info.0.txid, vec![(funding_info.0.index as u32, funding_info.1.clone())]);
@@ -2540,6 +2539,9 @@ impl<'a, ChanSigner: ChannelKeys, K: KeysInterface<ChanKeySigner = ChanSigner>>
25402539
let lockdown_from_offchain = Readable::read(reader)?;
25412540
let holder_tx_signed = Readable::read(reader)?;
25422541

2542+
let mut secp_ctx = Secp256k1::new();
2543+
secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
2544+
25432545
Ok((last_block_hash.clone(), ChannelMonitor {
25442546
latest_update_id,
25452547
commitment_transaction_number_obscure_factor,
@@ -2585,7 +2587,7 @@ impl<'a, ChanSigner: ChannelKeys, K: KeysInterface<ChanKeySigner = ChanSigner>>
25852587
holder_tx_signed,
25862588

25872589
last_block_hash,
2588-
secp_ctx: Secp256k1::new(),
2590+
secp_ctx,
25892591
}))
25902592
}
25912593
}
@@ -2700,7 +2702,7 @@ mod tests {
27002702
};
27012703
// Prune with one old state and a holder commitment tx holding a few overlaps with the
27022704
// old state.
2703-
let mut monitor = ChannelMonitor::new(keys,
2705+
let mut monitor = ChannelMonitor::new(Secp256k1::new(), keys,
27042706
&PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()), 0, &Script::new(),
27052707
(OutPoint { txid: Txid::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()),
27062708
&channel_parameters,

lightning/src/chain/keysinterface.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -744,8 +744,10 @@ pub struct KeysManager {
744744
shutdown_pubkey: PublicKey,
745745
channel_master_key: ExtendedPrivKey,
746746
channel_child_index: AtomicUsize,
747+
747748
rand_bytes_master_key: ExtendedPrivKey,
748749
rand_bytes_child_index: AtomicUsize,
750+
rand_bytes_unique_start: Sha256State,
749751

750752
seed: [u8; 32],
751753
starting_time_secs: u64,
@@ -794,31 +796,37 @@ impl KeysManager {
794796
let channel_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3).unwrap()).expect("Your RNG is busted");
795797
let rand_bytes_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(4).unwrap()).expect("Your RNG is busted");
796798

797-
KeysManager {
799+
let mut rand_bytes_unique_start = Sha256::engine();
800+
rand_bytes_unique_start.input(&byte_utils::be64_to_array(starting_time_secs));
801+
rand_bytes_unique_start.input(&byte_utils::be32_to_array(starting_time_nanos));
802+
rand_bytes_unique_start.input(seed);
803+
804+
let mut res = KeysManager {
798805
secp_ctx,
799806
node_secret,
807+
800808
destination_script,
801809
shutdown_pubkey,
810+
802811
channel_master_key,
803812
channel_child_index: AtomicUsize::new(0),
813+
804814
rand_bytes_master_key,
805815
rand_bytes_child_index: AtomicUsize::new(0),
816+
rand_bytes_unique_start,
806817

807818
seed: *seed,
808819
starting_time_secs,
809820
starting_time_nanos,
810-
}
821+
};
822+
let secp_seed = res.get_secure_random_bytes();
823+
res.secp_ctx.seeded_randomize(&secp_seed);
824+
res
811825
},
812826
Err(_) => panic!("Your rng is busted"),
813827
}
814828
}
815-
fn derive_unique_start(&self) -> Sha256State {
816-
let mut unique_start = Sha256::engine();
817-
unique_start.input(&byte_utils::be64_to_array(self.starting_time_secs));
818-
unique_start.input(&byte_utils::be32_to_array(self.starting_time_nanos));
819-
unique_start.input(&self.seed);
820-
unique_start
821-
}
829+
822830
/// Derive an old set of ChannelKeys for per-channel secrets based on a key derivation
823831
/// parameters.
824832
/// Key derivation parameters are accessible through a per-channel secrets
@@ -1017,7 +1025,7 @@ impl KeysInterface for KeysManager {
10171025
}
10181026

10191027
fn get_secure_random_bytes(&self) -> [u8; 32] {
1020-
let mut sha = self.derive_unique_start();
1028+
let mut sha = self.rand_bytes_unique_start.clone();
10211029

10221030
let child_ix = self.rand_bytes_child_index.fetch_add(1, Ordering::AcqRel);
10231031
let child_privkey = self.rand_bytes_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");

lightning/src/ln/channel.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -523,13 +523,16 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
523523

524524
let feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
525525

526+
let mut secp_ctx = Secp256k1::new();
527+
secp_ctx.seeded_randomize(&keys_provider.get_secure_random_bytes());
528+
526529
Ok(Channel {
527530
user_id,
528531
config: config.channel_options.clone(),
529532

530533
channel_id: keys_provider.get_secure_random_bytes(),
531534
channel_state: ChannelState::OurInitSent as u32,
532-
secp_ctx: Secp256k1::new(),
535+
secp_ctx,
533536
channel_value_satoshis,
534537

535538
latest_monitor_update_id: 0,
@@ -758,13 +761,16 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
758761
}
759762
} else { None };
760763

764+
let mut secp_ctx = Secp256k1::new();
765+
secp_ctx.seeded_randomize(&keys_provider.get_secure_random_bytes());
766+
761767
let chan = Channel {
762768
user_id,
763769
config: local_config,
764770

765771
channel_id: msg.temporary_channel_id,
766772
channel_state: (ChannelState::OurInitSent as u32) | (ChannelState::TheirInitSent as u32),
767-
secp_ctx: Secp256k1::new(),
773+
secp_ctx,
768774

769775
latest_monitor_update_id: 0,
770776

@@ -1568,7 +1574,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
15681574
let funding_redeemscript = self.get_funding_redeemscript();
15691575
let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
15701576
let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound());
1571-
let mut channel_monitor = ChannelMonitor::new(self.holder_keys.clone(),
1577+
let mut channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), self.holder_keys.clone(),
15721578
&self.shutdown_pubkey, self.get_holder_selected_contest_delay(),
15731579
&self.destination_script, (funding_txo, funding_txo_script.clone()),
15741580
&self.channel_transaction_parameters,
@@ -1638,7 +1644,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
16381644
let funding_txo = self.get_funding_txo().unwrap();
16391645
let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
16401646
let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound());
1641-
let mut channel_monitor = ChannelMonitor::new(self.holder_keys.clone(),
1647+
let mut channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), self.holder_keys.clone(),
16421648
&self.shutdown_pubkey, self.get_holder_selected_contest_delay(),
16431649
&self.destination_script, (funding_txo, funding_txo_script),
16441650
&self.channel_transaction_parameters,
@@ -4601,13 +4607,16 @@ impl<'a, ChanSigner: ChannelKeys, K: Deref> ReadableArgs<&'a K> for Channel<Chan
46014607
let counterparty_shutdown_scriptpubkey = Readable::read(reader)?;
46024608
let commitment_secrets = Readable::read(reader)?;
46034609

4610+
let mut secp_ctx = Secp256k1::new();
4611+
secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
4612+
46044613
Ok(Channel {
46054614
user_id,
46064615

46074616
config,
46084617
channel_id,
46094618
channel_state,
4610-
secp_ctx: Secp256k1::new(),
4619+
secp_ctx,
46114620
channel_value_satoshis,
46124621

46134622
latest_monitor_update_id,

lightning/src/ln/channelmanager.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,8 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
766766
/// Users need to notify the new ChannelManager when a new block is connected or
767767
/// disconnected using its `block_connected` and `block_disconnected` methods.
768768
pub fn new(network: Network, fee_est: F, chain_monitor: M, tx_broadcaster: T, logger: L, keys_manager: K, config: UserConfig, current_blockchain_height: usize) -> Self {
769-
let secp_ctx = Secp256k1::new();
769+
let mut secp_ctx = Secp256k1::new();
770+
secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
770771

771772
ChannelManager {
772773
default_configuration: config.clone(),
@@ -4111,6 +4112,9 @@ impl<'a, ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Der
41114112

41124113
let last_node_announcement_serial: u32 = Readable::read(reader)?;
41134114

4115+
let mut secp_ctx = Secp256k1::new();
4116+
secp_ctx.seeded_randomize(&args.keys_manager.get_secure_random_bytes());
4117+
41144118
let channel_manager = ChannelManager {
41154119
genesis_hash,
41164120
fee_estimator: args.fee_estimator,
@@ -4119,7 +4123,7 @@ impl<'a, ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Der
41194123

41204124
latest_block_height: AtomicUsize::new(latest_block_height as usize),
41214125
last_block_hash: Mutex::new(last_block_hash),
4122-
secp_ctx: Secp256k1::new(),
4126+
secp_ctx,
41234127

41244128
channel_state: Mutex::new(ChannelHolder {
41254129
by_id,

lightning/src/ln/onchaintx.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,9 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K> for OnchainTxHandler<K::ChanKeySi
406406
}
407407
let latest_height = Readable::read(reader)?;
408408

409+
let mut secp_ctx = Secp256k1::new();
410+
secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
411+
409412
Ok(OnchainTxHandler {
410413
destination_script,
411414
holder_commitment,
@@ -418,13 +421,13 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K> for OnchainTxHandler<K::ChanKeySi
418421
pending_claim_requests,
419422
onchain_events_waiting_threshold_conf,
420423
latest_height,
421-
secp_ctx: Secp256k1::new(),
424+
secp_ctx,
422425
})
423426
}
424427
}
425428

426429
impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
427-
pub(crate) fn new(destination_script: Script, keys: ChanSigner, channel_parameters: ChannelTransactionParameters, holder_commitment: HolderCommitmentTransaction) -> Self {
430+
pub(crate) fn new(destination_script: Script, keys: ChanSigner, channel_parameters: ChannelTransactionParameters, holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>) -> Self {
428431

429432
let key_storage = keys;
430433

@@ -441,7 +444,7 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
441444
onchain_events_waiting_threshold_conf: HashMap::new(),
442445
latest_height: 0,
443446

444-
secp_ctx: Secp256k1::new(),
447+
secp_ctx,
445448
}
446449
}
447450

lightning/src/util/test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl keysinterface::KeysInterface for OnlyReadsKeysInterface {
6969
fn get_destination_script(&self) -> Script { unreachable!(); }
7070
fn get_shutdown_pubkey(&self) -> PublicKey { unreachable!(); }
7171
fn get_channel_keys(&self, _inbound: bool, _channel_value_satoshis: u64) -> EnforcingChannelKeys { unreachable!(); }
72-
fn get_secure_random_bytes(&self) -> [u8; 32] { unreachable!(); }
72+
fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
7373

7474
fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::ChanKeySigner, msgs::DecodeError> {
7575
EnforcingChannelKeys::read(&mut std::io::Cursor::new(reader))

0 commit comments

Comments
 (0)