use bitcoin::secp256k1::ecdh::SharedSecret;
use ln::onion_utils;
+use super::blinded_route::BlindedRoute;
+use super::messenger::Destination;
use prelude::*;
// TODO: DRY with onion_utils::construct_onion_keys_callback
#[inline]
pub(super) fn construct_keys_callback<T: secp256k1::Signing + secp256k1::Verification,
- FType: FnMut(PublicKey, SharedSecret, PublicKey, [u8; 32], Option<PublicKey>)>(
- secp_ctx: &Secp256k1<T>, unblinded_path: &[PublicKey],
+ 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> {
let mut msg_blinding_point_priv = session_priv.clone();
let mut onion_packet_pubkey = msg_blinding_point.clone();
macro_rules! build_keys {
- ($pk: expr, $blinded: expr) => {
+ ($pk: expr, $blinded: expr, $encrypted_payload: expr) => {{
let encrypted_data_ss = SharedSecret::new(&$pk, &msg_blinding_point_priv);
let blinded_hop_pk = if $blinded { $pk } else {
let rho = onion_utils::gen_rho_from_shared_secret(encrypted_data_ss.as_ref());
let unblinded_pk_opt = if $blinded { None } else { Some($pk) };
- callback(blinded_hop_pk, onion_packet_ss, onion_packet_pubkey, rho, unblinded_pk_opt);
+ callback(blinded_hop_pk, onion_packet_ss, onion_packet_pubkey, rho, unblinded_pk_opt, $encrypted_payload);
+ (encrypted_data_ss, onion_packet_ss)
+ }}
+ }
+
+ macro_rules! build_keys_in_loop {
+ ($pk: expr, $blinded: expr, $encrypted_payload: expr) => {
+ let (encrypted_data_ss, onion_packet_ss) = build_keys!($pk, $blinded, $encrypted_payload);
let msg_blinding_point_blinding_factor = {
let mut sha = Sha256::engine();
}
for pk in unblinded_path {
- build_keys!(*pk, false);
+ build_keys_in_loop!(*pk, false, None);
+ }
+ if let Some(dest) = destination {
+ match dest {
+ Destination::Node(pk) => {
+ build_keys!(pk, false, None);
+ },
+ Destination::BlindedRoute(BlindedRoute { blinded_hops, .. }) => {
+ for hop in blinded_hops {
+ build_keys_in_loop!(hop.blinded_node_id, true, Some(hop.encrypted_payload));
+ }
+ },
+ }
}
Ok(())
}