From: Devrandom Date: Wed, 1 Jul 2020 10:31:53 +0000 (-0700) Subject: ChannelKeys provides individual commitment secrets X-Git-Tag: v0.0.12~51^2 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=1d37f56f8a9de6120198e723e5a2daaefcbcaf20;hp=cd13364d442faa1bb4edc433112e4000cbaf0d94;p=rust-lightning ChannelKeys provides individual commitment secrets --- diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index c4045e9c..9e5d362b 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -195,8 +195,9 @@ impl Readable for SpendableOutputDescriptor { // TODO: We should remove Clone by instead requesting a new ChannelKeys copy when we create // ChannelMonitors instead of expecting to clone the one out of the Channel into the monitors. pub trait ChannelKeys : Send+Clone { - /// Gets the commitment seed - fn commitment_seed(&self) -> &[u8; 32]; + /// Gets the commitment seed for a specific commitment number + /// Note that the commitment number starts at (1 << 48) - 1 and counts backwards + fn commitment_secret(&self, idx: u64) -> [u8; 32]; /// Gets the local channel public keys and basepoints fn pubkeys(&self) -> &ChannelPublicKeys; /// Gets arbitrary identifiers describing the set of keys which are provided back to you in @@ -404,7 +405,10 @@ impl InMemoryChannelKeys { } impl ChannelKeys for InMemoryChannelKeys { - fn commitment_seed(&self) -> &[u8; 32] { &self.commitment_seed } + fn commitment_secret(&self, idx: u64) -> [u8; 32] { + chan_utils::build_commitment_secret(&self.commitment_seed, idx) + } + fn pubkeys(&self) -> &ChannelPublicKeys { &self.local_channel_pubkeys } fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params } diff --git a/lightning/src/ln/chan_utils.rs b/lightning/src/ln/chan_utils.rs index 20ebc352..d780c33c 100644 --- a/lightning/src/ln/chan_utils.rs +++ b/lightning/src/ln/chan_utils.rs @@ -52,7 +52,8 @@ impl HTLCType { // Various functions for key derivation and transaction creation for use within channels. Primarily // used in Channel and ChannelMonitor. -pub(super) fn build_commitment_secret(commitment_seed: &[u8; 32], idx: u64) -> [u8; 32] { +/// Build the commitment secret from the seed and the commitment number +pub fn build_commitment_secret(commitment_seed: &[u8; 32], idx: u64) -> [u8; 32] { let mut res: [u8; 32] = commitment_seed.clone(); for i in 0..48 { let bitpos = 47 - i; diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 97c9fa67..c95d6e73 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -783,7 +783,7 @@ impl Channel { // Utilities to derive keys: fn build_local_commitment_secret(&self, idx: u64) -> SecretKey { - let res = chan_utils::build_commitment_secret(self.local_keys.commitment_seed(), idx); + let res = self.local_keys.commitment_secret(idx); SecretKey::from_slice(&res).unwrap() } @@ -2021,7 +2021,7 @@ impl Channel { } let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number - 1)); - let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed(), self.cur_local_commitment_transaction_number + 1); + let per_commitment_secret = self.local_keys.commitment_secret(self.cur_local_commitment_transaction_number + 1); // Update state now that we've passed all the can-fail calls... let mut need_our_commitment = false; @@ -2660,7 +2660,7 @@ impl Channel { fn get_last_revoke_and_ack(&self) -> msgs::RevokeAndACK { let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number)); - let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed(), self.cur_local_commitment_transaction_number + 2); + let per_commitment_secret = self.local_keys.commitment_secret(self.cur_local_commitment_transaction_number + 2); msgs::RevokeAndACK { channel_id: self.channel_id, per_commitment_secret, @@ -2743,7 +2743,7 @@ impl Channel { if msg.next_remote_commitment_number > 0 { match msg.data_loss_protect { OptionalField::Present(ref data_loss) => { - if chan_utils::build_commitment_secret(self.local_keys.commitment_seed(), INITIAL_COMMITMENT_NUMBER - msg.next_remote_commitment_number + 1) != data_loss.your_last_per_commitment_secret { + if self.local_keys.commitment_secret(INITIAL_COMMITMENT_NUMBER - msg.next_remote_commitment_number + 1) != data_loss.your_last_per_commitment_secret { return Err(ChannelError::Close("Peer sent a garbage channel_reestablish with secret key not matching the commitment height provided")); } if msg.next_remote_commitment_number > INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number { diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 0200ece2..5e8edb3c 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -1599,29 +1599,29 @@ fn test_fee_spike_violation_fails_htlc() { let feerate_per_kw = get_feerate!(nodes[0], chan.2); + const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1; + // Get the EnforcingChannelKeys for each channel, which will be used to (1) get the keys // needed to sign the new commitment tx and (2) sign the new commitment tx. - let (local_revocation_basepoint, local_htlc_basepoint, local_payment_point, local_chan_commitment_seed) = { + let (local_revocation_basepoint, local_htlc_basepoint, local_payment_point, local_secret, local_secret2) = { let chan_lock = nodes[0].node.channel_state.lock().unwrap(); let local_chan = chan_lock.by_id.get(&chan.2).unwrap(); let chan_keys = local_chan.get_local_keys(); let pubkeys = chan_keys.pubkeys(); - (pubkeys.revocation_basepoint, pubkeys.htlc_basepoint, pubkeys.payment_point, *chan_keys.commitment_seed()) + (pubkeys.revocation_basepoint, pubkeys.htlc_basepoint, pubkeys.payment_point, + chan_keys.commitment_secret(INITIAL_COMMITMENT_NUMBER), chan_keys.commitment_secret(INITIAL_COMMITMENT_NUMBER - 2)) }; - let (remote_delayed_payment_basepoint, remote_htlc_basepoint, remote_payment_point, remote_chan_commitment_seed) = { + let (remote_delayed_payment_basepoint, remote_htlc_basepoint, remote_payment_point, remote_secret1) = { let chan_lock = nodes[1].node.channel_state.lock().unwrap(); let remote_chan = chan_lock.by_id.get(&chan.2).unwrap(); let chan_keys = remote_chan.get_local_keys(); let pubkeys = chan_keys.pubkeys(); - (pubkeys.delayed_payment_basepoint, pubkeys.htlc_basepoint, pubkeys.payment_point, *chan_keys.commitment_seed()) + (pubkeys.delayed_payment_basepoint, pubkeys.htlc_basepoint, pubkeys.payment_point, + chan_keys.commitment_secret(INITIAL_COMMITMENT_NUMBER - 1)) }; // Assemble the set of keys we can use for signatures for our commitment_signed message. - const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1; - let commitment_secret = { - let res = chan_utils::build_commitment_secret(&remote_chan_commitment_seed, INITIAL_COMMITMENT_NUMBER - 1); - SecretKey::from_slice(&res).unwrap() - }; + let commitment_secret = SecretKey::from_slice(&remote_secret1).unwrap(); let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &commitment_secret); let commit_tx_keys = chan_utils::TxCreationKeys::new(&secp_ctx, &per_commitment_point, &remote_delayed_payment_basepoint, &remote_htlc_basepoint, &local_revocation_basepoint, &local_htlc_basepoint).unwrap(); @@ -1706,8 +1706,8 @@ fn test_fee_spike_violation_fails_htlc() { let _ = nodes[1].node.get_and_clear_pending_msg_events(); // Send the RAA to nodes[1]. - let per_commitment_secret = chan_utils::build_commitment_secret(&local_chan_commitment_seed, INITIAL_COMMITMENT_NUMBER); - let next_secret = SecretKey::from_slice(&chan_utils::build_commitment_secret(&local_chan_commitment_seed, INITIAL_COMMITMENT_NUMBER - 2)).unwrap(); + let per_commitment_secret = local_secret; + let next_secret = SecretKey::from_slice(&local_secret2).unwrap(); let next_per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &next_secret); let raa_msg = msgs::RevokeAndACK{ channel_id: chan.2, per_commitment_secret, next_per_commitment_point}; nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &raa_msg); @@ -8125,11 +8125,12 @@ fn test_counterparty_raa_skip_no_crash() { let nodes = create_network(2, &node_cfgs, &node_chanmgrs); let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2; - let commitment_seed = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&channel_id).unwrap().local_keys.commitment_seed().clone(); + let mut guard = nodes[0].node.channel_state.lock().unwrap(); + let local_keys = &guard.by_id.get_mut(&channel_id).unwrap().local_keys; const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1; let next_per_commitment_point = PublicKey::from_secret_key(&Secp256k1::new(), - &SecretKey::from_slice(&chan_utils::build_commitment_secret(&commitment_seed, INITIAL_COMMITMENT_NUMBER - 2)).unwrap()); - let per_commitment_secret = chan_utils::build_commitment_secret(&commitment_seed, INITIAL_COMMITMENT_NUMBER); + &SecretKey::from_slice(&local_keys.commitment_secret(INITIAL_COMMITMENT_NUMBER - 2)).unwrap()); + let per_commitment_secret = local_keys.commitment_secret(INITIAL_COMMITMENT_NUMBER); nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &msgs::RevokeAndACK { channel_id, per_commitment_secret, next_per_commitment_point }); diff --git a/lightning/src/util/enforcing_trait_impls.rs b/lightning/src/util/enforcing_trait_impls.rs index ee66d5f3..88cdd94a 100644 --- a/lightning/src/util/enforcing_trait_impls.rs +++ b/lightning/src/util/enforcing_trait_impls.rs @@ -48,7 +48,7 @@ impl EnforcingChannelKeys { } impl ChannelKeys for EnforcingChannelKeys { - fn commitment_seed(&self) -> &[u8; 32] { self.inner.commitment_seed() } + fn commitment_secret(&self, idx: u64) -> [u8; 32] { self.inner.commitment_secret(idx) } fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() } fn key_derivation_params(&self) -> (u64, u64) { self.inner.key_derivation_params() }