@@ -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,43 @@ 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 ( crate ) 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+ impl ReceiveTlvs {
271+ /// Returns the underlying TLVs.
272+ pub fn tlvs ( & self ) -> & UnauthenticatedReceiveTlvs {
273+ & self . tlvs
274+ }
275+ }
276+
277+ /// An unauthenticated [`ReceiveTlvs`].
278+ #[ derive( Clone , Debug ) ]
279+ pub struct UnauthenticatedReceiveTlvs {
260280 /// Used to authenticate the sender of a payment to the receiver and tie MPP HTLCs together.
261281 pub payment_secret : PaymentSecret ,
262282 /// Constraints for the receiver of this payment.
263283 pub payment_constraints : PaymentConstraints ,
264284 /// Context for the receiver of this payment.
265285 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 ) > ,
286+ }
287+
288+ impl UnauthenticatedReceiveTlvs {
289+ /// Creates an authenticated [`ReceiveTlvs`], which includes an HMAC and the provide [`Nonce`]
290+ /// that can be use later to verify it authenticity.
291+ pub fn authenticate ( self , nonce : Nonce , expanded_key : & ExpandedKey ) -> ReceiveTlvs {
292+ ReceiveTlvs {
293+ authentication : ( self . hmac_for_offer_payment ( nonce, expanded_key) , nonce) ,
294+ tlvs : self ,
295+ }
296+ }
268297}
269298
270299/// Data to construct a [`BlindedHop`] for sending a payment over.
@@ -392,12 +421,23 @@ impl Writeable for ForwardTlvs {
392421}
393422
394423impl Writeable for ReceiveTlvs {
424+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
425+ encode_tlv_stream ! ( w, {
426+ ( 12 , self . tlvs. payment_constraints, required) ,
427+ ( 65536 , self . tlvs. payment_secret, required) ,
428+ ( 65537 , self . tlvs. payment_context, required) ,
429+ ( 65539 , self . authentication, required) ,
430+ } ) ;
431+ Ok ( ( ) )
432+ }
433+ }
434+
435+ impl Writeable for UnauthenticatedReceiveTlvs {
395436 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
396437 encode_tlv_stream ! ( w, {
397438 ( 12 , self . payment_constraints, required) ,
398439 ( 65536 , self . payment_secret, required) ,
399440 ( 65537 , self . payment_context, required) ,
400- ( 65539 , self . authentication, option) ,
401441 } ) ;
402442 Ok ( ( ) )
403443 }
@@ -443,10 +483,12 @@ impl Readable for BlindedPaymentTlvs {
443483 } else {
444484 if payment_relay. is_some ( ) || features. is_some ( ) { return Err ( DecodeError :: InvalidValue ) }
445485 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,
486+ tlvs : UnauthenticatedReceiveTlvs {
487+ payment_secret : payment_secret. ok_or ( DecodeError :: InvalidValue ) ?,
488+ payment_constraints : payment_constraints. 0 . unwrap ( ) ,
489+ payment_context : payment_context. ok_or ( DecodeError :: InvalidValue ) ?,
490+ } ,
491+ authentication : authentication. ok_or ( DecodeError :: InvalidValue ) ?,
450492 } ) )
451493 }
452494 }
@@ -489,7 +531,7 @@ pub(crate) fn amt_to_forward_msat(inbound_amt_msat: u64, payment_relay: &Payment
489531}
490532
491533pub ( super ) fn compute_payinfo (
492- intermediate_nodes : & [ PaymentForwardNode ] , payee_tlvs : & ReceiveTlvs ,
534+ intermediate_nodes : & [ PaymentForwardNode ] , payee_tlvs : & UnauthenticatedReceiveTlvs ,
493535 payee_htlc_maximum_msat : u64 , min_final_cltv_expiry_delta : u16 ,
494536) -> Result < BlindedPayInfo , ( ) > {
495537 let mut curr_base_fee: u64 = 0 ;
@@ -613,7 +655,7 @@ impl_writeable_tlv_based!(Bolt12RefundContext, {});
613655#[ cfg( test) ]
614656mod tests {
615657 use bitcoin:: secp256k1:: PublicKey ;
616- use crate :: blinded_path:: payment:: { Bolt12RefundContext , PaymentForwardNode , ForwardTlvs , ReceiveTlvs , PaymentConstraints , PaymentContext , PaymentRelay } ;
658+ use crate :: blinded_path:: payment:: { Bolt12RefundContext , PaymentForwardNode , ForwardTlvs , PaymentConstraints , PaymentContext , PaymentRelay , UnauthenticatedReceiveTlvs } ;
617659 use crate :: types:: payment:: PaymentSecret ;
618660 use crate :: types:: features:: BlindedHopFeatures ;
619661 use crate :: ln:: functional_test_utils:: TEST_FINAL_CLTV ;
@@ -658,14 +700,13 @@ mod tests {
658700 } ,
659701 htlc_maximum_msat: u64 :: max_value( ) ,
660702 } ] ;
661- let recv_tlvs = ReceiveTlvs {
703+ let recv_tlvs = UnauthenticatedReceiveTlvs {
662704 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
663705 payment_constraints : PaymentConstraints {
664706 max_cltv_expiry : 0 ,
665707 htlc_minimum_msat : 1 ,
666708 } ,
667709 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
668- authentication : None ,
669710 } ;
670711 let htlc_maximum_msat = 100_000 ;
671712 let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, htlc_maximum_msat, 12 ) . unwrap ( ) ;
@@ -678,14 +719,13 @@ mod tests {
678719
679720 #[ test]
680721 fn compute_payinfo_1_hop ( ) {
681- let recv_tlvs = ReceiveTlvs {
722+ let recv_tlvs = UnauthenticatedReceiveTlvs {
682723 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
683724 payment_constraints : PaymentConstraints {
684725 max_cltv_expiry : 0 ,
685726 htlc_minimum_msat : 1 ,
686727 } ,
687728 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
688- authentication : None ,
689729 } ;
690730 let blinded_payinfo = super :: compute_payinfo ( & [ ] , & recv_tlvs, 4242 , TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
691731 assert_eq ! ( blinded_payinfo. fee_base_msat, 0 ) ;
@@ -735,14 +775,13 @@ mod tests {
735775 } ,
736776 htlc_maximum_msat: u64 :: max_value( )
737777 } ] ;
738- let recv_tlvs = ReceiveTlvs {
778+ let recv_tlvs = UnauthenticatedReceiveTlvs {
739779 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
740780 payment_constraints : PaymentConstraints {
741781 max_cltv_expiry : 0 ,
742782 htlc_minimum_msat : 3 ,
743783 } ,
744784 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
745- authentication : None ,
746785 } ;
747786 let htlc_maximum_msat = 100_000 ;
748787 let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, htlc_maximum_msat, TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
@@ -789,14 +828,13 @@ mod tests {
789828 } ,
790829 htlc_maximum_msat: u64 :: max_value( )
791830 } ] ;
792- let recv_tlvs = ReceiveTlvs {
831+ let recv_tlvs = UnauthenticatedReceiveTlvs {
793832 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
794833 payment_constraints : PaymentConstraints {
795834 max_cltv_expiry : 0 ,
796835 htlc_minimum_msat : 1 ,
797836 } ,
798837 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
799- authentication : None ,
800838 } ;
801839 let htlc_minimum_msat = 3798 ;
802840 assert ! ( super :: compute_payinfo( & intermediate_nodes[ ..] , & recv_tlvs, htlc_minimum_msat - 1 , TEST_FINAL_CLTV as u16 ) . is_err( ) ) ;
@@ -847,14 +885,13 @@ mod tests {
847885 } ,
848886 htlc_maximum_msat: 10_000
849887 } ] ;
850- let recv_tlvs = ReceiveTlvs {
888+ let recv_tlvs = UnauthenticatedReceiveTlvs {
851889 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
852890 payment_constraints : PaymentConstraints {
853891 max_cltv_expiry : 0 ,
854892 htlc_minimum_msat : 1 ,
855893 } ,
856894 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
857- authentication : None ,
858895 } ;
859896
860897 let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, 10_000 , TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
0 commit comments