Skip to content

Commit b035377

Browse files
committed
Randomize secp contexts for marginally better sidechannel resistance
1 parent 30dc938 commit b035377

File tree

6 files changed

+52
-27
lines changed

6 files changed

+52
-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<Signer: Sign> Writeable for ChannelMonitor<Signer> {
949949
}
950950

951951
impl<Signer: Sign> ChannelMonitor<Signer> {
952-
pub(crate) fn new(keys: Signer, shutdown_pubkey: &PublicKey,
952+
pub(crate) fn new(secp_ctx: Secp256k1<secp256k1::All>, keys: Signer, 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<Signer: Sign> ChannelMonitor<Signer> {
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<Signer: Sign> ChannelMonitor<Signer> {
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, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
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, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
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: 17 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,36 @@ 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-
}
822829
/// Derive an old set of Sign for per-channel secrets based on a key derivation
823830
/// parameters.
824831
/// Key derivation parameters are accessible through a per-channel secrets
@@ -1017,7 +1024,7 @@ impl KeysInterface for KeysManager {
10171024
}
10181025

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

10221029
let child_ix = self.rand_bytes_child_index.fetch_add(1, Ordering::AcqRel);
10231030
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
@@ -520,13 +520,16 @@ impl<Signer: Sign> Channel<Signer> {
520520

521521
let feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
522522

523+
let mut secp_ctx = Secp256k1::new();
524+
secp_ctx.seeded_randomize(&keys_provider.get_secure_random_bytes());
525+
523526
Ok(Channel {
524527
user_id,
525528
config: config.channel_options.clone(),
526529

527530
channel_id: keys_provider.get_secure_random_bytes(),
528531
channel_state: ChannelState::OurInitSent as u32,
529-
secp_ctx: Secp256k1::new(),
532+
secp_ctx,
530533
channel_value_satoshis,
531534

532535
latest_monitor_update_id: 0,
@@ -755,13 +758,16 @@ impl<Signer: Sign> Channel<Signer> {
755758
}
756759
} else { None };
757760

761+
let mut secp_ctx = Secp256k1::new();
762+
secp_ctx.seeded_randomize(&keys_provider.get_secure_random_bytes());
763+
758764
let chan = Channel {
759765
user_id,
760766
config: local_config,
761767

762768
channel_id: msg.temporary_channel_id,
763769
channel_state: (ChannelState::OurInitSent as u32) | (ChannelState::TheirInitSent as u32),
764-
secp_ctx: Secp256k1::new(),
770+
secp_ctx,
765771

766772
latest_monitor_update_id: 0,
767773

@@ -1565,7 +1571,7 @@ impl<Signer: Sign> Channel<Signer> {
15651571
let funding_redeemscript = self.get_funding_redeemscript();
15661572
let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
15671573
let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound());
1568-
let mut channel_monitor = ChannelMonitor::new(self.holder_signer.clone(),
1574+
let mut channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), self.holder_signer.clone(),
15691575
&self.shutdown_pubkey, self.get_holder_selected_contest_delay(),
15701576
&self.destination_script, (funding_txo, funding_txo_script.clone()),
15711577
&self.channel_transaction_parameters,
@@ -1635,7 +1641,7 @@ impl<Signer: Sign> Channel<Signer> {
16351641
let funding_txo = self.get_funding_txo().unwrap();
16361642
let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
16371643
let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound());
1638-
let mut channel_monitor = ChannelMonitor::new(self.holder_signer.clone(),
1644+
let mut channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), self.holder_signer.clone(),
16391645
&self.shutdown_pubkey, self.get_holder_selected_contest_delay(),
16401646
&self.destination_script, (funding_txo, funding_txo_script),
16411647
&self.channel_transaction_parameters,
@@ -4598,13 +4604,16 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
45984604
let counterparty_shutdown_scriptpubkey = Readable::read(reader)?;
45994605
let commitment_secrets = Readable::read(reader)?;
46004606

4607+
let mut secp_ctx = Secp256k1::new();
4608+
secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
4609+
46014610
Ok(Channel {
46024611
user_id,
46034612

46044613
config,
46054614
channel_id,
46064615
channel_state,
4607-
secp_ctx: Secp256k1::new(),
4616+
secp_ctx,
46084617
channel_value_satoshis,
46094618

46104619
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<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
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, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
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, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
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::Signer> {
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::Signer> {
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<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
427-
pub(crate) fn new(destination_script: Script, signer: ChannelSigner, channel_parameters: ChannelTransactionParameters, holder_commitment: HolderCommitmentTransaction) -> Self {
430+
pub(crate) fn new(destination_script: Script, signer: ChannelSigner, channel_parameters: ChannelTransactionParameters, holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>) -> Self {
428431
OnchainTxHandler {
429432
destination_script,
430433
holder_commitment,
@@ -438,7 +441,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
438441
onchain_events_waiting_threshold_conf: HashMap::new(),
439442
latest_height: 0,
440443

441-
secp_ctx: Secp256k1::new(),
444+
secp_ctx,
442445
}
443446
}
444447

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_signer(&self, _inbound: bool, _channel_value_satoshis: u64) -> EnforcingSigner { 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::Signer, msgs::DecodeError> {
7575
EnforcingSigner::read(&mut std::io::Cursor::new(reader))

0 commit comments

Comments
 (0)