@@ -20,7 +20,9 @@ use crate::io;
2020use crate :: io:: Cursor ;
2121use crate :: types:: payment:: PaymentSecret ;
2222use crate :: ln:: channel_state:: CounterpartyForwardingInfo ;
23+ use crate :: ln:: channelmanager:: Verification ;
2324use crate :: types:: features:: BlindedHopFeatures ;
25+ use crate :: ln:: inbound_payment:: ExpandedKey ;
2426use crate :: ln:: msgs:: DecodeError ;
2527use crate :: ln:: onion_utils;
2628use crate :: offers:: invoice_request:: InvoiceRequestFields ;
@@ -117,7 +119,7 @@ impl BlindedPaymentPath {
117119 let blinding_secret = SecretKey :: from_slice ( & blinding_secret_bytes[ ..] ) . expect ( "RNG is busted" ) ;
118120
119121 let blinded_payinfo = compute_payinfo (
120- intermediate_nodes, & payee_tlvs, htlc_maximum_msat, min_final_cltv_expiry_delta
122+ intermediate_nodes, & payee_tlvs. tlvs , htlc_maximum_msat, min_final_cltv_expiry_delta
121123 ) ?;
122124 Ok ( Self {
123125 inner_path : BlindedPath {
@@ -255,16 +257,36 @@ pub struct ForwardTlvs {
255257
256258/// Data to construct a [`BlindedHop`] for receiving a payment. This payload is custom to LDK and
257259/// may not be valid if received by another lightning implementation.
260+ ///
261+ /// Can only be constructed by calling [`UnauthenticatedReceiveTlvs::authenticate`].
258262#[ derive( Clone , Debug ) ]
259263pub struct ReceiveTlvs {
264+ /// The TLVs for which the HMAC in `authentication` is derived.
265+ pub tlvs : UnauthenticatedReceiveTlvs ,
266+ /// An HMAC of `tlvs` along with a nonce used to construct it.
267+ pub ( crate ) authentication : ( Hmac < Sha256 > , Nonce ) ,
268+ }
269+
270+ /// An unauthenticated [`ReceiveTlvs`].
271+ #[ derive( Clone , Debug ) ]
272+ pub struct UnauthenticatedReceiveTlvs {
260273 /// Used to authenticate the sender of a payment to the receiver and tie MPP HTLCs together.
261274 pub payment_secret : PaymentSecret ,
262275 /// Constraints for the receiver of this payment.
263276 pub payment_constraints : PaymentConstraints ,
264277 /// Context for the receiver of this payment.
265278 pub payment_context : PaymentContext ,
266- /// An HMAC of `payment_context` along with a nonce used to construct it.
267- pub authentication : Option < ( Hmac < Sha256 > , Nonce ) > ,
279+ }
280+
281+ impl UnauthenticatedReceiveTlvs {
282+ /// Creates an authenticated [`ReceiveTlvs`], which includes an HMAC and the provide [`Nonce`]
283+ /// that can be use later to verify it authenticity.
284+ pub fn authenticate ( self , nonce : Nonce , expanded_key : & ExpandedKey ) -> ReceiveTlvs {
285+ ReceiveTlvs {
286+ authentication : ( self . hmac_for_offer_payment ( nonce, expanded_key) , nonce) ,
287+ tlvs : self ,
288+ }
289+ }
268290}
269291
270292/// Data to construct a [`BlindedHop`] for sending a payment over.
@@ -392,12 +414,23 @@ impl Writeable for ForwardTlvs {
392414}
393415
394416impl Writeable for ReceiveTlvs {
417+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
418+ encode_tlv_stream ! ( w, {
419+ ( 12 , self . tlvs. payment_constraints, required) ,
420+ ( 65536 , self . tlvs. payment_secret, required) ,
421+ ( 65537 , self . tlvs. payment_context, required) ,
422+ ( 65539 , self . authentication, required) ,
423+ } ) ;
424+ Ok ( ( ) )
425+ }
426+ }
427+
428+ impl Writeable for UnauthenticatedReceiveTlvs {
395429 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
396430 encode_tlv_stream ! ( w, {
397431 ( 12 , self . payment_constraints, required) ,
398432 ( 65536 , self . payment_secret, required) ,
399433 ( 65537 , self . payment_context, required) ,
400- ( 65539 , self . authentication, option) ,
401434 } ) ;
402435 Ok ( ( ) )
403436 }
@@ -443,10 +476,12 @@ impl Readable for BlindedPaymentTlvs {
443476 } else {
444477 if payment_relay. is_some ( ) || features. is_some ( ) { return Err ( DecodeError :: InvalidValue ) }
445478 Ok ( BlindedPaymentTlvs :: Receive ( ReceiveTlvs {
446- payment_secret : payment_secret. ok_or ( DecodeError :: InvalidValue ) ?,
447- payment_constraints : payment_constraints. 0 . unwrap ( ) ,
448- payment_context : payment_context. ok_or ( DecodeError :: InvalidValue ) ?,
449- authentication,
479+ tlvs : UnauthenticatedReceiveTlvs {
480+ payment_secret : payment_secret. ok_or ( DecodeError :: InvalidValue ) ?,
481+ payment_constraints : payment_constraints. 0 . unwrap ( ) ,
482+ payment_context : payment_context. ok_or ( DecodeError :: InvalidValue ) ?,
483+ } ,
484+ authentication : authentication. ok_or ( DecodeError :: InvalidValue ) ?,
450485 } ) )
451486 }
452487 }
@@ -489,7 +524,7 @@ pub(crate) fn amt_to_forward_msat(inbound_amt_msat: u64, payment_relay: &Payment
489524}
490525
491526pub ( super ) fn compute_payinfo (
492- intermediate_nodes : & [ PaymentForwardNode ] , payee_tlvs : & ReceiveTlvs ,
527+ intermediate_nodes : & [ PaymentForwardNode ] , payee_tlvs : & UnauthenticatedReceiveTlvs ,
493528 payee_htlc_maximum_msat : u64 , min_final_cltv_expiry_delta : u16 ,
494529) -> Result < BlindedPayInfo , ( ) > {
495530 let mut curr_base_fee: u64 = 0 ;
@@ -613,7 +648,7 @@ impl_writeable_tlv_based!(Bolt12RefundContext, {});
613648#[ cfg( test) ]
614649mod tests {
615650 use bitcoin:: secp256k1:: PublicKey ;
616- use crate :: blinded_path:: payment:: { Bolt12RefundContext , PaymentForwardNode , ForwardTlvs , ReceiveTlvs , PaymentConstraints , PaymentContext , PaymentRelay } ;
651+ use crate :: blinded_path:: payment:: { Bolt12RefundContext , PaymentForwardNode , ForwardTlvs , PaymentConstraints , PaymentContext , PaymentRelay , UnauthenticatedReceiveTlvs } ;
617652 use crate :: types:: payment:: PaymentSecret ;
618653 use crate :: types:: features:: BlindedHopFeatures ;
619654 use crate :: ln:: functional_test_utils:: TEST_FINAL_CLTV ;
@@ -658,14 +693,13 @@ mod tests {
658693 } ,
659694 htlc_maximum_msat: u64 :: max_value( ) ,
660695 } ] ;
661- let recv_tlvs = ReceiveTlvs {
696+ let recv_tlvs = UnauthenticatedReceiveTlvs {
662697 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
663698 payment_constraints : PaymentConstraints {
664699 max_cltv_expiry : 0 ,
665700 htlc_minimum_msat : 1 ,
666701 } ,
667702 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
668- authentication : None ,
669703 } ;
670704 let htlc_maximum_msat = 100_000 ;
671705 let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, htlc_maximum_msat, 12 ) . unwrap ( ) ;
@@ -678,14 +712,13 @@ mod tests {
678712
679713 #[ test]
680714 fn compute_payinfo_1_hop ( ) {
681- let recv_tlvs = ReceiveTlvs {
715+ let recv_tlvs = UnauthenticatedReceiveTlvs {
682716 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
683717 payment_constraints : PaymentConstraints {
684718 max_cltv_expiry : 0 ,
685719 htlc_minimum_msat : 1 ,
686720 } ,
687721 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
688- authentication : None ,
689722 } ;
690723 let blinded_payinfo = super :: compute_payinfo ( & [ ] , & recv_tlvs, 4242 , TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
691724 assert_eq ! ( blinded_payinfo. fee_base_msat, 0 ) ;
@@ -735,14 +768,13 @@ mod tests {
735768 } ,
736769 htlc_maximum_msat: u64 :: max_value( )
737770 } ] ;
738- let recv_tlvs = ReceiveTlvs {
771+ let recv_tlvs = UnauthenticatedReceiveTlvs {
739772 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
740773 payment_constraints : PaymentConstraints {
741774 max_cltv_expiry : 0 ,
742775 htlc_minimum_msat : 3 ,
743776 } ,
744777 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
745- authentication : None ,
746778 } ;
747779 let htlc_maximum_msat = 100_000 ;
748780 let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, htlc_maximum_msat, TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
@@ -789,14 +821,13 @@ mod tests {
789821 } ,
790822 htlc_maximum_msat: u64 :: max_value( )
791823 } ] ;
792- let recv_tlvs = ReceiveTlvs {
824+ let recv_tlvs = UnauthenticatedReceiveTlvs {
793825 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
794826 payment_constraints : PaymentConstraints {
795827 max_cltv_expiry : 0 ,
796828 htlc_minimum_msat : 1 ,
797829 } ,
798830 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
799- authentication : None ,
800831 } ;
801832 let htlc_minimum_msat = 3798 ;
802833 assert ! ( super :: compute_payinfo( & intermediate_nodes[ ..] , & recv_tlvs, htlc_minimum_msat - 1 , TEST_FINAL_CLTV as u16 ) . is_err( ) ) ;
@@ -847,14 +878,13 @@ mod tests {
847878 } ,
848879 htlc_maximum_msat: 10_000
849880 } ] ;
850- let recv_tlvs = ReceiveTlvs {
881+ let recv_tlvs = UnauthenticatedReceiveTlvs {
851882 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
852883 payment_constraints : PaymentConstraints {
853884 max_cltv_expiry : 0 ,
854885 htlc_minimum_msat : 1 ,
855886 } ,
856887 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
857- authentication : None ,
858888 } ;
859889
860890 let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, 10_000 , TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
0 commit comments