X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fonion_message%2Fblinded_route.rs;h=82a325a9e046bbd714d2b1fc6a53b89c1808d014;hb=f0775f837987dee29d85b3c717fb0b9edd1bda02;hp=e47c77de35459ba0b1082117c06d7e291d052d5d;hpb=d2a9ae0b8eb5bdb1724be0b8d398d0fdf9870266;p=rust-lightning diff --git a/lightning/src/onion_message/blinded_route.rs b/lightning/src/onion_message/blinded_route.rs index e47c77de..82a325a9 100644 --- a/lightning/src/onion_message/blinded_route.rs +++ b/lightning/src/onion_message/blinded_route.rs @@ -9,16 +9,22 @@ //! Creating blinded routes and related utilities live here. -use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey}; +use bitcoin::hashes::{Hash, HashEngine}; +use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey}; -use chain::keysinterface::KeysInterface; +use crate::chain::keysinterface::{KeysInterface, Recipient}; +use super::packet::ControlTlvs; use super::utils; -use ln::msgs::DecodeError; -use util::chacha20poly1305rfc::ChaChaPolyWriteAdapter; -use util::ser::{Readable, VecWriter, Writeable, Writer}; +use crate::ln::msgs::DecodeError; +use crate::ln::onion_utils; +use crate::util::chacha20poly1305rfc::{ChaChaPolyReadAdapter, ChaChaPolyWriteAdapter}; +use crate::util::ser::{FixedLengthReader, LengthReadableArgs, Readable, VecWriter, Writeable, Writer}; -use io; -use prelude::*; +use core::mem; +use core::ops::Deref; +use crate::io::{self, Cursor}; +use crate::prelude::*; /// Onion messages can be sent and received to blinded routes, which serve to hide the identity of /// the recipient. @@ -69,6 +75,41 @@ impl BlindedRoute { blinded_hops: blinded_hops(secp_ctx, node_pks, &blinding_secret).map_err(|_| ())?, }) } + + // Advance the blinded route by one hop, so make the second hop into the new introduction node. + pub(super) fn advance_by_one + (&mut self, keys_manager: &K, secp_ctx: &Secp256k1) -> Result<(), ()> + where K::Target: KeysInterface + { + let control_tlvs_ss = keys_manager.ecdh(Recipient::Node, &self.blinding_point, None)?; + let rho = onion_utils::gen_rho_from_shared_secret(&control_tlvs_ss.secret_bytes()); + let encrypted_control_tlvs = self.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 => { + let blinding_factor = { + let mut sha = Sha256::engine(); + sha.input(&self.blinding_point.serialize()[..]); + sha.input(control_tlvs_ss.as_ref()); + Sha256::from_engine(sha).into_inner() + }; + self.blinding_point.mul_tweak(secp_ctx, &Scalar::from_be_bytes(blinding_factor).unwrap()) + .map_err(|_| ())? + } + }; + mem::swap(&mut self.blinding_point, &mut new_blinding_point); + mem::swap(&mut self.introduction_node_id, &mut next_node_id); + Ok(()) + }, + _ => Err(()) + } + } } /// Construct blinded hops for the given `unblinded_path`.