Minor BlindedHop docs update
[rust-lightning] / lightning / src / blinded_path / utils.rs
index 1993ad932267db8f2d2c8a98f999f2726530b833..1ac6519452c1eb10af3757240d41a046d381efaa 100644 (file)
@@ -16,18 +16,26 @@ use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey, Scalar};
 use bitcoin::secp256k1::ecdh::SharedSecret;
 
 use super::BlindedPath;
+use crate::ln::msgs::DecodeError;
 use crate::ln::onion_utils;
 use crate::onion_message::Destination;
+use crate::util::chacha20poly1305rfc::ChaChaPolyWriteAdapter;
+use crate::util::ser::{Readable, VecWriter, Writeable};
 
+use crate::io;
 use crate::prelude::*;
 
 // TODO: DRY with onion_utils::construct_onion_keys_callback
 #[inline]
-pub(crate) fn construct_keys_callback<T: secp256k1::Signing + secp256k1::Verification,
-       FType: FnMut(PublicKey, SharedSecret, PublicKey, [u8; 32], Option<PublicKey>, Option<Vec<u8>>)>(
-       secp_ctx: &Secp256k1<T>, unblinded_path: &[PublicKey], destination: Option<Destination>,
-       session_priv: &SecretKey, mut callback: FType
-) -> Result<(), secp256k1::Error> {
+pub(crate) fn construct_keys_callback<'a, T, I, F>(
+       secp_ctx: &Secp256k1<T>, unblinded_path: I, destination: Option<Destination>,
+       session_priv: &SecretKey, mut callback: F
+) -> Result<(), secp256k1::Error>
+where
+       T: secp256k1::Signing + secp256k1::Verification,
+       I: Iterator<Item=&'a PublicKey>,
+       F: FnMut(PublicKey, SharedSecret, PublicKey, [u8; 32], Option<PublicKey>, Option<Vec<u8>>),
+{
        let mut msg_blinding_point_priv = session_priv.clone();
        let mut msg_blinding_point = PublicKey::from_secret_key(secp_ctx, &msg_blinding_point_priv);
        let mut onion_packet_pubkey_priv = msg_blinding_point_priv.clone();
@@ -96,3 +104,26 @@ pub(crate) fn construct_keys_callback<T: secp256k1::Signing + secp256k1::Verific
        }
        Ok(())
 }
+
+/// Encrypt TLV payload to be used as a [`crate::blinded_path::BlindedHop::encrypted_payload`].
+pub(super) fn encrypt_payload<P: Writeable>(payload: P, encrypted_tlvs_ss: [u8; 32]) -> Vec<u8> {
+       let mut writer = VecWriter(Vec::new());
+       let write_adapter = ChaChaPolyWriteAdapter::new(encrypted_tlvs_ss, &payload);
+       write_adapter.write(&mut writer).expect("In-memory writes cannot fail");
+       writer.0
+}
+
+/// Blinded path encrypted payloads may be padded to ensure they are equal length.
+///
+/// Reads padding to the end, ignoring what's read.
+pub(crate) struct Padding {}
+impl Readable for Padding {
+       #[inline]
+       fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
+               loop {
+                       let mut buf = [0; 8192];
+                       if reader.read(&mut buf[..])? == 0 { break; }
+               }
+               Ok(Self {})
+       }
+}