@@ -15,7 +15,7 @@ use crate::ln::channelmanager::{HTLCSource, RecipientOnionFields};
1515use crate :: ln:: msgs;
1616use crate :: offers:: invoice_request:: InvoiceRequest ;
1717use crate :: routing:: gossip:: NetworkUpdate ;
18- use crate :: routing:: router:: { Path , RouteHop , RouteParameters , TrampolineHop } ;
18+ use crate :: routing:: router:: { BlindedTail , Path , RouteHop , RouteParameters , TrampolineHop } ;
1919use crate :: sign:: NodeSigner ;
2020use crate :: types:: features:: { ChannelFeatures , NodeFeatures } ;
2121use crate :: types:: payment:: { PaymentHash , PaymentPreimage } ;
@@ -109,26 +109,42 @@ pub(crate) fn next_hop_pubkey<T: secp256k1::Verification>(
109109 curr_pubkey. mul_tweak ( secp_ctx, & Scalar :: from_be_bytes ( blinding_factor) . unwrap ( ) )
110110}
111111
112- // can only fail if an intermediary hop has an invalid public key or session_priv is invalid
112+ pub ( super ) trait HopInfo {
113+ fn node_pubkey ( & self ) -> & PublicKey ;
114+ }
115+
116+ impl HopInfo for RouteHop {
117+ fn node_pubkey ( & self ) -> & PublicKey {
118+ & self . pubkey
119+ }
120+ }
121+
122+ impl HopInfo for TrampolineHop {
123+ fn node_pubkey ( & self ) -> & PublicKey {
124+ & self . pubkey
125+ }
126+ }
127+
113128#[ inline]
114- pub ( super ) fn construct_onion_keys_callback < T , FType > (
115- secp_ctx : & Secp256k1 < T > , path : & Path , session_priv : & SecretKey , mut callback : FType ,
129+ pub ( super ) fn construct_onion_keys_generic_callback < T , H , FType > (
130+ secp_ctx : & Secp256k1 < T > , hops : & [ H ] , blinded_tail : Option < & BlindedTail > ,
131+ session_priv : & SecretKey , mut callback : FType ,
116132) -> Result < ( ) , secp256k1:: Error >
117133where
118134 T : secp256k1:: Signing ,
119- FType : FnMut ( SharedSecret , [ u8 ; 32 ] , PublicKey , Option < & RouteHop > , usize ) ,
135+ H : HopInfo ,
136+ FType : FnMut ( SharedSecret , [ u8 ; 32 ] , PublicKey , Option < & H > , usize ) ,
120137{
121138 let mut blinded_priv = session_priv. clone ( ) ;
122139 let mut blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
123140
124- let unblinded_hops_iter = path. hops . iter ( ) . map ( |h| ( & h. pubkey , Some ( h) ) ) ;
125- let blinded_pks_iter = path
126- . blinded_tail
127- . as_ref ( )
141+ let unblinded_hops_iter = hops. iter ( ) . map ( |h| ( h. node_pubkey ( ) , Some ( h) ) ) ;
142+ let blinded_pks_iter = blinded_tail
128143 . map ( |t| t. hops . iter ( ) )
129144 . unwrap_or ( [ ] . iter ( ) )
130145 . skip ( 1 ) // Skip the intro node because it's included in the unblinded hops
131146 . map ( |h| ( & h. blinded_node_id , None ) ) ;
147+
132148 for ( idx, ( pubkey, route_hop_opt) ) in unblinded_hops_iter. chain ( blinded_pks_iter) . enumerate ( ) {
133149 let shared_secret = SharedSecret :: new ( pubkey, & blinded_priv) ;
134150
@@ -154,9 +170,10 @@ pub(super) fn construct_onion_keys<T: secp256k1::Signing>(
154170) -> Result < Vec < OnionKeys > , secp256k1:: Error > {
155171 let mut res = Vec :: with_capacity ( path. hops . len ( ) ) ;
156172
157- construct_onion_keys_callback (
173+ construct_onion_keys_generic_callback (
158174 secp_ctx,
159- & path,
175+ & path. hops ,
176+ path. blinded_tail . as_ref ( ) ,
160177 session_priv,
161178 |shared_secret, _blinding_factor, ephemeral_pubkey, _, _| {
162179 let ( rho, mu) = gen_rho_mu_from_shared_secret ( shared_secret. as_ref ( ) ) ;
@@ -176,53 +193,16 @@ pub(super) fn construct_onion_keys<T: secp256k1::Signing>(
176193 Ok ( res)
177194}
178195
179- #[ inline]
180- pub ( super ) fn construct_trampoline_onion_keys_callback < T , FType > (
181- secp_ctx : & Secp256k1 < T > , path : & Path , session_priv : & SecretKey , mut callback : FType ,
182- ) -> Result < ( ) , secp256k1:: Error >
183- where
184- T : secp256k1:: Signing ,
185- FType : FnMut ( SharedSecret , [ u8 ; 32 ] , PublicKey , Option < & TrampolineHop > , usize ) ,
186- {
187- let mut blinded_priv = session_priv. clone ( ) ;
188- let mut blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
189-
190- let unblinded_hops_iter = path. trampoline_hops . iter ( ) . map ( |h| ( & h. pubkey , Some ( h) ) ) ;
191- let blinded_pks_iter = path
192- . blinded_tail
193- . as_ref ( )
194- . map ( |t| t. hops . iter ( ) )
195- . unwrap_or ( [ ] . iter ( ) )
196- . skip ( 1 ) // Skip the intro node because it's included in the unblinded hops
197- . map ( |h| ( & h. blinded_node_id , None ) ) ;
198- for ( idx, ( pubkey, route_hop_opt) ) in unblinded_hops_iter. chain ( blinded_pks_iter) . enumerate ( ) {
199- let shared_secret = SharedSecret :: new ( pubkey, & blinded_priv) ;
200-
201- let mut sha = Sha256 :: engine ( ) ;
202- sha. input ( & blinded_pub. serialize ( ) [ ..] ) ;
203- sha. input ( shared_secret. as_ref ( ) ) ;
204- let blinding_factor = Sha256 :: from_engine ( sha) . to_byte_array ( ) ;
205-
206- let ephemeral_pubkey = blinded_pub;
207-
208- blinded_priv = blinded_priv. mul_tweak ( & Scalar :: from_be_bytes ( blinding_factor) . unwrap ( ) ) ?;
209- blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
210-
211- callback ( shared_secret, blinding_factor, ephemeral_pubkey, route_hop_opt, idx) ;
212- }
213-
214- Ok ( ( ) )
215- }
216-
217196// can only fail if an intermediary hop has an invalid public key or session_priv is invalid
218197pub ( super ) fn construct_trampoline_onion_keys < T : secp256k1:: Signing > (
219198 secp_ctx : & Secp256k1 < T > , path : & Path , session_priv : & SecretKey ,
220199) -> Result < Vec < OnionKeys > , secp256k1:: Error > {
221200 let mut res = Vec :: with_capacity ( path. trampoline_hops . len ( ) ) ;
222201
223- construct_trampoline_onion_keys_callback (
202+ construct_onion_keys_generic_callback (
224203 secp_ctx,
225- & path,
204+ & path. trampoline_hops ,
205+ path. blinded_tail . as_ref ( ) ,
226206 session_priv,
227207 |shared_secret, _blinding_factor, ephemeral_pubkey, _, _| {
228208 let ( rho, mu) = gen_rho_mu_from_shared_secret ( shared_secret. as_ref ( ) ) ;
@@ -1074,8 +1054,14 @@ where
10741054 }
10751055 } ;
10761056
1077- construct_onion_keys_callback ( secp_ctx, & path, session_priv, callback)
1078- . expect ( "Route that we sent via spontaneously grew invalid keys in the middle of it?" ) ;
1057+ construct_onion_keys_generic_callback (
1058+ secp_ctx,
1059+ & path. hops ,
1060+ path. blinded_tail . as_ref ( ) ,
1061+ session_priv,
1062+ callback,
1063+ )
1064+ . expect ( "Route that we sent via spontaneously grew invalid keys in the middle of it?" ) ;
10791065
10801066 if let Some ( FailureLearnings {
10811067 network_update,
0 commit comments