Skip to content

Commit 898aa5f

Browse files
committed
Introduce construct_trampoline_onion_keys method
1 parent 1b2debb commit 898aa5f

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

lightning/src/ln/onion_utils.rs

+66
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,72 @@ pub(super) fn construct_onion_keys<T: secp256k1::Signing>(
176176
Ok(res)
177177
}
178178

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+
217+
// can only fail if an intermediary hop has an invalid public key or session_priv is invalid
218+
pub(super) fn construct_trampoline_onion_keys<T: secp256k1::Signing>(
219+
secp_ctx: &Secp256k1<T>, path: &Path, session_priv: &SecretKey,
220+
) -> Result<Vec<OnionKeys>, secp256k1::Error> {
221+
let mut res = Vec::with_capacity(path.trampoline_hops.len());
222+
223+
construct_trampoline_onion_keys_callback(
224+
secp_ctx,
225+
&path,
226+
session_priv,
227+
|shared_secret, _blinding_factor, ephemeral_pubkey, _, _| {
228+
let (rho, mu) = gen_rho_mu_from_shared_secret(shared_secret.as_ref());
229+
230+
res.push(OnionKeys {
231+
#[cfg(test)]
232+
shared_secret,
233+
#[cfg(test)]
234+
blinding_factor: _blinding_factor,
235+
ephemeral_pubkey,
236+
rho,
237+
mu,
238+
});
239+
},
240+
)?;
241+
242+
Ok(res)
243+
}
244+
179245
fn build_trampoline_onion_payloads<'a>(
180246
path: &'a Path, total_msat: u64, recipient_onion: &'a RecipientOnionFields,
181247
starting_htlc_offset: u32, keysend_preimage: &Option<PaymentPreimage>,

0 commit comments

Comments
 (0)