@@ -992,41 +992,19 @@ pub fn process_onion_failure<T: secp256k1::Signing, L: Deref>(
992992where
993993 L :: Target : Logger ,
994994{
995- let ( path, primary_session_priv ) = match htlc_source {
995+ let ( path, session_priv ) = match htlc_source {
996996 HTLCSource :: OutboundRoute { ref path, ref session_priv, .. } => ( path, session_priv) ,
997997 _ => unreachable ! ( ) ,
998998 } ;
999999
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)
10231001}
10241002
10251003/// Process failure we got back from upstream on a payment we sent (implying htlc_source is an
10261004/// OutboundRoute).
10271005fn 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 ,
10301008) -> DecodedOnionFailure
10311009where
10321010 L :: Target : Logger ,
@@ -1097,22 +1075,27 @@ where
10971075 let nontrampoline_bt =
10981076 if path. has_trampoline_hops ( ) { None } else { path. blinded_tail . as_ref ( ) } ;
10991077 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, _) | {
11021080 ( route_hop_option. map ( |rh| ErrorHop :: RouteHop ( rh) ) , shared_secret)
1103- } ) ;
1081+ } ,
1082+ ) ;
11041083
11051084 let trampolines = if path. has_trampoline_hops ( ) {
11061085 // Trampoline hops are part of the blinded tail, so this can never panic
11071086 let blinded_tail = path. blinded_tail . as_ref ( ) ;
11081087 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+ )
11161099 } else {
11171100 None
11181101 } ;
@@ -2513,18 +2496,24 @@ pub fn create_payment_onion<T: secp256k1::Signing>(
25132496 )
25142497}
25152498
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+
25162506/// Build a payment onion, returning the first hop msat and cltv values as well.
25172507/// `cur_block_height` should be set to the best known block height + 1.
25182508pub ( crate ) fn create_payment_onion_internal < T : secp256k1:: Signing > (
25192509 secp_ctx : & Secp256k1 < T > , path : & Path , session_priv : & SecretKey , total_msat : u64 ,
25202510 recipient_onion : & RecipientOnionFields , cur_block_height : u32 , payment_hash : & PaymentHash ,
25212511 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 ] > ,
25242514) -> Result < ( msgs:: OnionPacket , u64 , u32 ) , APIError > {
25252515 let mut outer_total_msat = total_msat;
25262516 let mut outer_starting_htlc_offset = cur_block_height;
2527- let mut outer_session_priv_override = None ;
25282517 let mut trampoline_packet_option = None ;
25292518
25302519 if let Some ( blinded_tail) = & path. blinded_tail {
@@ -2539,12 +2528,15 @@ pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
25392528 keysend_preimage,
25402529 ) ?;
25412530
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) ;
25422534 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 ) ;
25442536 let trampoline_packet = construct_trampoline_onion_packet (
25452537 trampoline_payloads,
25462538 onion_keys,
2547- prng_seed ,
2539+ trampoline_prng_seed ,
25482540 payment_hash,
25492541 // TODO: specify a fixed size for privacy in future spec upgrade
25502542 None ,
@@ -2554,11 +2546,6 @@ pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
25542546 } ) ?;
25552547
25562548 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- } ) ) ;
25622549 }
25632550 }
25642551
@@ -2572,14 +2559,11 @@ pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
25722559 trampoline_packet_option,
25732560 ) ?;
25742561
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+ } ) ?;
25832567 Ok ( ( onion_packet, htlc_msat, htlc_cltv) )
25842568}
25852569
@@ -3571,7 +3555,7 @@ mod tests {
35713555 & logger,
35723556 & build_trampoline_test_path ( ) ,
35733557 & outer_session_priv,
3574- Some ( & trampoline_session_priv) ,
3558+ Some ( trampoline_session_priv) ,
35753559 error_packet,
35763560 ) ;
35773561 assert_eq ! (
@@ -3584,19 +3568,15 @@ mod tests {
35843568 // shared secret cryptography sanity tests
35853569 let session_priv = get_test_session_key ( ) ;
35863570 let path = build_trampoline_test_path ( ) ;
3571+ let outer_onion_keys = construct_onion_keys ( & Secp256k1 :: new ( ) , & path, & session_priv) ;
35873572
3573+ let trampoline_session_priv = compute_trampoline_session_priv ( & session_priv) ;
35883574 let trampoline_onion_keys = construct_trampoline_onion_keys (
35893575 & secp_ctx,
35903576 & path. blinded_tail . as_ref ( ) . unwrap ( ) ,
3591- & session_priv ,
3577+ & trampoline_session_priv ,
35923578 ) ;
35933579
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-
36003580 let htlc_source = HTLCSource :: OutboundRoute {
36013581 path,
36023582 session_priv,
0 commit comments