]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Pass Nonce directly to InvoiceRequestBuilder
authorJeffrey Czyz <jkczyz@gmail.com>
Fri, 12 Jul 2024 16:14:18 +0000 (11:14 -0500)
committerJeffrey Czyz <jkczyz@gmail.com>
Mon, 22 Jul 2024 16:34:04 +0000 (11:34 -0500)
When using InvoiceRequestBuilder::deriving_payer_id, the nonce generated
needs to be the same one included in any reply path. This is because the
nonce is used along with the invoice request TLVs to derive a payer id.
While this data is also included in the payer_metadata, including it in
the blinded path would allow reducing the amount of data needed there to
just enough to provide entropy (i.e., 16 bytes). This is more important
for Refund because it can be transmitted via a QR code. But using the
same payer_metadata structure for both InvoiceRequest and Refund would
be beneficial to avoid more code.

lightning/src/ln/channelmanager.rs
lightning/src/offers/invoice_request.rs
lightning/src/offers/offer.rs

index 837a8927dcd8a40fed7c9803bf642377827865f7..6e6b0ceb6ee5c224604f4a2cbd007c26ee521ab2 100644 (file)
@@ -8976,8 +8976,9 @@ where
                let entropy = &*self.entropy_source;
                let secp_ctx = &self.secp_ctx;
 
+               let nonce = Nonce::from_entropy_source(entropy);
                let builder: InvoiceRequestBuilder<DerivedPayerId, secp256k1::All> = offer
-                       .request_invoice_deriving_payer_id(expanded_key, entropy, secp_ctx, payment_id)?
+                       .request_invoice_deriving_payer_id(expanded_key, nonce, secp_ctx, payment_id)?
                        .into();
                let builder = builder.chain_hash(self.chain_hash)?;
 
index 39eb157d76f09b532d612e086bc15aa4ee6dd241..b8e47bac59e04e046052f606464f9e7d2d437575 100644 (file)
@@ -61,8 +61,6 @@ use bitcoin::blockdata::constants::ChainHash;
 use bitcoin::network::Network;
 use bitcoin::secp256k1::{Keypair, PublicKey, Secp256k1, self};
 use bitcoin::secp256k1::schnorr::Signature;
-use core::ops::Deref;
-use crate::sign::EntropySource;
 use crate::io;
 use crate::blinded_path::BlindedPath;
 use crate::ln::types::PaymentHash;
@@ -171,11 +169,10 @@ macro_rules! invoice_request_explicit_payer_id_builder_methods { ($self: ident,
        }
 
        #[cfg_attr(c_bindings, allow(dead_code))]
-       pub(super) fn deriving_metadata<ES: Deref>(
-               offer: &'a Offer, payer_id: PublicKey, expanded_key: &ExpandedKey, entropy_source: ES,
+       pub(super) fn deriving_metadata(
+               offer: &'a Offer, payer_id: PublicKey, expanded_key: &ExpandedKey, nonce: Nonce,
                payment_id: PaymentId,
-       ) -> Self where ES::Target: EntropySource {
-               let nonce = Nonce::from_entropy_source(entropy_source);
+       ) -> Self {
                let payment_id = Some(payment_id);
                let derivation_material = MetadataMaterial::new(nonce, expanded_key, IV_BYTES, payment_id);
                let metadata = Metadata::Derived(derivation_material);
@@ -201,11 +198,10 @@ macro_rules! invoice_request_derived_payer_id_builder_methods { (
        $self: ident, $self_type: ty, $secp_context: ty
 ) => {
        #[cfg_attr(c_bindings, allow(dead_code))]
-       pub(super) fn deriving_payer_id<ES: Deref>(
-               offer: &'a Offer, expanded_key: &ExpandedKey, entropy_source: ES,
+       pub(super) fn deriving_payer_id(
+               offer: &'a Offer, expanded_key: &ExpandedKey, nonce: Nonce,
                secp_ctx: &'b Secp256k1<$secp_context>, payment_id: PaymentId
-       ) -> Self where ES::Target: EntropySource {
-               let nonce = Nonce::from_entropy_source(entropy_source);
+       ) -> Self {
                let payment_id = Some(payment_id);
                let derivation_material = MetadataMaterial::new(nonce, expanded_key, IV_BYTES, payment_id);
                let metadata = Metadata::DerivedSigningPubkey(derivation_material);
@@ -1403,6 +1399,7 @@ mod tests {
                let payer_id = payer_pubkey();
                let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
                let entropy = FixedEntropy {};
+               let nonce = Nonce::from_entropy_source(&entropy);
                let secp_ctx = Secp256k1::new();
                let payment_id = PaymentId([1; 32]);
 
@@ -1410,7 +1407,7 @@ mod tests {
                        .amount_msats(1000)
                        .build().unwrap();
                let invoice_request = offer
-                       .request_invoice_deriving_metadata(payer_id, &expanded_key, &entropy, payment_id)
+                       .request_invoice_deriving_metadata(payer_id, &expanded_key, nonce, payment_id)
                        .unwrap()
                        .build().unwrap()
                        .sign(payer_sign).unwrap();
@@ -1476,6 +1473,7 @@ mod tests {
        fn builds_invoice_request_with_derived_payer_id() {
                let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
                let entropy = FixedEntropy {};
+               let nonce = Nonce::from_entropy_source(&entropy);
                let secp_ctx = Secp256k1::new();
                let payment_id = PaymentId([1; 32]);
 
@@ -1483,7 +1481,7 @@ mod tests {
                        .amount_msats(1000)
                        .build().unwrap();
                let invoice_request = offer
-                       .request_invoice_deriving_payer_id(&expanded_key, &entropy, &secp_ctx, payment_id)
+                       .request_invoice_deriving_payer_id(&expanded_key, nonce, &secp_ctx, payment_id)
                        .unwrap()
                        .build_and_sign()
                        .unwrap();
index 94d5175a5b62aadac22fa69524133b4644f1cadb..b5e9154d53aba912b2783135ff09a471ddf7abb9 100644 (file)
@@ -82,10 +82,8 @@ use bitcoin::network::Network;
 use bitcoin::secp256k1::{Keypair, PublicKey, Secp256k1, self};
 use core::hash::{Hash, Hasher};
 use core::num::NonZeroU64;
-use core::ops::Deref;
 use core::str::FromStr;
 use core::time::Duration;
-use crate::sign::EntropySource;
 use crate::io;
 use crate::blinded_path::BlindedPath;
 use crate::ln::channelmanager::PaymentId;
@@ -699,25 +697,22 @@ macro_rules! request_invoice_derived_payer_id { ($self: ident, $builder: ty) =>
        /// [`Bolt12Invoice::verify`]: crate::offers::invoice::Bolt12Invoice::verify
        /// [`ExpandedKey`]: crate::ln::inbound_payment::ExpandedKey
        pub fn request_invoice_deriving_payer_id<
-               'a, 'b, ES: Deref,
+               'a, 'b,
                #[cfg(not(c_bindings))]
                T: secp256k1::Signing
        >(
-               &'a $self, expanded_key: &ExpandedKey, entropy_source: ES,
+               &'a $self, expanded_key: &ExpandedKey, nonce: Nonce,
                #[cfg(not(c_bindings))]
                secp_ctx: &'b Secp256k1<T>,
                #[cfg(c_bindings)]
                secp_ctx: &'b Secp256k1<secp256k1::All>,
                payment_id: PaymentId
-       ) -> Result<$builder, Bolt12SemanticError>
-       where
-               ES::Target: EntropySource,
-       {
+       ) -> Result<$builder, Bolt12SemanticError> {
                if $self.offer_features().requires_unknown_bits() {
                        return Err(Bolt12SemanticError::UnknownRequiredFeatures);
                }
 
-               Ok(<$builder>::deriving_payer_id($self, expanded_key, entropy_source, secp_ctx, payment_id))
+               Ok(<$builder>::deriving_payer_id($self, expanded_key, nonce, secp_ctx, payment_id))
        }
 } }
 
@@ -728,18 +723,15 @@ macro_rules! request_invoice_explicit_payer_id { ($self: ident, $builder: ty) =>
        /// Useful for recurring payments using the same `payer_id` with different invoices.
        ///
        /// [`InvoiceRequest::payer_id`]: crate::offers::invoice_request::InvoiceRequest::payer_id
-       pub fn request_invoice_deriving_metadata<ES: Deref>(
-               &$self, payer_id: PublicKey, expanded_key: &ExpandedKey, entropy_source: ES,
+       pub fn request_invoice_deriving_metadata(
+               &$self, payer_id: PublicKey, expanded_key: &ExpandedKey, nonce: Nonce,
                payment_id: PaymentId
-       ) -> Result<$builder, Bolt12SemanticError>
-       where
-               ES::Target: EntropySource,
-       {
+       ) -> Result<$builder, Bolt12SemanticError> {
                if $self.offer_features().requires_unknown_bits() {
                        return Err(Bolt12SemanticError::UnknownRequiredFeatures);
                }
 
-               Ok(<$builder>::deriving_metadata($self, payer_id, expanded_key, entropy_source, payment_id))
+               Ok(<$builder>::deriving_metadata($self, payer_id, expanded_key, nonce, payment_id))
        }
 
        /// Creates an [`InvoiceRequestBuilder`] for the offer with the given `metadata` and `payer_id`,