]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Pass Nonce directly to OfferBuilder
authorJeffrey Czyz <jkczyz@gmail.com>
Wed, 19 Jun 2024 17:42:16 +0000 (12:42 -0500)
committerJeffrey Czyz <jkczyz@gmail.com>
Mon, 22 Jul 2024 16:34:02 +0000 (11:34 -0500)
When using OfferBuilder::deriving_signing_pubkey, the nonce generated
needs to be the same one included in any OfferBuilder::paths. This is
because the nonce is used along with the offer TLVs to derive a signing
pubkey and will soon be elided from the metadata entirely.

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

index 9bceb5816b63db64c9d1d3db116b5735ac4afa99..34267adeda9ebbe4a31d2c71c4714c1e82c7e986 100644 (file)
@@ -64,6 +64,7 @@ use crate::ln::wire::Encode;
 use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice};
 use crate::offers::invoice_error::InvoiceError;
 use crate::offers::invoice_request::{DerivedPayerId, InvoiceRequestBuilder};
+use crate::offers::nonce::Nonce;
 use crate::offers::offer::{Offer, OfferBuilder};
 use crate::offers::parse::Bolt12SemanticError;
 use crate::offers::refund::{Refund, RefundBuilder};
@@ -8784,13 +8785,11 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
                let entropy = &*$self.entropy_source;
                let secp_ctx = &$self.secp_ctx;
 
+               let nonce = Nonce::from_entropy_source(entropy);
                let path = $self.create_blinded_paths_using_absolute_expiry(OffersContext::Unknown {}, absolute_expiry)
                        .and_then(|paths| paths.into_iter().next().ok_or(()))
                        .map_err(|_| Bolt12SemanticError::MissingPaths)?;
-
-               let builder = OfferBuilder::deriving_signing_pubkey(
-                       node_id, expanded_key, entropy, secp_ctx
-               )
+               let builder = OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
                        .chain_hash($self.chain_hash)
                        .path(path);
 
index 3f96e703b2a6dcae21bef4019070c4f792da24ce..cfe97afd109e97ccda9afe85eb18881785ff4709 100644 (file)
@@ -1416,6 +1416,7 @@ mod tests {
        use crate::ln::msgs::DecodeError;
        use crate::offers::invoice_request::InvoiceRequestTlvStreamRef;
        use crate::offers::merkle::{SignError, SignatureTlvStreamRef, TaggedHash, self};
+       use crate::offers::nonce::Nonce;
        use crate::offers::offer::{Amount, OfferTlvStreamRef, Quantity};
        use crate::prelude::*;
        #[cfg(not(c_bindings))]
@@ -1752,6 +1753,7 @@ mod tests {
                let node_id = recipient_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 blinded_path = BlindedPath {
@@ -1765,8 +1767,7 @@ mod tests {
 
                #[cfg(c_bindings)]
                use crate::offers::offer::OfferWithDerivedMetadataBuilder as OfferBuilder;
-               let offer = OfferBuilder
-                       ::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
+               let offer = OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
                        .amount_msats(1000)
                        .path(blinded_path)
                        .build().unwrap();
@@ -1785,8 +1786,7 @@ mod tests {
                let expanded_key = ExpandedKey::new(&KeyMaterial([41; 32]));
                assert!(invoice_request.verify(&expanded_key, &secp_ctx).is_err());
 
-               let offer = OfferBuilder
-                       ::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
+               let offer = OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
                        .amount_msats(1000)
                        // Omit the path so that node_id is used for the signing pubkey instead of deriving
                        .build().unwrap();
index b9ccc5f4d7d2f238b07ecbcae23628c72e10ee5e..3b45f9511b5fd4afef42c5a5970744493534523c 100644 (file)
@@ -1217,6 +1217,7 @@ mod tests {
        use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
        use crate::offers::invoice::{Bolt12Invoice, SIGNATURE_TAG as INVOICE_SIGNATURE_TAG};
        use crate::offers::merkle::{SignError, SignatureTlvStreamRef, TaggedHash, self};
+       use crate::offers::nonce::Nonce;
        use crate::offers::offer::{Amount, OfferTlvStreamRef, Quantity};
        #[cfg(not(c_bindings))]
        use {
@@ -2274,12 +2275,12 @@ mod tests {
                let node_id = recipient_pubkey();
                let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
                let entropy = FixedEntropy {};
+               let nonce = Nonce::from_entropy_source(&entropy);
                let secp_ctx = Secp256k1::new();
 
                #[cfg(c_bindings)]
                use crate::offers::offer::OfferWithDerivedMetadataBuilder as OfferBuilder;
-               let offer = OfferBuilder
-                       ::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
+               let offer = OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
                        .chain(Network::Testnet)
                        .amount_msats(1000)
                        .supported_quantity(Quantity::Unbounded)
index 03e1e92a482cbe82af959af3dfb4c6cc651abff4..674cfeaa12ceab6817be76a7a86a9308241da783 100644 (file)
@@ -243,9 +243,9 @@ macro_rules! offer_explicit_metadata_builder_methods { (
 
 macro_rules! offer_derived_metadata_builder_methods { ($secp_context: ty) => {
        /// Similar to [`OfferBuilder::new`] except, if [`OfferBuilder::path`] is called, the signing
-       /// pubkey is derived from the given [`ExpandedKey`] and [`EntropySource`]. This provides
-       /// recipient privacy by using a different signing pubkey for each offer. Otherwise, the
-       /// provided `node_id` is used for the signing pubkey.
+       /// pubkey is derived from the given [`ExpandedKey`] and [`Nonce`]. This provides recipient
+       /// privacy by using a different signing pubkey for each offer. Otherwise, the provided
+       /// `node_id` is used for the signing pubkey.
        ///
        /// Also, sets the metadata when [`OfferBuilder::build`] is called such that it can be used by
        /// [`InvoiceRequest::verify`] to determine if the request was produced for the offer given an
@@ -253,11 +253,10 @@ macro_rules! offer_derived_metadata_builder_methods { ($secp_context: ty) => {
        ///
        /// [`InvoiceRequest::verify`]: crate::offers::invoice_request::InvoiceRequest::verify
        /// [`ExpandedKey`]: crate::ln::inbound_payment::ExpandedKey
-       pub fn deriving_signing_pubkey<ES: Deref>(
-               node_id: PublicKey, expanded_key: &ExpandedKey, entropy_source: ES,
+       pub fn deriving_signing_pubkey(
+               node_id: PublicKey, expanded_key: &ExpandedKey, nonce: Nonce,
                secp_ctx: &'a Secp256k1<$secp_context>
-       ) -> Self where ES::Target: EntropySource {
-               let nonce = Nonce::from_entropy_source(entropy_source);
+       ) -> Self {
                let derivation_material = MetadataMaterial::new(nonce, expanded_key, IV_BYTES, None);
                let metadata = Metadata::DerivedSigningPubkey(derivation_material);
                Self {
@@ -1164,6 +1163,7 @@ mod tests {
        use crate::ln::features::OfferFeatures;
        use crate::ln::inbound_payment::ExpandedKey;
        use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
+       use crate::offers::nonce::Nonce;
        use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError};
        use crate::offers::test_utils::*;
        use crate::util::ser::{BigSize, Writeable};
@@ -1278,12 +1278,12 @@ mod tests {
                let node_id = recipient_pubkey();
                let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
                let entropy = FixedEntropy {};
+               let nonce = Nonce::from_entropy_source(&entropy);
                let secp_ctx = Secp256k1::new();
 
                #[cfg(c_bindings)]
                use super::OfferWithDerivedMetadataBuilder as OfferBuilder;
-               let offer = OfferBuilder
-                       ::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
+               let offer = OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
                        .amount_msats(1000)
                        .build().unwrap();
                assert_eq!(offer.signing_pubkey(), Some(node_id));
@@ -1329,6 +1329,7 @@ mod tests {
                let node_id = recipient_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 blinded_path = BlindedPath {
@@ -1342,8 +1343,7 @@ mod tests {
 
                #[cfg(c_bindings)]
                use super::OfferWithDerivedMetadataBuilder as OfferBuilder;
-               let offer = OfferBuilder
-                       ::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
+               let offer = OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
                        .amount_msats(1000)
                        .path(blinded_path)
                        .build().unwrap();
index 69f4073e678ec0c7b4ae5254d9059e950eadfc32..7c084ba3e256ad80ef89521841ebc9266c19ae6b 100644 (file)
@@ -565,6 +565,7 @@ mod tests {
        use crate::offers::invoice::InvoiceTlvStreamRef;
        use crate::offers::merkle;
        use crate::offers::merkle::{SignatureTlvStreamRef, TaggedHash};
+       use crate::offers::nonce::Nonce;
        use crate::offers::offer::{Offer, OfferBuilder, OfferTlvStreamRef, Quantity};
        use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError};
        use crate::offers::static_invoice::{
@@ -608,13 +609,13 @@ mod tests {
                let now = now();
                let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
                let entropy = FixedEntropy {};
+               let nonce = Nonce::from_entropy_source(&entropy);
                let secp_ctx = Secp256k1::new();
 
-               let offer =
-                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
-                               .path(blinded_path())
-                               .build()
-                               .unwrap();
+               let offer = OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
+                       .path(blinded_path())
+                       .build()
+                       .unwrap();
 
                StaticInvoiceBuilder::for_offer_using_derived_keys(
                        &offer,
@@ -647,13 +648,13 @@ mod tests {
                let now = now();
                let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
                let entropy = FixedEntropy {};
+               let nonce = Nonce::from_entropy_source(&entropy);
                let secp_ctx = Secp256k1::new();
 
-               let offer =
-                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
-                               .path(blinded_path())
-                               .build()
-                               .unwrap();
+               let offer = OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
+                       .path(blinded_path())
+                       .build()
+                       .unwrap();
 
                let invoice = StaticInvoiceBuilder::for_offer_using_derived_keys(
                        &offer,
@@ -742,13 +743,14 @@ mod tests {
                let now = now();
                let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
                let entropy = FixedEntropy {};
+               let nonce = Nonce::from_entropy_source(&entropy);
                let secp_ctx = Secp256k1::new();
 
                let future_expiry = Duration::from_secs(u64::max_value());
                let past_expiry = Duration::from_secs(0);
 
                let valid_offer =
-                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
+                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
                                .path(blinded_path())
                                .absolute_expiry(future_expiry)
                                .build()
@@ -769,7 +771,7 @@ mod tests {
                assert_eq!(invoice.absolute_expiry(), Some(future_expiry));
 
                let expired_offer =
-                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
+                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
                                .path(blinded_path())
                                .absolute_expiry(past_expiry)
                                .build()
@@ -797,10 +799,11 @@ mod tests {
                let now = now();
                let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
                let entropy = FixedEntropy {};
+               let nonce = Nonce::from_entropy_source(&entropy);
                let secp_ctx = Secp256k1::new();
 
                let valid_offer =
-                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
+                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
                                .path(blinded_path())
                                .build()
                                .unwrap();
@@ -860,10 +863,11 @@ mod tests {
                let now = now();
                let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
                let entropy = FixedEntropy {};
+               let nonce = Nonce::from_entropy_source(&entropy);
                let secp_ctx = Secp256k1::new();
 
                let valid_offer =
-                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
+                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
                                .path(blinded_path())
                                .build()
                                .unwrap();
@@ -916,10 +920,11 @@ mod tests {
                let now = now();
                let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
                let entropy = FixedEntropy {};
+               let nonce = Nonce::from_entropy_source(&entropy);
                let secp_ctx = Secp256k1::new();
 
                let offer_with_extra_chain =
-                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
+                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
                                .path(blinded_path())
                                .chain(Network::Bitcoin)
                                .chain(Network::Testnet)
@@ -947,13 +952,13 @@ mod tests {
                let now = now();
                let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
                let entropy = FixedEntropy {};
+               let nonce = Nonce::from_entropy_source(&entropy);
                let secp_ctx = Secp256k1::new();
 
-               let offer =
-                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
-                               .path(blinded_path())
-                               .build()
-                               .unwrap();
+               let offer = OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
+                       .path(blinded_path())
+                       .build()
+                       .unwrap();
 
                const TEST_RELATIVE_EXPIRY: u32 = 3600;
                let invoice = StaticInvoiceBuilder::for_offer_using_derived_keys(
@@ -988,13 +993,13 @@ mod tests {
                let now = now();
                let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
                let entropy = FixedEntropy {};
+               let nonce = Nonce::from_entropy_source(&entropy);
                let secp_ctx = Secp256k1::new();
 
-               let offer =
-                       OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
-                               .path(blinded_path())
-                               .build()
-                               .unwrap();
+               let offer = OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
+                       .path(blinded_path())
+                       .build()
+                       .unwrap();
 
                let invoice = StaticInvoiceBuilder::for_offer_using_derived_keys(
                        &offer,