9
9
10
10
//! Data structures and methods for constructing [`BlindedPaymentPath`]s to send a payment over.
11
11
12
+ use bitcoin:: hashes:: hmac:: Hmac ;
13
+ use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
12
14
use bitcoin:: secp256k1:: { self , PublicKey , Secp256k1 , SecretKey } ;
13
15
14
16
use crate :: blinded_path:: { BlindedHop , BlindedPath , IntroductionNode , NodeIdLookUp } ;
@@ -18,10 +20,13 @@ use crate::io;
18
20
use crate :: io:: Cursor ;
19
21
use crate :: types:: payment:: PaymentSecret ;
20
22
use crate :: ln:: channel_state:: CounterpartyForwardingInfo ;
23
+ use crate :: ln:: channelmanager:: Verification ;
21
24
use crate :: types:: features:: BlindedHopFeatures ;
25
+ use crate :: ln:: inbound_payment:: ExpandedKey ;
22
26
use crate :: ln:: msgs:: DecodeError ;
23
27
use crate :: ln:: onion_utils;
24
28
use crate :: offers:: invoice_request:: InvoiceRequestFields ;
29
+ use crate :: offers:: nonce:: Nonce ;
25
30
use crate :: offers:: offer:: OfferId ;
26
31
use crate :: routing:: gossip:: { NodeId , ReadOnlyNetworkGraph } ;
27
32
use crate :: sign:: { EntropySource , NodeSigner , Recipient } ;
@@ -114,7 +119,7 @@ impl BlindedPaymentPath {
114
119
let blinding_secret = SecretKey :: from_slice ( & blinding_secret_bytes[ ..] ) . expect ( "RNG is busted" ) ;
115
120
116
121
let blinded_payinfo = compute_payinfo (
117
- 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
118
123
) ?;
119
124
Ok ( Self {
120
125
inner_path : BlindedPath {
@@ -252,8 +257,26 @@ pub struct ForwardTlvs {
252
257
253
258
/// Data to construct a [`BlindedHop`] for receiving a payment. This payload is custom to LDK and
254
259
/// may not be valid if received by another lightning implementation.
260
+ ///
261
+ /// Can only be constructed by calling [`UnauthenticatedReceiveTlvs::authenticate`].
255
262
#[ derive( Clone , Debug ) ]
256
263
pub 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 {
257
280
/// Used to authenticate the sender of a payment to the receiver and tie MPP HTLCs together.
258
281
pub payment_secret : PaymentSecret ,
259
282
/// Constraints for the receiver of this payment.
@@ -262,6 +285,17 @@ pub struct ReceiveTlvs {
262
285
pub payment_context : PaymentContext ,
263
286
}
264
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
+ }
297
+ }
298
+
265
299
/// Data to construct a [`BlindedHop`] for sending a payment over.
266
300
///
267
301
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
@@ -400,11 +434,23 @@ impl Writeable for ForwardTlvs {
400
434
}
401
435
402
436
impl Writeable for ReceiveTlvs {
437
+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
438
+ encode_tlv_stream ! ( w, {
439
+ ( 12 , self . tlvs. payment_constraints, required) ,
440
+ ( 65536 , self . tlvs. payment_secret, required) ,
441
+ ( 65537 , self . tlvs. payment_context, required) ,
442
+ ( 65539 , self . authentication, required) ,
443
+ } ) ;
444
+ Ok ( ( ) )
445
+ }
446
+ }
447
+
448
+ impl Writeable for UnauthenticatedReceiveTlvs {
403
449
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
404
450
encode_tlv_stream ! ( w, {
405
451
( 12 , self . payment_constraints, required) ,
406
452
( 65536 , self . payment_secret, required) ,
407
- ( 65537 , self . payment_context, required)
453
+ ( 65537 , self . payment_context, required) ,
408
454
} ) ;
409
455
Ok ( ( ) )
410
456
}
@@ -432,6 +478,7 @@ impl Readable for BlindedPaymentTlvs {
432
478
( 14 , features, ( option, encoding: ( BlindedHopFeatures , WithoutLength ) ) ) ,
433
479
( 65536 , payment_secret, option) ,
434
480
( 65537 , payment_context, ( default_value, PaymentContext :: unknown( ) ) ) ,
481
+ ( 65539 , authentication, option) ,
435
482
} ) ;
436
483
let _padding: Option < utils:: Padding > = _padding;
437
484
@@ -449,9 +496,12 @@ impl Readable for BlindedPaymentTlvs {
449
496
} else {
450
497
if payment_relay. is_some ( ) || features. is_some ( ) { return Err ( DecodeError :: InvalidValue ) }
451
498
Ok ( BlindedPaymentTlvs :: Receive ( ReceiveTlvs {
452
- payment_secret : payment_secret. ok_or ( DecodeError :: InvalidValue ) ?,
453
- payment_constraints : payment_constraints. 0 . unwrap ( ) ,
454
- payment_context : payment_context. 0 . unwrap ( ) ,
499
+ tlvs : UnauthenticatedReceiveTlvs {
500
+ payment_secret : payment_secret. ok_or ( DecodeError :: InvalidValue ) ?,
501
+ payment_constraints : payment_constraints. 0 . unwrap ( ) ,
502
+ payment_context : payment_context. 0 . unwrap ( ) ,
503
+ } ,
504
+ authentication : authentication. ok_or ( DecodeError :: InvalidValue ) ?,
455
505
} ) )
456
506
}
457
507
}
@@ -494,7 +544,7 @@ pub(crate) fn amt_to_forward_msat(inbound_amt_msat: u64, payment_relay: &Payment
494
544
}
495
545
496
546
pub ( super ) fn compute_payinfo (
497
- intermediate_nodes : & [ PaymentForwardNode ] , payee_tlvs : & ReceiveTlvs ,
547
+ intermediate_nodes : & [ PaymentForwardNode ] , payee_tlvs : & UnauthenticatedReceiveTlvs ,
498
548
payee_htlc_maximum_msat : u64 , min_final_cltv_expiry_delta : u16 ,
499
549
) -> Result < BlindedPayInfo , ( ) > {
500
550
let mut curr_base_fee: u64 = 0 ;
@@ -631,7 +681,7 @@ impl_writeable_tlv_based!(Bolt12RefundContext, {});
631
681
#[ cfg( test) ]
632
682
mod tests {
633
683
use bitcoin:: secp256k1:: PublicKey ;
634
- use crate :: blinded_path:: payment:: { PaymentForwardNode , ForwardTlvs , ReceiveTlvs , PaymentConstraints , PaymentContext , PaymentRelay } ;
684
+ use crate :: blinded_path:: payment:: { PaymentForwardNode , ForwardTlvs , PaymentConstraints , PaymentContext , PaymentRelay , UnauthenticatedReceiveTlvs } ;
635
685
use crate :: types:: payment:: PaymentSecret ;
636
686
use crate :: types:: features:: BlindedHopFeatures ;
637
687
use crate :: ln:: functional_test_utils:: TEST_FINAL_CLTV ;
@@ -676,7 +726,7 @@ mod tests {
676
726
} ,
677
727
htlc_maximum_msat: u64 :: max_value( ) ,
678
728
} ] ;
679
- let recv_tlvs = ReceiveTlvs {
729
+ let recv_tlvs = UnauthenticatedReceiveTlvs {
680
730
payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
681
731
payment_constraints : PaymentConstraints {
682
732
max_cltv_expiry : 0 ,
@@ -695,7 +745,7 @@ mod tests {
695
745
696
746
#[ test]
697
747
fn compute_payinfo_1_hop ( ) {
698
- let recv_tlvs = ReceiveTlvs {
748
+ let recv_tlvs = UnauthenticatedReceiveTlvs {
699
749
payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
700
750
payment_constraints : PaymentConstraints {
701
751
max_cltv_expiry : 0 ,
@@ -751,7 +801,7 @@ mod tests {
751
801
} ,
752
802
htlc_maximum_msat: u64 :: max_value( )
753
803
} ] ;
754
- let recv_tlvs = ReceiveTlvs {
804
+ let recv_tlvs = UnauthenticatedReceiveTlvs {
755
805
payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
756
806
payment_constraints : PaymentConstraints {
757
807
max_cltv_expiry : 0 ,
@@ -804,7 +854,7 @@ mod tests {
804
854
} ,
805
855
htlc_maximum_msat: u64 :: max_value( )
806
856
} ] ;
807
- let recv_tlvs = ReceiveTlvs {
857
+ let recv_tlvs = UnauthenticatedReceiveTlvs {
808
858
payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
809
859
payment_constraints : PaymentConstraints {
810
860
max_cltv_expiry : 0 ,
@@ -861,7 +911,7 @@ mod tests {
861
911
} ,
862
912
htlc_maximum_msat: 10_000
863
913
} ] ;
864
- let recv_tlvs = ReceiveTlvs {
914
+ let recv_tlvs = UnauthenticatedReceiveTlvs {
865
915
payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
866
916
payment_constraints : PaymentConstraints {
867
917
max_cltv_expiry : 0 ,
0 commit comments