From 7d601782fb828f5b4bc08e8883e10d6672147b4e Mon Sep 17 00:00:00 2001 From: Drazen Date: Fri, 21 Feb 2025 14:12:55 +0100 Subject: [PATCH] Disable acks, friendlier SURB construction --- Cargo.lock | 2 ++ common/nymsphinx/anonymous-replies/Cargo.toml | 1 + .../anonymous-replies/src/reply_surb.rs | 30 +++++++++++++++++-- .../anonymous-replies/src/requests.rs | 6 ++++ common/nymsphinx/framing/Cargo.toml | 4 +++ common/nymsphinx/framing/src/processing.rs | 14 ++++++--- 6 files changed, 50 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0bff8583a2..1efd0230e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6778,6 +6778,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "serde", + "sphinx-packet", "thiserror 2.0.11", "wasm-bindgen", ] @@ -6832,6 +6833,7 @@ name = "nym-sphinx-framing" version = "0.1.0" dependencies = [ "bytes", + "cfg-if", "log", "nym-metrics", "nym-sphinx-acknowledgements", diff --git a/common/nymsphinx/anonymous-replies/Cargo.toml b/common/nymsphinx/anonymous-replies/Cargo.toml index ade1cc7f59..161a6a9db2 100644 --- a/common/nymsphinx/anonymous-replies/Cargo.toml +++ b/common/nymsphinx/anonymous-replies/Cargo.toml @@ -12,6 +12,7 @@ rand = { workspace = true } bs58 = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } +sphinx-packet = { workspace = true } nym-crypto = { path = "../../crypto", features = ["stream_cipher", "rand"] } nym-sphinx-addressing = { path = "../addressing" } diff --git a/common/nymsphinx/anonymous-replies/src/reply_surb.rs b/common/nymsphinx/anonymous-replies/src/reply_surb.rs index 3ac7af8571..cd8d962bbc 100644 --- a/common/nymsphinx/anonymous-replies/src/reply_surb.rs +++ b/common/nymsphinx/anonymous-replies/src/reply_surb.rs @@ -7,11 +7,12 @@ use nym_sphinx_addressing::clients::Recipient; use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN}; use nym_sphinx_params::packet_sizes::PacketSize; use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm}; -use nym_sphinx_types::{NymPacket, SURBMaterial, SphinxError, SURB}; +use nym_sphinx_types::{Destination, NymPacket, SURBMaterial, SphinxError, SURB}; use nym_topology::{NymRouteProvider, NymTopologyError}; use rand::{CryptoRng, RngCore}; use serde::de::{Error as SerdeError, Visitor}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use sphinx_packet::route::Node; use std::fmt::{self, Formatter}; use std::time; @@ -83,6 +84,25 @@ impl ReplySurb { packet_size.plaintext_size() - ack_overhead - ReplySurbKeyDigestAlgorithm::output_size() - 1 } + pub fn construct_with_route( + rng: &mut R, + destination: Destination, + average_delay: time::Duration, + route: &[Node], + ) -> Result + where + R: RngCore + CryptoRng, + { + let delays = nym_sphinx_routing::generate_hop_delays(average_delay, route.len()); + let surb_material = SURBMaterial::new(route.to_vec(), delays, destination); + + // this can't fail as we know we have a valid route to gateway and have correct number of delays + Ok(ReplySurb { + surb: surb_material.construct_SURB().unwrap(), + encryption_key: SurbEncryptionKey::new(rng), + }) + } + // TODO: should this return `ReplySURBError` for consistency sake // or keep `NymTopologyError` because it's the only error it can actually return? pub fn construct( @@ -123,11 +143,15 @@ impl ReplySurb { pub fn to_bytes(&self) -> Vec { // KEY || SURB_BYTES - self.encryption_key + let bytes: Vec = self.encryption_key .to_bytes() .into_iter() .chain(self.surb.to_bytes()) - .collect() + .collect(); + + assert_eq!(bytes.len(), ReplySurb::serialized_len()); + + bytes } pub fn from_bytes(bytes: &[u8]) -> Result { diff --git a/common/nymsphinx/anonymous-replies/src/requests.rs b/common/nymsphinx/anonymous-replies/src/requests.rs index 7503f141e2..34e578e0d2 100644 --- a/common/nymsphinx/anonymous-replies/src/requests.rs +++ b/common/nymsphinx/anonymous-replies/src/requests.rs @@ -139,6 +139,11 @@ impl RepliableMessage { sender_tag: AnonymousSenderTag, reply_surbs: Vec, ) -> Self { + + println!("New data message message: {} bytes", data.len()); + println!("New data message surbs: {} bytes", reply_surbs.len() * ReplySurb::serialized_len()); + println!("New data message surbs: {} bytes", reply_surbs.iter().flat_map(|s| s.to_bytes()).collect::>().len()); + RepliableMessage { sender_tag, content: RepliableMessageContent::Data { @@ -170,6 +175,7 @@ impl RepliableMessage { } pub fn try_from_bytes(bytes: &[u8]) -> Result { + println!("Trying to deserialize message: {} bytes", bytes.len()); if bytes.len() < SENDER_TAG_SIZE + 1 { return Err(InvalidReplyRequestError::RequestTooShortToDeserialize); } diff --git a/common/nymsphinx/framing/Cargo.toml b/common/nymsphinx/framing/Cargo.toml index 03cff4ca9d..aaaa1ef7fa 100644 --- a/common/nymsphinx/framing/Cargo.toml +++ b/common/nymsphinx/framing/Cargo.toml @@ -9,6 +9,7 @@ repository = { workspace = true } [dependencies] bytes = { workspace = true } +cfg-if = { workspace = true } tokio-util = { workspace = true, features = ["codec"] } thiserror = { workspace = true } log = { workspace = true } @@ -20,5 +21,8 @@ nym-metrics = { path = "../../nym-metrics" } nym-sphinx-addressing = { path = "../addressing" } nym-sphinx-acknowledgements = { path = "../acknowledgements" } +[features] +no-acks = [] + [dev-dependencies] tokio = { workspace = true, features = ["full"] } diff --git a/common/nymsphinx/framing/src/processing.rs b/common/nymsphinx/framing/src/processing.rs index d00d4d797c..2905a07763 100644 --- a/common/nymsphinx/framing/src/processing.rs +++ b/common/nymsphinx/framing/src/processing.rs @@ -230,8 +230,12 @@ fn split_into_ack_and_message( | PacketSize::ExtendedPacket32 | PacketSize::OutfoxRegularPacket => { trace!("received a normal packet!"); - let (ack_data, message) = split_hop_data_into_ack_and_message(data, packet_type)?; - let (ack_first_hop, ack_packet) = + cfg_if::cfg_if! { + if #[cfg(feature = "no-acks")] { + return Ok((None, data)); + } else { + let (ack_data, message) = split_hop_data_into_ack_and_message(data, packet_type)?; + let (ack_first_hop, ack_packet) = match SurbAck::try_recover_first_hop_packet(&ack_data, packet_type) { Ok((first_hop, packet)) => (first_hop, packet), Err(err) => { @@ -239,8 +243,10 @@ fn split_into_ack_and_message( return Err(err.into()); } }; - let forward_ack = MixPacket::new(ack_first_hop, ack_packet, packet_type); - Ok((Some(forward_ack), message)) + let forward_ack = MixPacket::new(ack_first_hop, ack_packet, packet_type); + Ok((Some(forward_ack), message)) + } + } } } }