Remove redundant `claiming_channel_id` variable
[rust-lightning] / lightning / src / blinded_path / message.rs
index 024fb451d00a78d1fe42a0524b042cfe3f42b9ec..3a5541fa1468272f3859972bca2cdfb4f8053ee8 100644 (file)
@@ -1,9 +1,18 @@
 use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey};
-use crate::blinded_path::BlindedHop;
+
+use crate::blinded_path::{BlindedHop, BlindedPath};
 use crate::blinded_path::utils;
 use crate::io;
+use crate::io::Cursor;
+use crate::ln::onion_utils;
+use crate::onion_message::packet::ControlTlvs;
 use crate::prelude::*;
-use crate::util::ser::{Writeable, Writer};
+use crate::sign::{NodeSigner, Recipient};
+use crate::crypto::streams::ChaChaPolyReadAdapter;
+use crate::util::ser::{FixedLengthReader, LengthReadableArgs, Writeable, Writer};
+
+use core::mem;
+use core::ops::Deref;
 
 /// TLVs to encode in an intermediate onion message packet's hop data. When provided in a blinded
 /// route, they are encoded into [`BlindedHop::encrypted_payload`].
@@ -48,32 +57,41 @@ impl Writeable for ReceiveTlvs {
 pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
        secp_ctx: &Secp256k1<T>, unblinded_path: &[PublicKey], session_priv: &SecretKey
 ) -> Result<Vec<BlindedHop>, secp256k1::Error> {
-       let mut blinded_hops = Vec::with_capacity(unblinded_path.len());
-
-       let mut prev_ss_and_blinded_node_id = None;
-       utils::construct_keys_callback(secp_ctx, unblinded_path, None, session_priv, |blinded_node_id, _, _, encrypted_payload_ss, unblinded_pk, _| {
-               if let Some((prev_ss, prev_blinded_node_id)) = prev_ss_and_blinded_node_id {
-                       if let Some(pk) = unblinded_pk {
-                               let payload = ForwardTlvs {
-                                       next_node_id: pk,
-                                       next_blinding_override: None,
-                               };
-                               blinded_hops.push(BlindedHop {
-                                       blinded_node_id: prev_blinded_node_id,
-                                       encrypted_payload: utils::encrypt_payload(payload, prev_ss),
-                               });
-                       } else { debug_assert!(false); }
-               }
-               prev_ss_and_blinded_node_id = Some((encrypted_payload_ss, blinded_node_id));
-       })?;
+       let blinded_tlvs = unblinded_path.iter()
+               .skip(1) // The first node's TLVs contains the next node's pubkey
+               .map(|pk| {
+                       ControlTlvs::Forward(ForwardTlvs { next_node_id: *pk, next_blinding_override: None })
+               })
+               .chain(core::iter::once(ControlTlvs::Receive(ReceiveTlvs { path_id: None })));
 
-       if let Some((final_ss, final_blinded_node_id)) = prev_ss_and_blinded_node_id {
-               let final_payload = ReceiveTlvs { path_id: None };
-               blinded_hops.push(BlindedHop {
-                       blinded_node_id: final_blinded_node_id,
-                       encrypted_payload: utils::encrypt_payload(final_payload, final_ss),
-               });
-       } else { debug_assert!(false) }
+       utils::construct_blinded_hops(secp_ctx, unblinded_path.iter(), blinded_tlvs, session_priv)
+}
 
-       Ok(blinded_hops)
+// Advance the blinded onion message path by one hop, so make the second hop into the new
+// introduction node.
+pub(crate) fn advance_path_by_one<NS: Deref, T: secp256k1::Signing + secp256k1::Verification>(
+       path: &mut BlindedPath, node_signer: &NS, secp_ctx: &Secp256k1<T>
+) -> Result<(), ()> where NS::Target: NodeSigner {
+       let control_tlvs_ss = node_signer.ecdh(Recipient::Node, &path.blinding_point, None)?;
+       let rho = onion_utils::gen_rho_from_shared_secret(&control_tlvs_ss.secret_bytes());
+       let encrypted_control_tlvs = path.blinded_hops.remove(0).encrypted_payload;
+       let mut s = Cursor::new(&encrypted_control_tlvs);
+       let mut reader = FixedLengthReader::new(&mut s, encrypted_control_tlvs.len() as u64);
+       match ChaChaPolyReadAdapter::read(&mut reader, rho) {
+               Ok(ChaChaPolyReadAdapter { readable: ControlTlvs::Forward(ForwardTlvs {
+                       mut next_node_id, next_blinding_override,
+               })}) => {
+                       let mut new_blinding_point = match next_blinding_override {
+                               Some(blinding_point) => blinding_point,
+                               None => {
+                                       onion_utils::next_hop_pubkey(secp_ctx, path.blinding_point,
+                                               control_tlvs_ss.as_ref()).map_err(|_| ())?
+                               }
+                       };
+                       mem::swap(&mut path.blinding_point, &mut new_blinding_point);
+                       mem::swap(&mut path.introduction_node_id, &mut next_node_id);
+                       Ok(())
+               },
+               _ => Err(())
+       }
 }