Merge pull request #1779 from valentinewallace/2022-10-node-pk-keysinterface
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Mon, 24 Oct 2022 17:37:25 +0000 (17:37 +0000)
committerGitHub <noreply@github.com>
Mon, 24 Oct 2022 17:37:25 +0000 (17:37 +0000)
Add `KeysInterface::get_node_id` method

lightning/src/chain/keysinterface.rs
lightning/src/util/test_utils.rs

index 7650d4f5210cb706af297efc3f8e5303a2b93ed9..e3108fd54daa9c5a773cf0acfa85611c3c5fd787 100644 (file)
@@ -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<SecretKey, ()>;
+       /// 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<PublicKey, ()> {
+               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<SharedSecret, ()>;
        /// 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<RecoverableSignature, ()>;
 
        /// Get secret key material as bytes for use in encrypting and decrypting inbound payment data.
@@ -871,6 +890,7 @@ impl ReadableArgs<SecretKey> for InMemorySigner {
 pub struct KeysManager {
        secp_ctx: Secp256k1<secp256k1::All>,
        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<PublicKey, ()> {
+               match recipient {
+                       Recipient::Node => Ok(self.node_id.clone()),
+                       Recipient::PhantomNode => Err(())
+               }
+       }
+
        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 {
@@ -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<PublicKey, ()> {
+               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<SharedSecret, ()> {
                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,
                }
        }
 
index 37302b1e0ec1b6618c580fd7c7bb72b4022d9aad..89bf27de2805ef8c152279cc02855d114d7a4e9b 100644 (file)
@@ -608,6 +608,9 @@ impl keysinterface::KeysInterface for TestKeysInterface {
        fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
                self.backing.get_node_secret(recipient)
        }
+       fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
+               self.backing.get_node_id(recipient)
+       }
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
                self.backing.ecdh(recipient, other_key, tweak)
        }