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};
/// 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
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.");
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;
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;
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;
}
let mut spend_tx = Transaction {
version: 2,
- lock_time: 0,
+ lock_time: PackedLockTime(0),
input,
output: outputs,
};
}
}
+ 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()
}
}
}
+ 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()
}