Skip to content

Commit f7825ba

Browse files
Support constructing onion keys for blinded hops
1 parent fc0cf41 commit f7825ba

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

lightning/src/ln/onion_utils.rs

+25-6
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,22 @@ pub(crate) fn next_hop_packet_pubkey<T: secp256k1::Signing + secp256k1::Verifica
104104

105105
// can only fail if an intermediary hop has an invalid public key or session_priv is invalid
106106
#[inline]
107-
pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(SharedSecret, [u8; 32], PublicKey, &RouteHop, usize)> (secp_ctx: &Secp256k1<T>, path: &Vec<RouteHop>, session_priv: &SecretKey, mut callback: FType) -> Result<(), secp256k1::Error> {
107+
pub(super) fn construct_onion_keys_callback<T, FType>(
108+
secp_ctx: &Secp256k1<T>, path: &Path, session_priv: &SecretKey, mut callback: FType
109+
) -> Result<(), secp256k1::Error>
110+
where
111+
T: secp256k1::Signing,
112+
FType: FnMut(SharedSecret, [u8; 32], PublicKey, Option<&RouteHop>, usize)
113+
{
108114
let mut blinded_priv = session_priv.clone();
109115
let mut blinded_pub = PublicKey::from_secret_key(secp_ctx, &blinded_priv);
110116

111-
for (idx, hop) in path.iter().enumerate() {
112-
let shared_secret = SharedSecret::new(&hop.pubkey, &blinded_priv);
117+
for (idx, (pubkey, route_hop_opt)) in path.hops.iter().map(|h| (h.pubkey, Some(h)))
118+
.chain(path.blinded_tail.as_ref().map(|t| t.hops.iter()).unwrap_or([].iter()).skip(1)
119+
.map(|h| (h.blinded_node_id, None)))
120+
.enumerate()
121+
{
122+
let shared_secret = SharedSecret::new(&pubkey, &blinded_priv);
113123

114124
let mut sha = Sha256::engine();
115125
sha.input(&blinded_pub.serialize()[..]);
@@ -121,7 +131,7 @@ pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(
121131
blinded_priv = blinded_priv.mul_tweak(&Scalar::from_be_bytes(blinding_factor).unwrap())?;
122132
blinded_pub = PublicKey::from_secret_key(secp_ctx, &blinded_priv);
123133

124-
callback(shared_secret, blinding_factor, ephemeral_pubkey, hop, idx);
134+
callback(shared_secret, blinding_factor, ephemeral_pubkey, route_hop_opt, idx);
125135
}
126136

127137
Ok(())
@@ -131,7 +141,9 @@ pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(
131141
pub(super) fn construct_onion_keys<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, path: &Path, session_priv: &SecretKey) -> Result<Vec<OnionKeys>, secp256k1::Error> {
132142
let mut res = Vec::with_capacity(path.hops.len());
133143

134-
construct_onion_keys_callback(secp_ctx, &path.hops, session_priv, |shared_secret, _blinding_factor, ephemeral_pubkey, _, _| {
144+
construct_onion_keys_callback(secp_ctx, &path, session_priv,
145+
|shared_secret, _blinding_factor, ephemeral_pubkey, _, _|
146+
{
135147
let (rho, mu) = gen_rho_mu_from_shared_secret(shared_secret.as_ref());
136148

137149
res.push(OnionKeys {
@@ -396,9 +408,16 @@ where L::Target: Logger {
396408
let mut is_from_final_node = false;
397409

398410
// Handle packed channel/node updates for passing back for the route handler
399-
construct_onion_keys_callback(secp_ctx, &path.hops, session_priv, |shared_secret, _, _, route_hop, route_hop_idx| {
411+
construct_onion_keys_callback(secp_ctx, &path, session_priv,
412+
|shared_secret, _, _, route_hop_opt, route_hop_idx|
413+
{
400414
if res.is_some() { return; }
401415

416+
let route_hop = match route_hop_opt {
417+
Some(hop) => hop,
418+
None => return,
419+
};
420+
402421
let amt_to_forward = htlc_msat - route_hop.fee_msat;
403422
htlc_msat = amt_to_forward;
404423

0 commit comments

Comments
 (0)