@@ -992,41 +992,19 @@ pub fn process_onion_failure<T: secp256k1::Signing, L: Deref>(
992
992
where
993
993
L :: Target : Logger ,
994
994
{
995
- let ( path, primary_session_priv ) = match htlc_source {
995
+ let ( path, session_priv ) = match htlc_source {
996
996
HTLCSource :: OutboundRoute { ref path, ref session_priv, .. } => ( path, session_priv) ,
997
997
_ => unreachable ! ( ) ,
998
998
} ;
999
999
1000
- if path. has_trampoline_hops ( ) {
1001
- // If we have Trampoline hops, the outer onion session_priv is a hash of the inner one.
1002
- let session_priv_hash = Sha256 :: hash ( & primary_session_priv. secret_bytes ( ) ) . to_byte_array ( ) ;
1003
- let outer_session_priv =
1004
- SecretKey :: from_slice ( & session_priv_hash[ ..] ) . expect ( "You broke SHA-256!" ) ;
1005
- process_onion_failure_inner (
1006
- secp_ctx,
1007
- logger,
1008
- path,
1009
- & outer_session_priv,
1010
- Some ( primary_session_priv) ,
1011
- encrypted_packet,
1012
- )
1013
- } else {
1014
- process_onion_failure_inner (
1015
- secp_ctx,
1016
- logger,
1017
- path,
1018
- primary_session_priv,
1019
- None ,
1020
- encrypted_packet,
1021
- )
1022
- }
1000
+ process_onion_failure_inner ( secp_ctx, logger, path, & session_priv, None , encrypted_packet)
1023
1001
}
1024
1002
1025
1003
/// Process failure we got back from upstream on a payment we sent (implying htlc_source is an
1026
1004
/// OutboundRoute).
1027
1005
fn process_onion_failure_inner < T : secp256k1:: Signing , L : Deref > (
1028
- secp_ctx : & Secp256k1 < T > , logger : & L , path : & Path , outer_session_priv : & SecretKey ,
1029
- inner_session_priv : Option < & SecretKey > , mut encrypted_packet : OnionErrorPacket ,
1006
+ secp_ctx : & Secp256k1 < T > , logger : & L , path : & Path , session_priv : & SecretKey ,
1007
+ trampoline_session_priv_override : Option < SecretKey > , mut encrypted_packet : OnionErrorPacket ,
1030
1008
) -> DecodedOnionFailure
1031
1009
where
1032
1010
L :: Target : Logger ,
@@ -1097,22 +1075,27 @@ where
1097
1075
let nontrampoline_bt =
1098
1076
if path. has_trampoline_hops ( ) { None } else { path. blinded_tail . as_ref ( ) } ;
1099
1077
let nontrampolines =
1100
- construct_onion_keys_generic ( secp_ctx, & path. hops , nontrampoline_bt, outer_session_priv )
1101
- . map ( |( shared_secret, _, _, route_hop_option, _) | {
1078
+ construct_onion_keys_generic ( secp_ctx, & path. hops , nontrampoline_bt, session_priv ) . map (
1079
+ |( shared_secret, _, _, route_hop_option, _) | {
1102
1080
( route_hop_option. map ( |rh| ErrorHop :: RouteHop ( rh) ) , shared_secret)
1103
- } ) ;
1081
+ } ,
1082
+ ) ;
1104
1083
1105
1084
let trampolines = if path. has_trampoline_hops ( ) {
1106
1085
// Trampoline hops are part of the blinded tail, so this can never panic
1107
1086
let blinded_tail = path. blinded_tail . as_ref ( ) ;
1108
1087
let hops = & blinded_tail. unwrap ( ) . trampoline_hops ;
1109
- let inner_session_priv =
1110
- inner_session_priv. expect ( "Trampoline hops always have an inner session priv" ) ;
1111
- Some ( construct_onion_keys_generic ( secp_ctx, hops, blinded_tail, inner_session_priv) . map (
1112
- |( shared_secret, _, _, route_hop_option, _) | {
1113
- ( route_hop_option. map ( |tram_hop| ErrorHop :: TrampolineHop ( tram_hop) ) , shared_secret)
1114
- } ,
1115
- ) )
1088
+ let trampoline_session_priv = trampoline_session_priv_override
1089
+ . unwrap_or_else ( || compute_trampoline_session_priv ( session_priv) ) ;
1090
+ Some (
1091
+ construct_onion_keys_generic ( secp_ctx, hops, blinded_tail, & trampoline_session_priv)
1092
+ . map ( |( shared_secret, _, _, route_hop_option, _) | {
1093
+ (
1094
+ route_hop_option. map ( |tram_hop| ErrorHop :: TrampolineHop ( tram_hop) ) ,
1095
+ shared_secret,
1096
+ )
1097
+ } ) ,
1098
+ )
1116
1099
} else {
1117
1100
None
1118
1101
} ;
@@ -2513,18 +2496,24 @@ pub fn create_payment_onion<T: secp256k1::Signing>(
2513
2496
)
2514
2497
}
2515
2498
2499
+ pub ( super ) fn compute_trampoline_session_priv ( outer_onion_session_priv : & SecretKey ) -> SecretKey {
2500
+ // When creating the inner trampoline onion, we set the session priv to the hash of the outer
2501
+ // onion session priv.
2502
+ let session_priv_hash = Sha256 :: hash ( & outer_onion_session_priv. secret_bytes ( ) ) . to_byte_array ( ) ;
2503
+ SecretKey :: from_slice ( & session_priv_hash[ ..] ) . expect ( "You broke SHA-256!" )
2504
+ }
2505
+
2516
2506
/// Build a payment onion, returning the first hop msat and cltv values as well.
2517
2507
/// `cur_block_height` should be set to the best known block height + 1.
2518
2508
pub ( crate ) fn create_payment_onion_internal < T : secp256k1:: Signing > (
2519
2509
secp_ctx : & Secp256k1 < T > , path : & Path , session_priv : & SecretKey , total_msat : u64 ,
2520
2510
recipient_onion : & RecipientOnionFields , cur_block_height : u32 , payment_hash : & PaymentHash ,
2521
2511
keysend_preimage : & Option < PaymentPreimage > , invoice_request : Option < & InvoiceRequest > ,
2522
- prng_seed : [ u8 ; 32 ] , secondary_session_priv : Option < SecretKey > ,
2523
- secondary_prng_seed : Option < [ u8 ; 32 ] > ,
2512
+ prng_seed : [ u8 ; 32 ] , trampoline_session_priv_override : Option < SecretKey > ,
2513
+ trampoline_prng_seed_override : Option < [ u8 ; 32 ] > ,
2524
2514
) -> Result < ( msgs:: OnionPacket , u64 , u32 ) , APIError > {
2525
2515
let mut outer_total_msat = total_msat;
2526
2516
let mut outer_starting_htlc_offset = cur_block_height;
2527
- let mut outer_session_priv_override = None ;
2528
2517
let mut trampoline_packet_option = None ;
2529
2518
2530
2519
if let Some ( blinded_tail) = & path. blinded_tail {
@@ -2539,12 +2528,15 @@ pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
2539
2528
keysend_preimage,
2540
2529
) ?;
2541
2530
2531
+ let trampoline_session_priv = trampoline_session_priv_override
2532
+ . unwrap_or_else ( || compute_trampoline_session_priv ( session_priv) ) ;
2533
+ let trampoline_prng_seed = trampoline_prng_seed_override. unwrap_or ( prng_seed) ;
2542
2534
let onion_keys =
2543
- construct_trampoline_onion_keys ( & secp_ctx, & blinded_tail, & session_priv ) ;
2535
+ construct_trampoline_onion_keys ( & secp_ctx, & blinded_tail, & trampoline_session_priv ) ;
2544
2536
let trampoline_packet = construct_trampoline_onion_packet (
2545
2537
trampoline_payloads,
2546
2538
onion_keys,
2547
- prng_seed ,
2539
+ trampoline_prng_seed ,
2548
2540
payment_hash,
2549
2541
// TODO: specify a fixed size for privacy in future spec upgrade
2550
2542
None ,
@@ -2554,11 +2546,6 @@ pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
2554
2546
} ) ?;
2555
2547
2556
2548
trampoline_packet_option = Some ( trampoline_packet) ;
2557
-
2558
- outer_session_priv_override = Some ( secondary_session_priv. unwrap_or_else ( || {
2559
- let session_priv_hash = Sha256 :: hash ( & session_priv. secret_bytes ( ) ) . to_byte_array ( ) ;
2560
- SecretKey :: from_slice ( & session_priv_hash[ ..] ) . expect ( "You broke SHA-256!" )
2561
- } ) ) ;
2562
2549
}
2563
2550
}
2564
2551
@@ -2572,14 +2559,11 @@ pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
2572
2559
trampoline_packet_option,
2573
2560
) ?;
2574
2561
2575
- let outer_session_priv = outer_session_priv_override. as_ref ( ) . unwrap_or ( session_priv) ;
2576
- let onion_keys = construct_onion_keys ( & secp_ctx, & path, outer_session_priv) ;
2577
- let outer_onion_prng_seed = secondary_prng_seed. unwrap_or ( prng_seed) ;
2578
- let onion_packet =
2579
- construct_onion_packet ( onion_payloads, onion_keys, outer_onion_prng_seed, payment_hash)
2580
- . map_err ( |_| APIError :: InvalidRoute {
2581
- err : "Route size too large considering onion data" . to_owned ( ) ,
2582
- } ) ?;
2562
+ let onion_keys = construct_onion_keys ( & secp_ctx, & path, session_priv) ;
2563
+ let onion_packet = construct_onion_packet ( onion_payloads, onion_keys, prng_seed, payment_hash)
2564
+ . map_err ( |_| APIError :: InvalidRoute {
2565
+ err : "Route size too large considering onion data" . to_owned ( ) ,
2566
+ } ) ?;
2583
2567
Ok ( ( onion_packet, htlc_msat, htlc_cltv) )
2584
2568
}
2585
2569
@@ -3571,7 +3555,7 @@ mod tests {
3571
3555
& logger,
3572
3556
& build_trampoline_test_path ( ) ,
3573
3557
& outer_session_priv,
3574
- Some ( & trampoline_session_priv) ,
3558
+ Some ( trampoline_session_priv) ,
3575
3559
error_packet,
3576
3560
) ;
3577
3561
assert_eq ! (
@@ -3584,19 +3568,15 @@ mod tests {
3584
3568
// shared secret cryptography sanity tests
3585
3569
let session_priv = get_test_session_key ( ) ;
3586
3570
let path = build_trampoline_test_path ( ) ;
3571
+ let outer_onion_keys = construct_onion_keys ( & Secp256k1 :: new ( ) , & path, & session_priv) ;
3587
3572
3573
+ let trampoline_session_priv = compute_trampoline_session_priv ( & session_priv) ;
3588
3574
let trampoline_onion_keys = construct_trampoline_onion_keys (
3589
3575
& secp_ctx,
3590
3576
& path. blinded_tail . as_ref ( ) . unwrap ( ) ,
3591
- & session_priv ,
3577
+ & trampoline_session_priv ,
3592
3578
) ;
3593
3579
3594
- let outer_onion_keys = {
3595
- let session_priv_hash = Sha256 :: hash ( & session_priv. secret_bytes ( ) ) . to_byte_array ( ) ;
3596
- let outer_session_priv = SecretKey :: from_slice ( & session_priv_hash[ ..] ) . unwrap ( ) ;
3597
- construct_onion_keys ( & Secp256k1 :: new ( ) , & path, & outer_session_priv)
3598
- } ;
3599
-
3600
3580
let htlc_source = HTLCSource :: OutboundRoute {
3601
3581
path,
3602
3582
session_priv,
0 commit comments