X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fkeysinterface.rs;h=a89cc602bc2b61588509a5c7b83239979fbf3226;hb=e9ac2b1669bf9f3c44de89f67f5d549280065ea3;hp=4231d08259abcbe1e4c50550f4b40aa7d7064faa;hpb=10071b51e2b7bafcef1ce958524bd70ef5c7ba5a;p=rust-lightning diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index 4231d082..a89cc602 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -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}; @@ -54,7 +55,7 @@ pub struct KeyMaterial(pub [u8; 32]); /// Information about a spendable output to a P2WSH script. See /// SpendableOutputDescriptor::DelayedPaymentOutput for more details on how to spend this. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct DelayedPaymentOutputDescriptor { /// The outpoint which is spendable pub outpoint: OutPoint, @@ -94,7 +95,7 @@ impl_writeable_tlv_based!(DelayedPaymentOutputDescriptor, { /// Information about a spendable output to our "payment key". See /// SpendableOutputDescriptor::StaticPaymentOutput for more details on how to spend this. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct StaticPaymentOutputDescriptor { /// The outpoint which is spendable pub outpoint: OutPoint, @@ -125,7 +126,7 @@ impl_writeable_tlv_based!(StaticPaymentOutputDescriptor, { /// spend on-chain. The information needed to do this is provided in this enum, including the /// outpoint describing which txid and output index is available, the full output which exists at /// that txid/index, and any keys or other information required to sign. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum SpendableOutputDescriptor { /// An output to a script which was provided via KeysInterface directly, either from /// `get_destination_script()` or `get_shutdown_scriptpubkey()`, thus you should already know @@ -404,6 +405,12 @@ pub trait KeysInterface { /// 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; + /// 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; /// 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 @@ -619,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."); @@ -1015,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; @@ -1026,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; @@ -1037,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; @@ -1049,7 +1056,7 @@ impl KeysManager { } let mut spend_tx = Transaction { version: 2, - lock_time: 0, + lock_time: PackedLockTime(0), input, output: outputs, }; @@ -1133,6 +1140,14 @@ impl KeysInterface for KeysManager { } } + fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result { + 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() } @@ -1217,6 +1232,14 @@ impl KeysInterface for PhantomKeysManager { } } + fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result { + 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() }