67
67
//! ```
68
68
69
69
use bitcoin:: blockdata:: constants:: ChainHash ;
70
- use bitcoin:: hashes:: { Hash , HashEngine } ;
71
- use bitcoin:: hashes:: hmac:: { Hmac , HmacEngine } ;
72
- use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
73
70
use bitcoin:: network:: constants:: Network ;
74
71
use bitcoin:: secp256k1:: PublicKey ;
75
- use core:: convert:: { TryFrom , TryInto } ;
72
+ use core:: convert:: TryFrom ;
76
73
use core:: num:: NonZeroU64 ;
77
74
use core:: str:: FromStr ;
78
75
use core:: time:: Duration ;
@@ -83,7 +80,7 @@ use crate::ln::msgs::MAX_VALUE_MSAT;
83
80
use crate :: offers:: invoice_request:: InvoiceRequestBuilder ;
84
81
use crate :: offers:: merkle:: TlvStream ;
85
82
use crate :: offers:: parse:: { Bech32Encode , ParseError , ParsedMessage , SemanticError } ;
86
- use crate :: offers:: signer:: SigningPubkey ;
83
+ use crate :: offers:: signer:: { MetadataMaterial , SigningPubkey , self } ;
87
84
use crate :: onion_message:: BlindedPath ;
88
85
use crate :: util:: ser:: { HighZeroBytesDroppedBigSize , WithoutLength , Writeable , Writer } ;
89
86
use crate :: util:: string:: PrintableString ;
@@ -100,7 +97,7 @@ use std::time::SystemTime;
100
97
/// [module-level documentation]: self
101
98
pub struct OfferBuilder {
102
99
offer : OfferContents ,
103
- metadata_material : Option < ( Nonce , HmacEngine < Sha256 > ) > ,
100
+ metadata_material : Option < MetadataMaterial > ,
104
101
}
105
102
106
103
impl OfferBuilder {
@@ -110,14 +107,7 @@ impl OfferBuilder {
110
107
///
111
108
/// Use a different pubkey per offer to avoid correlating offers.
112
109
pub fn new ( description : String , signing_pubkey : SigningPubkey ) -> Self {
113
- let ( metadata_material, signing_pubkey) = match signing_pubkey {
114
- SigningPubkey :: Explicit ( pubkey) => ( None , pubkey) ,
115
- SigningPubkey :: Derived ( expanded_key, nonce) => {
116
- let metadata_material = ( nonce, expanded_key. hmac_for_offer ( nonce) ) ;
117
- let signing_pubkey = expanded_key. signing_pubkey_for_offer ( nonce) ;
118
- ( Some ( metadata_material) , signing_pubkey)
119
- } ,
120
- } ;
110
+ let ( metadata_material, signing_pubkey) = signing_pubkey. into_parts ( ) ;
121
111
let offer = OfferContents {
122
112
chains : None , metadata : None , amount : None , description,
123
113
features : OfferFeatures :: empty ( ) , absolute_expiry : None , issuer : None , paths : None ,
@@ -167,7 +157,7 @@ impl OfferBuilder {
167
157
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
168
158
pub fn metadata_derived ( mut self , key : & ExpandedKey , nonce : Nonce ) -> Self {
169
159
self . offer . metadata = None ;
170
- self . metadata_material = Some ( ( nonce, key. hmac_for_offer ( nonce ) ) ) ;
160
+ self . metadata_material = Some ( MetadataMaterial :: new ( nonce, key) ) ;
171
161
self
172
162
}
173
163
@@ -240,18 +230,14 @@ impl OfferBuilder {
240
230
}
241
231
}
242
232
243
- // Create the metadata for stateless verification. It consists of a 16-byte nonce and a
244
- // 32-byte HMAC of the offer bytes excluding the signing pubkey.
245
- if let Some ( ( nonce, mut hmac) ) = self . metadata_material {
233
+ // Create the metadata for stateless verification of an InvoiceRequest.
234
+ if let Some ( mut metadata_material) = self . metadata_material {
246
235
debug_assert ! ( self . offer. metadata. is_none( ) ) ;
247
236
let mut tlv_stream = self . offer . as_tlv_stream ( ) ;
248
237
tlv_stream. node_id = None ;
249
- tlv_stream. write ( & mut hmac) . unwrap ( ) ;
250
-
251
- let mut metadata = nonce. as_slice ( ) . to_vec ( ) ;
252
- metadata. extend_from_slice ( & Hmac :: from_engine ( hmac) . into_inner ( ) ) ;
238
+ tlv_stream. write ( & mut metadata_material) . unwrap ( ) ;
253
239
254
- self . offer . metadata = Some ( metadata ) ;
240
+ self . offer . metadata = Some ( metadata_material . into_metadata ( ) ) ;
255
241
}
256
242
257
243
let mut bytes = Vec :: new ( ) ;
@@ -536,23 +522,15 @@ impl OfferContents {
536
522
pub ( super ) fn verify ( & self , tlv_stream : TlvStream < ' _ > , key : & ExpandedKey ) -> bool {
537
523
match & self . metadata {
538
524
Some ( metadata) => {
539
- let mut hmac = if metadata. len ( ) < Nonce :: LENGTH {
540
- return false ;
541
- } else {
542
- let nonce = Nonce ( metadata[ ..Nonce :: LENGTH ] . try_into ( ) . unwrap ( ) ) ;
543
- key. hmac_for_offer ( nonce)
544
- } ;
545
-
546
- for record in tlv_stream. range ( OFFER_TYPES ) {
525
+ let tlv_stream = tlv_stream. range ( OFFER_TYPES ) . filter ( |record| {
547
526
match record. r#type {
548
527
// TODO: Assert value bytes == metadata?
549
- OFFER_METADATA_TYPE => { } ,
550
- OFFER_NODE_ID_TYPE => { } ,
551
- _ => hmac . input ( record . record_bytes ) ,
528
+ OFFER_METADATA_TYPE => false ,
529
+ OFFER_NODE_ID_TYPE => false ,
530
+ _ => true ,
552
531
}
553
- }
554
-
555
- & metadata[ Nonce :: LENGTH ..] == & Hmac :: from_engine ( hmac) . into_inner ( )
532
+ } ) ;
533
+ signer:: verify_metadata ( metadata, key, tlv_stream)
556
534
} ,
557
535
None => false ,
558
536
}
0 commit comments