]> git.bitcoin.ninja Git - rust-lightning/commitdiff
ChannelKeys provides individual commitment secrets
authorDevrandom <c1.devrandom@niftybox.net>
Wed, 1 Jul 2020 10:31:53 +0000 (03:31 -0700)
committerDevrandom <c1.devrandom@niftybox.net>
Wed, 1 Jul 2020 18:54:56 +0000 (11:54 -0700)
lightning/src/chain/keysinterface.rs
lightning/src/ln/chan_utils.rs
lightning/src/ln/channel.rs
lightning/src/ln/functional_tests.rs
lightning/src/util/enforcing_trait_impls.rs

index c4045e9c60c4e96aa6989ab0cb48f4e90ed992e4..9e5d362bb0af65897db621dd1d65883d976398bc 100644 (file)
@@ -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 }
 
index 20ebc3520bfd670db5b71ed32b8b5577bf52d3ad..d780c33c1462b28f322356e28a27788d1fa99c10 100644 (file)
@@ -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;
index 97c9fa6789b3c4a2045539281c27b1a28cf1d0b4..c95d6e73fe25227e2062f8c865b2a5db61583618 100644 (file)
@@ -783,7 +783,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
        // 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<ChanSigner: ChannelKeys> Channel<ChanSigner> {
                }
 
                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<ChanSigner: ChannelKeys> Channel<ChanSigner> {
 
        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<ChanSigner: ChannelKeys> Channel<ChanSigner> {
                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 {
index 0200ece21734b66f184336efb0ec9c8768988bde..5e8edb3ca5e602adfac4ad94878dae7fa44e4e3a 100644 (file)
@@ -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 });
index ee66d5f3ab81d54d77456d5026d7fe98479a567b..88cdd94afb8de227c2475fe16de4d5b1b130818c 100644 (file)
@@ -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() }