@@ -19,14 +19,14 @@ use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
1919use  crate :: ln:: msgs; 
2020use  crate :: ln:: msgs:: MAX_VALUE_MSAT ; 
2121use  crate :: util:: chacha20:: ChaCha20 ; 
22- use  crate :: util:: crypto:: hkdf_extract_expand_thrice ; 
22+ use  crate :: util:: crypto:: hkdf_extract_expand_4x ; 
2323use  crate :: util:: errors:: APIError ; 
2424use  crate :: util:: logger:: Logger ; 
2525
26- use  core:: convert:: TryInto ; 
26+ use  core:: convert:: { TryFrom ,   TryInto } ; 
2727use  core:: ops:: Deref ; 
2828
29- const  IV_LEN :  usize  = 16 ; 
29+ pub ( crate )   const  IV_LEN :  usize  = 16 ; 
3030const  METADATA_LEN :  usize  = 16 ; 
3131const  METADATA_KEY_LEN :  usize  = 32 ; 
3232const  AMT_MSAT_LEN :  usize  = 8 ; 
@@ -48,21 +48,85 @@ pub struct ExpandedKey {
4848	/// The key used to authenticate a user-provided payment hash and metadata as previously 
4949/// registered with LDK. 
5050user_pmt_hash_key :  [ u8 ;  32 ] , 
51+ 	/// The base key used to derive signing keys and authenticate messages for BOLT 12 Offers. 
52+ offers_base_key :  [ u8 ;  32 ] , 
5153} 
5254
5355impl  ExpandedKey  { 
5456	/// Create a  new [`ExpandedKey`] for generating an inbound payment hash and secret. 
5557/// 
5658/// It is recommended to cache this value and not regenerate it for each new inbound payment. 
5759pub  fn  new ( key_material :  & KeyMaterial )  -> ExpandedKey  { 
58- 		let  ( metadata_key,  ldk_pmt_hash_key,  user_pmt_hash_key)  =
59- 			hkdf_extract_expand_thrice ( b"LDK Inbound Payment Key Expansion" ,  & key_material. 0 ) ; 
60+ 		let  ( metadata_key,  ldk_pmt_hash_key,  user_pmt_hash_key,  offers_base_key )  =
61+ 			hkdf_extract_expand_4x ( b"LDK Inbound Payment Key Expansion" ,  & key_material. 0 ) ; 
6062		Self  { 
6163			metadata_key, 
6264			ldk_pmt_hash_key, 
6365			user_pmt_hash_key, 
66+ 			offers_base_key, 
6467		} 
6568	} 
69+ 
70+ 	/// Returns an [`HmacEngine`] used to construct [`Offer::metadata`]. 
71+ /// 
72+ /// [`Offer::metadata`]: crate::offers::offer::Offer::metadata 
73+ #[ allow( unused) ]  
74+ 	pub ( crate )  fn  hmac_for_offer ( 
75+ 		& self ,  nonce :  Nonce ,  iv_bytes :  & [ u8 ;  IV_LEN ] 
76+ 	)  -> HmacEngine < Sha256 >  { 
77+ 		let  mut  hmac = HmacEngine :: < Sha256 > :: new ( & self . offers_base_key ) ; 
78+ 		hmac. input ( iv_bytes) ; 
79+ 		hmac. input ( & nonce. 0 ) ; 
80+ 		hmac
81+ 	} 
82+ } 
83+ 
84+ /// A 128-bit number used only once. 
85+ /// 
86+ /// Needed when constructing [`Offer::metadata`] and deriving [`Offer::signing_pubkey`] from 
87+ /// [`ExpandedKey`]. Must not be reused for any other derivation without first hashing. 
88+ /// 
89+ /// [`Offer::metadata`]: crate::offers::offer::Offer::metadata 
90+ /// [`Offer::signing_pubkey`]: crate::offers::offer::Offer::signing_pubkey 
91+ #[ allow( unused) ]  
92+ #[ derive( Clone ,  Copy ,  Debug ,  PartialEq ) ]  
93+ pub ( crate )  struct  Nonce ( pub ( crate )  [ u8 ;  Self :: LENGTH ] ) ; 
94+ 
95+ impl  Nonce  { 
96+ 	/// Number of bytes in the nonce. 
97+ pub  const  LENGTH :  usize  = 16 ; 
98+ 
99+ 	/// Creates a `Nonce` from the given [`EntropySource`]. 
100+ pub  fn  from_entropy_source < ES :  Deref > ( entropy_source :  ES )  -> Self 
101+ 	where 
102+ 		ES :: Target :  EntropySource , 
103+ 	{ 
104+ 		let  mut  bytes = [ 0u8 ;  Self :: LENGTH ] ; 
105+ 		let  rand_bytes = entropy_source. get_secure_random_bytes ( ) ; 
106+ 		bytes. copy_from_slice ( & rand_bytes[ ..Self :: LENGTH ] ) ; 
107+ 
108+ 		Nonce ( bytes) 
109+ 	} 
110+ 
111+ 	/// Returns a slice of the underlying bytes of size [`Nonce::LENGTH`]. 
112+ pub  fn  as_slice ( & self )  -> & [ u8 ]  { 
113+ 		& self . 0 
114+ 	} 
115+ } 
116+ 
117+ impl  TryFrom < & [ u8 ] >  for  Nonce  { 
118+ 	type  Error  = ( ) ; 
119+ 
120+ 	fn  try_from ( bytes :  & [ u8 ] )  -> Result < Self ,  ( ) >  { 
121+ 		if  bytes. len ( )  != Self :: LENGTH  { 
122+ 			return  Err ( ( ) ) ; 
123+ 		} 
124+ 
125+ 		let  mut  copied_bytes = [ 0u8 ;  Self :: LENGTH ] ; 
126+ 		copied_bytes. copy_from_slice ( bytes) ; 
127+ 
128+ 		Ok ( Self ( copied_bytes) ) 
129+ 	} 
66130} 
67131
68132enum  Method  { 
0 commit comments