Downgrade `hashbrown` to meet MSRV
[rust-lightning] / lightning / src / chain / keysinterface.rs
index 33c88cf11e38c672d6394bd3027b89b8664bbf0b..73b8a1b98224ace7aef2f6db05a82ca2a020e476 100644 (file)
@@ -25,10 +25,11 @@ use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hash_types::WPubkeyHash;
 
-use bitcoin::secp256k1::{SecretKey, PublicKey};
+use bitcoin::secp256k1::{SecretKey, PublicKey, Scalar};
 use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature, Signing};
+use bitcoin::secp256k1::ecdh::SharedSecret;
 use bitcoin::secp256k1::ecdsa::RecoverableSignature;
-use bitcoin::{secp256k1, Witness};
+use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness};
 
 use util::{byte_utils, transaction_utils};
 use util::crypto::{hkdf_extract_expand_twice, sign};
@@ -397,11 +398,19 @@ pub trait KeysInterface {
        /// A type which implements Sign which will be returned by get_channel_signer.
        type Signer : Sign;
 
-       /// Get node secret key (aka node_id or network_key) based on the provided [`Recipient`].
+       /// Get node secret key based on the provided [`Recipient`].
+       ///
+       /// The node_id/network_key is the public key that corresponds to this secret key.
        ///
        /// This method must return the same value each time it is called with a given `Recipient`
        /// parameter.
        fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()>;
+       /// Gets the ECDH shared secret of our [`node secret`] and `other_key`, multiplying by `tweak` if
+       /// one is provided. Note that this tweak can be applied to `other_key` instead of our node
+       /// secret, though this is less efficient.
+       ///
+       /// [`node secret`]: Self::get_node_secret
+       fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()>;
        /// Get a script pubkey which we send funds to when claiming on-chain contestable outputs.
        ///
        /// This method should return a different value each time it is called, to avoid linking
@@ -617,7 +626,7 @@ impl InMemorySigner {
                if spend_tx.input.len() <= input_idx { return Err(()); }
                if !spend_tx.input[input_idx].script_sig.is_empty() { return Err(()); }
                if spend_tx.input[input_idx].previous_output != descriptor.outpoint.into_bitcoin_outpoint() { return Err(()); }
-               if spend_tx.input[input_idx].sequence != descriptor.to_self_delay as u32 { return Err(()); }
+               if spend_tx.input[input_idx].sequence.0 != descriptor.to_self_delay as u32 { return Err(()); }
 
                let delayed_payment_key = chan_utils::derive_private_key(&secp_ctx, &descriptor.per_commitment_point, &self.delayed_payment_base_key)
                        .expect("We constructed the payment_base_key, so we can only fail here if the RNG is busted.");
@@ -1013,7 +1022,7 @@ impl KeysManager {
                                        input.push(TxIn {
                                                previous_output: descriptor.outpoint.into_bitcoin_outpoint(),
                                                script_sig: Script::new(),
-                                               sequence: 0,
+                                               sequence: Sequence::ZERO,
                                                witness: Witness::new(),
                                        });
                                        witness_weight += StaticPaymentOutputDescriptor::MAX_WITNESS_LENGTH;
@@ -1024,7 +1033,7 @@ impl KeysManager {
                                        input.push(TxIn {
                                                previous_output: descriptor.outpoint.into_bitcoin_outpoint(),
                                                script_sig: Script::new(),
-                                               sequence: descriptor.to_self_delay as u32,
+                                               sequence: Sequence(descriptor.to_self_delay as u32),
                                                witness: Witness::new(),
                                        });
                                        witness_weight += DelayedPaymentOutputDescriptor::MAX_WITNESS_LENGTH;
@@ -1035,7 +1044,7 @@ impl KeysManager {
                                        input.push(TxIn {
                                                previous_output: outpoint.into_bitcoin_outpoint(),
                                                script_sig: Script::new(),
-                                               sequence: 0,
+                                               sequence: Sequence::ZERO,
                                                witness: Witness::new(),
                                        });
                                        witness_weight += 1 + 73 + 34;
@@ -1047,7 +1056,7 @@ impl KeysManager {
                }
                let mut spend_tx = Transaction {
                        version: 2,
-                       lock_time: 0,
+                       lock_time: PackedLockTime(0),
                        input,
                        output: outputs,
                };
@@ -1131,6 +1140,14 @@ impl KeysInterface for KeysManager {
                }
        }
 
+       fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
+               let mut node_secret = self.get_node_secret(recipient)?;
+               if let Some(tweak) = tweak {
+                       node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
+               }
+               Ok(SharedSecret::new(other_key, &node_secret))
+       }
+
        fn get_inbound_payment_key_material(&self) -> KeyMaterial {
                self.inbound_payment_key.clone()
        }
@@ -1215,6 +1232,14 @@ impl KeysInterface for PhantomKeysManager {
                }
        }
 
+       fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
+               let mut node_secret = self.get_node_secret(recipient)?;
+               if let Some(tweak) = tweak {
+                       node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
+               }
+               Ok(SharedSecret::new(other_key, &node_secret))
+       }
+
        fn get_inbound_payment_key_material(&self) -> KeyMaterial {
                self.inbound_payment_key.clone()
        }