X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fkeysinterface.rs;h=b12eee017aa93b81a080bf342a267c76aa309f5e;hb=384c4dc7753e4b7ac53ea380e52809babd8f0f9b;hp=1c64a8bccdfbe4953b6944cb9b9bbc4115b18f4e;hpb=89747dc085ba1e1185e7dd2b0ce6b7cc24b25e2b;p=rust-lightning diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index 1c64a8bc..b12eee01 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -31,22 +31,22 @@ use bitcoin::secp256k1::ecdh::SharedSecret; use bitcoin::secp256k1::ecdsa::RecoverableSignature; use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness}; -use util::{byte_utils, transaction_utils}; -use util::crypto::{hkdf_extract_expand_twice, sign}; -use util::ser::{Writeable, Writer, Readable, ReadableArgs}; - -use chain::transaction::OutPoint; -use ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI; -use ln::{chan_utils, PaymentPreimage}; -use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction}; -use ln::msgs::UnsignedChannelAnnouncement; -use ln::script::ShutdownScript; - -use prelude::*; +use crate::util::{byte_utils, transaction_utils}; +use crate::util::crypto::{hkdf_extract_expand_twice, sign}; +use crate::util::ser::{Writeable, Writer, Readable, ReadableArgs}; + +use crate::chain::transaction::OutPoint; +use crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI; +use crate::ln::{chan_utils, PaymentPreimage}; +use crate::ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction}; +use crate::ln::msgs::UnsignedChannelAnnouncement; +use crate::ln::script::ShutdownScript; + +use crate::prelude::*; use core::sync::atomic::{AtomicUsize, Ordering}; -use io::{self, Error}; -use ln::msgs::{DecodeError, MAX_VALUE_MSAT}; -use util::invoice::construct_invoice_preimage; +use crate::io::{self, Error}; +use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; +use crate::util::invoice::construct_invoice_preimage; /// Used as initial key material, to be expanded into multiple secret keys (but not to be used /// directly). This is used within LDK to encrypt/decrypt inbound payment data. @@ -352,7 +352,7 @@ pub trait BaseSign { /// Computes the signature for a commitment transaction's anchor output used as an /// input within `anchor_tx`, which spends the commitment transaction, at index `input`. fn sign_holder_anchor_input( - &self, anchor_tx: &mut Transaction, input: usize, secp_ctx: &Secp256k1, + &self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1, ) -> Result; /// Signs a channel announcement message with our funding key and our node secret key (aka @@ -411,11 +411,28 @@ pub trait KeysInterface { /// /// This method must return the same value each time it is called with a given `Recipient` /// parameter. + /// + /// Errors if the `Recipient` variant is not supported by the implementation. fn get_node_secret(&self, recipient: Recipient) -> Result; + /// Get node id based on the provided [`Recipient`]. This public key corresponds to the secret in + /// [`get_node_secret`]. + /// + /// This method must return the same value each time it is called with a given `Recipient` + /// parameter. + /// + /// Errors if the `Recipient` variant is not supported by the implementation. + /// + /// [`get_node_secret`]: KeysInterface::get_node_secret + fn get_node_id(&self, recipient: Recipient) -> Result { + let secp_ctx = Secp256k1::signing_only(); + Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?)) + } /// 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. /// + /// Errors if the `Recipient` variant is not supported by the implementation. + /// /// [`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. @@ -455,6 +472,8 @@ pub trait KeysInterface { /// The hrp is ascii bytes, while the invoice data is base32. /// /// The secret key used to sign the invoice is dependent on the [`Recipient`]. + /// + /// Errors if the `Recipient` variant is not supported by the implementation. fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], receipient: Recipient) -> Result; /// Get secret key material as bytes for use in encrypting and decrypting inbound payment data. @@ -771,7 +790,7 @@ impl BaseSign for InMemorySigner { } fn sign_holder_anchor_input( - &self, anchor_tx: &mut Transaction, input: usize, secp_ctx: &Secp256k1, + &self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1, ) -> Result { let witness_script = chan_utils::get_anchor_redeemscript(&self.holder_channel_pubkeys.funding_pubkey); let sighash = sighash::SighashCache::new(&*anchor_tx).segwit_signature_hash( @@ -871,6 +890,7 @@ impl ReadableArgs for InMemorySigner { pub struct KeysManager { secp_ctx: Secp256k1, node_secret: SecretKey, + node_id: PublicKey, inbound_payment_key: KeyMaterial, destination_script: Script, shutdown_pubkey: PublicKey, @@ -912,6 +932,7 @@ impl KeysManager { match ExtendedPrivKey::new_master(Network::Testnet, seed) { Ok(master_key) => { let node_secret = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(0).unwrap()).expect("Your RNG is busted").private_key; + let node_id = PublicKey::from_secret_key(&secp_ctx, &node_secret); let destination_script = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(1).unwrap()) { Ok(destination_key) => { let wpubkey_hash = WPubkeyHash::hash(&ExtendedPubKey::from_priv(&secp_ctx, &destination_key).to_pub().to_bytes()); @@ -939,6 +960,7 @@ impl KeysManager { let mut res = KeysManager { secp_ctx, node_secret, + node_id, inbound_payment_key: KeyMaterial(inbound_pmt_key_bytes), destination_script, @@ -1158,6 +1180,13 @@ impl KeysInterface for KeysManager { } } + fn get_node_id(&self, recipient: Recipient) -> Result { + match recipient { + Recipient::Node => Ok(self.node_id.clone()), + Recipient::PhantomNode => Err(()) + } + } + 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 { @@ -1238,6 +1267,7 @@ pub struct PhantomKeysManager { inner: KeysManager, inbound_payment_key: KeyMaterial, phantom_secret: SecretKey, + phantom_node_id: PublicKey, } impl KeysInterface for PhantomKeysManager { @@ -1250,6 +1280,13 @@ impl KeysInterface for PhantomKeysManager { } } + fn get_node_id(&self, recipient: Recipient) -> Result { + match recipient { + Recipient::Node => self.inner.get_node_id(Recipient::Node), + Recipient::PhantomNode => Ok(self.phantom_node_id.clone()), + } + } + 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 { @@ -1303,10 +1340,13 @@ impl PhantomKeysManager { pub fn new(seed: &[u8; 32], starting_time_secs: u64, starting_time_nanos: u32, cross_node_seed: &[u8; 32]) -> Self { let inner = KeysManager::new(seed, starting_time_secs, starting_time_nanos); let (inbound_key, phantom_key) = hkdf_extract_expand_twice(b"LDK Inbound and Phantom Payment Key Expansion", cross_node_seed); + let phantom_secret = SecretKey::from_slice(&phantom_key).unwrap(); + let phantom_node_id = PublicKey::from_secret_key(&inner.secp_ctx, &phantom_secret); Self { inner, inbound_payment_key: KeyMaterial(inbound_key), - phantom_secret: SecretKey::from_slice(&phantom_key).unwrap(), + phantom_secret, + phantom_node_id, } }