More work on the reciever end, and outfox format

This commit is contained in:
durch
2023-05-04 16:08:46 +02:00
parent 4d837a0402
commit 19c4b3255c
37 changed files with 1234 additions and 1622 deletions
@@ -69,7 +69,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --release --all --features cpucycles
args: --workspace --release --all
- name: Install Rust stable
uses: actions-rs/toolchain@v1
Generated
+1
View File
@@ -4059,6 +4059,7 @@ dependencies = [
"curve25519-dalek",
"fastrand",
"getrandom 0.2.9",
"log",
"rand 0.7.3",
"rayon",
"sphinx-packet",
+2 -2
View File
@@ -53,7 +53,7 @@ where
}
async fn on_messages(&mut self, mut mix_packets: Vec<MixPacket>) {
debug_assert!(!mix_packets.is_empty());
assert!(!mix_packets.is_empty());
let result = if mix_packets.len() == 1 {
let mix_packet = mix_packets.pop().unwrap();
@@ -103,7 +103,7 @@ where
}
}
shutdown.recv_timeout().await;
log::debug!("MixTrafficController: Exiting");
log::error!("MixTrafficController: Exiting");
})
}
}
@@ -71,7 +71,8 @@ impl AcknowledgementListener {
while !shutdown.is_shutdown() {
tokio::select! {
acks = self.ack_receiver.next() => match acks {
Some(acks) => self.handle_ack_receiver_item(acks).await,
Some(acks) => {self.handle_ack_receiver_item(acks).await}
None => {
log::trace!("AcknowledgementListener: Stopping since channel closed");
break;
@@ -49,11 +49,11 @@ where
packet_recipient: Recipient,
chunk_data: Fragment,
) -> Result<PreparedFragment, PreparationError> {
info!("retransmitting normal packet...");
debug!("retransmitting normal packet...");
// TODO: Figure out retransmission packet type signaling
self.message_handler
.try_prepare_single_chunk_for_sending(packet_recipient, chunk_data, PacketType::Mix)
.try_prepare_single_chunk_for_sending(packet_recipient, chunk_data, PacketType::Outfox)
.await
}
@@ -431,7 +431,7 @@ where
lane: TransmissionLane,
packet_type: PacketType,
) -> Result<(), PreparationError> {
info!("Sending non-reply message with packet type {packet_type}");
debug!("Sending non-reply message with packet type {packet_type}");
// TODO: I really dislike existence of this assertion, it implies code has to be re-organised
debug_assert!(!matches!(message, NymMessage::Reply(_)));
@@ -439,7 +439,11 @@ where
let topology_permit = self.topology_access.get_read_permit().await;
let topology = self.get_topology(&topology_permit)?;
let packet_size = self.optimal_packet_size(&message);
let packet_size = if packet_type == PacketType::Outfox {
PacketSize::OutfoxRegularPacket
} else {
self.optimal_packet_size(&message)
};
debug!("Using {packet_size} packets for {message}");
let fragments = self
.message_preparer
@@ -482,7 +486,7 @@ where
amount: u32,
packet_type: PacketType,
) -> Result<(), PreparationError> {
info!("Sending additional reply SURBs with packet type {packet_type}");
debug!("Sending additional reply SURBs with packet type {packet_type}");
let sender_tag = self.get_or_create_sender_tag(&recipient);
let (reply_surbs, reply_keys) =
self.generate_reply_surbs_with_keys(amount as usize).await?;
@@ -514,7 +518,7 @@ where
lane: TransmissionLane,
packet_type: PacketType,
) -> Result<(), SurbWrappedPreparationError> {
info!("Sending message with reply SURBs with packet type {packet_type}");
debug!("Sending message with reply SURBs with packet type {packet_type}");
let sender_tag = self.get_or_create_sender_tag(&recipient);
let (reply_surbs, reply_keys) = self
.generate_reply_surbs_with_keys(num_reply_surbs as usize)
@@ -538,7 +542,7 @@ where
chunk: Fragment,
packet_type: PacketType,
) -> Result<PreparedFragment, PreparationError> {
info!("Sending single chunk with packet type {packet_type}");
debug!("Sending single chunk with packet type {packet_type}");
let topology_permit = self.topology_access.get_read_permit().await;
let topology = self.get_topology(&topology_permit)?;
@@ -353,7 +353,7 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
};
if let Some(completed) = completed_message {
info!("received {completed}");
debug!("received {completed}");
completed_messages.push(completed)
}
}
@@ -579,6 +579,8 @@ impl<C, St> GatewayClient<C, St> {
&mut self,
packets: Vec<MixPacket>,
) -> Result<(), GatewayClientError> {
warn!("Sending {} mix packets", packets.len());
if !self.authenticated {
return Err(GatewayClientError::NotAuthenticated);
}
@@ -623,9 +625,10 @@ impl<C, St> GatewayClient<C, St> {
) -> Result<(), GatewayClientError> {
if let Err(err) = self.send_websocket_message_without_response(msg).await {
if err.is_closed_connection() && self.should_reconnect_on_failure {
info!("Going to attempt a reconnection");
error!("Going to attempt a reconnection");
self.attempt_reconnection().await
} else {
error!("{err}");
Err(err)
}
} else {
@@ -50,10 +50,15 @@ impl PacketRouter {
let ack_overhead = PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN;
for received_packet in unwrapped_packets {
if received_packet.len() == PacketSize::AckPacket.plaintext_size() {
if received_packet.len() == PacketSize::AckPacket.plaintext_size()
|| received_packet.len() == PacketSize::OutfoxAckPacket.plaintext_size()
{
received_acks.push(received_packet);
} else if received_packet.len()
== PacketSize::RegularPacket.plaintext_size() - ack_overhead
|| received_packet.len()
== PacketSize::OutfoxRegularPacket.plaintext_size() - ack_overhead
|| received_packet.len() == PacketSize::OutfoxRegularPacket.size() - 6
{
trace!("routing regular packet");
received_messages.push(received_packet);
@@ -10,7 +10,7 @@ use nym_sphinx_forwarding::packet::MixPacket;
use nym_sphinx_framing::packet::FramedNymPacket;
use nym_sphinx_params::{PacketSize, PacketType};
use nym_sphinx_types::{
Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, NymPacket, Payload,
Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, NymPacket, NymProcessedPacket,
PrivateKey, ProcessedPacket,
};
use std::convert::TryFrom;
@@ -56,10 +56,10 @@ impl SphinxPacketProcessor {
fn perform_initial_packet_processing(
&self,
packet: NymPacket,
) -> Result<ProcessedPacket, MixProcessingError> {
) -> Result<NymProcessedPacket, MixProcessingError> {
measure!({
packet.process(&self.sphinx_key).map_err(|err| {
debug!("Failed to unwrap Sphinx packet: {err}");
info!("Failed to unwrap NymPacket packet: {err}");
MixProcessingError::NymPacketProcessingError(err)
})
})
@@ -73,7 +73,7 @@ impl SphinxPacketProcessor {
fn perform_initial_unwrapping(
&self,
received: FramedNymPacket,
) -> Result<ProcessedPacket, MixProcessingError> {
) -> Result<NymProcessedPacket, MixProcessingError> {
measure!({
let packet = received.into_inner();
@@ -101,14 +101,17 @@ impl SphinxPacketProcessor {
fn split_hop_data_into_ack_and_message(
&self,
mut extracted_data: Vec<u8>,
packet_type: PacketType,
) -> Result<(Vec<u8>, Vec<u8>), MixProcessingError> {
let ack_len = SurbAck::len(Some(packet_type));
// in theory it's impossible for this to fail since it managed to go into correct `match`
// branch at the caller
if extracted_data.len() < SurbAck::len() {
if extracted_data.len() < ack_len {
return Err(MixProcessingError::NoSurbAckInFinalHop);
}
let message = extracted_data.split_off(SurbAck::len());
let message = extracted_data.split_off(ack_len);
let ack_data = extracted_data;
Ok((ack_data, message))
}
@@ -130,13 +133,18 @@ impl SphinxPacketProcessor {
| PacketSize::ExtendedPacket8
| PacketSize::ExtendedPacket16
| PacketSize::ExtendedPacket32
| PacketSize::OutfoxRegularPacket
| PacketSize::OutfoxExtendedPacket8
| PacketSize::OutfoxExtendedPacket16
| PacketSize::OutfoxExtendedPacket32 => {
| PacketSize::OutfoxRegularPacket => {
trace!("received a normal packet!");
let (ack_data, message) = self.split_hop_data_into_ack_and_message(data)?;
let (ack_first_hop, ack_packet) = SurbAck::try_recover_first_hop_packet(&ack_data)?;
let (ack_data, message) =
self.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) => {
error!("Failed to recover first hop from ack data: {err}");
return Err(err.into());
}
};
let forward_ack = MixPacket::new(ack_first_hop, ack_packet, packet_type);
Ok((Some(forward_ack), message))
}
@@ -149,14 +157,12 @@ impl SphinxPacketProcessor {
fn process_final_hop(
&self,
destination: DestinationAddressBytes,
payload: Payload,
payload: Vec<u8>,
packet_size: PacketSize,
packet_type: PacketType,
) -> Result<MixProcessingResult, MixProcessingError> {
let packet_message = payload.recover_plaintext()?;
let (forward_ack, message) =
self.split_into_ack_and_message(packet_message, packet_size, packet_type)?;
self.split_into_ack_and_message(payload, packet_size, packet_type)?;
Ok(MixProcessingResult::FinalHop(ProcessedFinalHop {
destination,
@@ -169,18 +175,48 @@ impl SphinxPacketProcessor {
/// or a final hop.
fn perform_final_processing(
&self,
packet: ProcessedPacket,
packet: NymProcessedPacket,
packet_size: PacketSize,
packet_type: PacketType,
) -> Result<MixProcessingResult, MixProcessingError> {
match packet {
ProcessedPacket::ForwardHop(packet, address, delay) => {
self.process_forward_hop(NymPacket::Sphinx(*packet), address, delay, packet_type)
NymProcessedPacket::Sphinx(packet) => {
match packet {
ProcessedPacket::ForwardHop(packet, address, delay) => self
.process_forward_hop(
NymPacket::Sphinx(*packet),
address,
delay,
packet_type,
),
// right now there's no use for the surb_id included in the header - probably it should get removed from the
// sphinx all together?
ProcessedPacket::FinalHop(destination, _, payload) => self.process_final_hop(
destination,
payload.recover_plaintext()?,
packet_size,
packet_type,
),
}
}
// right now there's no use for the surb_id included in the header - probably it should get removed from the
// sphinx all together?
ProcessedPacket::FinalHop(destination, _, payload) => {
self.process_final_hop(destination, payload, packet_size, packet_type)
NymProcessedPacket::Outfox(packet) => {
let next_address = *packet.next_address();
let packet = packet.into_packet();
if packet.is_final_hop() {
self.process_final_hop(
DestinationAddressBytes::from_bytes(next_address),
packet.recover_plaintext().to_vec(),
packet_size,
packet_type,
)
} else {
let mix_packet = MixPacket::new(
NymNodeRoutingAddress::try_from_bytes(&next_address)?,
NymPacket::Outfox(packet),
PacketType::Outfox,
);
Ok(MixProcessingResult::ForwardHop(mix_packet, None))
}
}
}
}
@@ -225,31 +261,71 @@ mod tests {
let short_data = vec![42u8];
assert!(processor
.split_hop_data_into_ack_and_message(short_data)
.split_hop_data_into_ack_and_message(short_data, PacketType::Mix)
.is_err());
let sufficient_data = vec![42u8; SurbAck::len()];
let sufficient_data = vec![42u8; SurbAck::len(Some(PacketType::Mix))];
let (ack, data) = processor
.split_hop_data_into_ack_and_message(sufficient_data.clone())
.split_hop_data_into_ack_and_message(sufficient_data.clone(), PacketType::Mix)
.unwrap();
assert_eq!(sufficient_data, ack);
assert!(data.is_empty());
let long_data = vec![42u8; SurbAck::len() * 5];
let long_data = vec![42u8; SurbAck::len(Some(PacketType::Mix)) * 5];
let (ack, data) = processor
.split_hop_data_into_ack_and_message(long_data)
.split_hop_data_into_ack_and_message(long_data, PacketType::Mix)
.unwrap();
assert_eq!(ack.len(), SurbAck::len());
assert_eq!(data.len(), SurbAck::len() * 4)
assert_eq!(ack.len(), SurbAck::len(Some(PacketType::Mix)));
assert_eq!(data.len(), SurbAck::len(Some(PacketType::Mix)) * 4)
}
#[tokio::test]
async fn splitting_hop_data_works_for_sufficiently_long_payload_outfox() {
let processor = fixture();
let short_data = vec![42u8];
assert!(processor
.split_hop_data_into_ack_and_message(short_data, PacketType::Outfox)
.is_err());
let sufficient_data = vec![42u8; SurbAck::len(Some(PacketType::Outfox))];
let (ack, data) = processor
.split_hop_data_into_ack_and_message(sufficient_data.clone(), PacketType::Outfox)
.unwrap();
assert_eq!(sufficient_data, ack);
assert!(data.is_empty());
let long_data = vec![42u8; SurbAck::len(Some(PacketType::Outfox)) * 5];
let (ack, data) = processor
.split_hop_data_into_ack_and_message(long_data, PacketType::Outfox)
.unwrap();
assert_eq!(ack.len(), SurbAck::len(Some(PacketType::Outfox)));
assert_eq!(data.len(), SurbAck::len(Some(PacketType::Outfox)) * 4)
}
#[tokio::test]
async fn splitting_into_ack_and_message_returns_whole_data_for_ack() {
let processor = fixture();
let data = vec![42u8; SurbAck::len() + 10];
let data = vec![42u8; SurbAck::len(Some(PacketType::Mix)) + 10];
let (ack, message) = processor
.split_into_ack_and_message(data.clone(), PacketSize::AckPacket, Default::default())
.split_into_ack_and_message(data.clone(), PacketSize::AckPacket, PacketType::Mix)
.unwrap();
assert!(ack.is_none());
assert_eq!(data, message)
}
#[tokio::test]
async fn splitting_into_ack_and_message_returns_whole_data_for_ack_outfox() {
let processor = fixture();
let data = vec![42u8; SurbAck::len(Some(PacketType::Outfox)) + 10];
let (ack, message) = processor
.split_into_ack_and_message(
data.clone(),
PacketSize::OutfoxAckPacket,
PacketType::Outfox,
)
.unwrap();
assert!(ack.is_none());
assert_eq!(data, message)
@@ -3,9 +3,7 @@
use crate::AckKey;
use nym_crypto::symmetric::stream_cipher::{self, encrypt, iv_from_slice, random_iv, IvSizeUser};
use nym_sphinx_params::{
packet_sizes::PacketSize, AckEncryptionAlgorithm, SerializedFragmentIdentifier, FRAG_ID_LEN,
};
use nym_sphinx_params::{AckEncryptionAlgorithm, SerializedFragmentIdentifier, FRAG_ID_LEN};
use rand::{CryptoRng, RngCore};
// TODO: should those functions even exist in this file?
@@ -28,9 +26,9 @@ pub fn recover_identifier(
) -> Option<SerializedFragmentIdentifier> {
// The content of an 'ACK' packet consists of AckEncryptionAlgorithm::IV followed by
// serialized FragmentIdentifier
if iv_id_ciphertext.len() != PacketSize::AckPacket.plaintext_size() {
return None;
}
// if iv_id_ciphertext.len() != PacketSize::AckPacket.plaintext_size() {
// return None;
// }
let iv_size = AckEncryptionAlgorithm::iv_size();
let iv = iv_from_slice::<AckEncryptionAlgorithm>(&iv_id_ciphertext[..iv_size]);
@@ -17,6 +17,7 @@ use std::convert::TryFrom;
use std::time;
use thiserror::Error;
#[derive(Debug)]
pub struct SurbAck {
surb_ack_packet: NymPacket,
first_hop_address: NymNodeRoutingAddress,
@@ -55,15 +56,24 @@ impl SurbAck {
let surb_ack_payload = prepare_identifier(rng, ack_key, marshaled_fragment_id);
let packet_size = match packet_type {
PacketType::Outfox => PacketSize::OutfoxAckPacket.payload_size(),
PacketType::Outfox => {
if surb_ack_payload.len() >= 48 {
surb_ack_payload.len()
} else {
48
}
}
PacketType::Mix => PacketSize::AckPacket.payload_size(),
PacketType::Vpn => PacketSize::AckPacket.payload_size(),
};
let surb_ack_packet = match packet_type {
PacketType::Outfox => {
NymPacket::outfox_build(surb_ack_payload, route.as_slice(), Some(packet_size))?
}
PacketType::Outfox => NymPacket::outfox_build(
surb_ack_payload,
route.as_slice(),
&destination,
Some(packet_size),
)?,
PacketType::Mix => NymPacket::sphinx_build(
packet_size,
surb_ack_payload,
@@ -92,10 +102,17 @@ impl SurbAck {
})
}
pub fn len() -> usize {
pub fn len(packet_type: Option<PacketType>) -> usize {
// TODO: this will be variable once/if we decide to introduce optimization described
// in common/nymsphinx/chunking/src/lib.rs:available_plaintext_size()
PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN
let packet_type = packet_type.unwrap_or(PacketType::Mix);
match packet_type {
PacketType::Outfox => {
PacketSize::OutfoxAckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN
}
PacketType::Mix => PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN,
PacketType::Vpn => PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN,
}
}
pub fn expected_total_delay(&self) -> Delay {
@@ -116,21 +133,19 @@ impl SurbAck {
// partial reciprocal of `prepare_for_sending` performed by the gateway
pub fn try_recover_first_hop_packet(
b: &[u8],
packet_type: PacketType,
) -> Result<(NymNodeRoutingAddress, NymPacket), SurbAckRecoveryError> {
if b.len() != Self::len() {
Err(SurbAckRecoveryError::InvalidPacketSize {
received: b.len(),
expected: Self::len(),
})
} else {
let address = NymNodeRoutingAddress::try_from_bytes(b)?;
let address = NymNodeRoutingAddress::try_from_bytes(b)?;
// TODO: this will be variable once/if we decide to introduce optimization described
// in common/nymsphinx/chunking/src/lib.rs:available_plaintext_size()
let address_offset = MAX_NODE_ADDRESS_UNPADDED_LEN;
let packet = NymPacket::sphinx_from_bytes(&b[address_offset..])?;
// TODO: this will be variable once/if we decide to introduce optimization described
// in common/nymsphinx/chunking/src/lib.rs:available_plaintext_size()
let address_offset = MAX_NODE_ADDRESS_UNPADDED_LEN;
let packet = match packet_type {
PacketType::Outfox => NymPacket::outfox_from_bytes(&b[address_offset..])?,
PacketType::Mix => NymPacket::sphinx_from_bytes(&b[address_offset..])?,
PacketType::Vpn => NymPacket::sphinx_from_bytes(&b[address_offset..])?,
};
Ok((address, packet))
}
Ok((address, packet))
}
}
+24 -17
View File
@@ -42,7 +42,8 @@ impl Encoder<FramedNymPacket> for NymCodec {
fn encode(&mut self, item: FramedNymPacket, dst: &mut BytesMut) -> Result<(), Self::Error> {
item.header.encode(dst);
let packet_bytes = item.packet.to_bytes()?;
dst.put(packet_bytes.as_slice());
let encoded = packet_bytes.as_slice();
dst.put(encoded);
Ok(())
}
}
@@ -103,22 +104,23 @@ impl Decoder for NymCodec {
// reserve for that.
// we also assume the next packet coming from the same client will use exactly the same versioning
// as the current packet
let mut allocate_for_next_packet = header.size() + PacketSize::AckPacket.size();
if !src.is_empty() {
match Header::decode(src) {
Ok(Some(next_header)) => {
allocate_for_next_packet = next_header.size() + next_header.packet_size.size();
}
Ok(None) => {
// we don't have enough information to know how much to reserve, fallback to the ack case
}
// the next frame will be malformed but let's leave handling the error to the next
// call to 'decode', as presumably, the current sphinx packet is still valid
Err(_) => return Ok(Some(nymsphinx_packet)),
};
}
src.reserve(allocate_for_next_packet);
// let mut allocate_for_next_packet = header.size() + PacketSize::AckPacket.size();
// if !src.is_empty() {
// match Header::decode(src) {
// Ok(Some(next_header)) => {
// allocate_for_next_packet = next_header.size() + next_header.packet_size.size();
// }
// Ok(None) => {
// // we don't have enough information to know how much to reserve, fallback to the ack case
// }
// // the next frame will be malformed but let's leave handling the error to the next
// // call to 'decode', as presumably, the current sphinx packet is still valid
// Err(_) => return Ok(Some(nymsphinx_packet)),
// };
// }
// src.reserve(allocate_for_next_packet);
Ok(Some(nymsphinx_packet))
}
}
@@ -154,11 +156,16 @@ mod packet_encoding {
node4_pk,
);
let destination = Destination::new(
DestinationAddressBytes::from_bytes([3u8; DESTINATION_ADDRESS_LENGTH]),
[4u8; IDENTIFIER_LENGTH],
);
let route = &[node1, node2, node3, node4];
let payload = vec![1; 48];
NymPacket::outfox_build(payload, route, Some(size.plaintext_size())).unwrap()
NymPacket::outfox_build(payload, route, &destination, Some(size.plaintext_size())).unwrap()
}
fn make_valid_sphinx_packet(size: PacketSize) -> NymPacket {
+16 -11
View File
@@ -24,14 +24,19 @@ impl FramedNymPacket {
// already managed to somehow create a sphinx packet
let packet_size = PacketSize::get_type(packet.len()).unwrap();
FramedNymPacket {
header: Header {
packet_version: PacketVersion::new(use_legacy_version),
packet_size,
packet_type,
},
packet,
}
let use_legacy = if packet_type == PacketType::Outfox {
false
} else {
use_legacy_version
};
let header = Header {
packet_version: PacketVersion::new(use_legacy),
packet_size,
packet_type,
};
FramedNymPacket { header, packet }
}
pub fn header(&self) -> Header {
@@ -96,16 +101,16 @@ impl Header {
pub(crate) fn encode(&self, dst: &mut BytesMut) {
// we reserve one byte for `packet_size` and the other for `mode`
dst.reserve(Self::LEGACY_SIZE);
// dst.reserve(Self::LEGACY_SIZE);
if let Some(version) = self.packet_version.as_u8() {
dst.reserve(Self::VERSIONED_SIZE);
// dst.reserve(Self::VERSIONED_SIZE);
dst.put_u8(version)
}
dst.put_u8(self.packet_size as u8);
dst.put_u8(self.packet_type as u8);
// reserve bytes for the actual packet
dst.reserve(self.packet_size.size());
// dst.reserve(self.packet_size.size());
}
pub(crate) fn decode(src: &mut BytesMut) -> Result<Option<Self>, NymCodecError> {
+10 -55
View File
@@ -28,11 +28,9 @@ const EXTENDED_PACKET_SIZE_8: usize = 8 * 1024 + SPHINX_PACKET_OVERHEAD;
const EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + SPHINX_PACKET_OVERHEAD;
const EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + SPHINX_PACKET_OVERHEAD;
const OUTFOX_ACK_PACKET_SIZE: usize = ACK_IV_SIZE + FRAG_ID_LEN + OUTFOX_PACKET_OVERHEAD;
// 48 is min outfox payload size
const OUTFOX_ACK_PACKET_SIZE: usize = 48 + OUTFOX_PACKET_OVERHEAD;
const OUTFOX_REGULAR_PACKET_SIZE: usize = 2 * 1024 + OUTFOX_PACKET_OVERHEAD;
const OUTFOX_EXTENDED_PACKET_SIZE_8: usize = 8 * 1024 + OUTFOX_PACKET_OVERHEAD;
const OUTFOX_EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + OUTFOX_PACKET_OVERHEAD;
const OUTFOX_EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + OUTFOX_PACKET_OVERHEAD;
#[derive(Debug, Error)]
pub enum InvalidPacketSize {
@@ -76,18 +74,6 @@ pub enum PacketSize {
// for sending SURB-ACKs
#[serde(rename = "outfox_ack")]
OutfoxAckPacket = 7,
// for example for streaming fast and furious in uncompressed 10bit 4K HDR quality
#[serde(rename = "outfox_extended32")]
OutfoxExtendedPacket32 = 8,
// for example for streaming fast and furious in heavily compressed lossy RealPlayer quality
#[serde(rename = "outfox_extended8")]
OutfoxExtendedPacket8 = 9,
// for example for streaming fast and furious in compressed XviD quality
#[serde(rename = "outfox_extended16")]
OutfoxExtendedPacket16 = 10,
}
impl PartialOrd for PacketSize {
@@ -116,9 +102,6 @@ impl FromStr for PacketSize {
"extended32" => Ok(Self::ExtendedPacket32),
"outfox_regular" => Ok(Self::OutfoxRegularPacket),
"outfox_ack" => Ok(Self::OutfoxAckPacket),
"outfox_extended8" => Ok(Self::OutfoxExtendedPacket8),
"outfox_extended16" => Ok(Self::OutfoxExtendedPacket16),
"outfox_extended32" => Ok(Self::OutfoxExtendedPacket32),
s => Err(InvalidPacketSize::UnknownExtendedPacketVariant {
received: s.to_string(),
}),
@@ -136,9 +119,6 @@ impl Display for PacketSize {
PacketSize::ExtendedPacket16 => write!(f, "extended16"),
PacketSize::OutfoxRegularPacket => write!(f, "outfox_regular"),
PacketSize::OutfoxAckPacket => write!(f, "outfox_ack"),
PacketSize::OutfoxExtendedPacket32 => write!(f, "outfox_extended32"),
PacketSize::OutfoxExtendedPacket8 => write!(f, "outfox_extended8"),
PacketSize::OutfoxExtendedPacket16 => write!(f, "outfox_extended16"),
}
}
}
@@ -165,15 +145,6 @@ impl TryFrom<u8> for PacketSize {
_ if value == (PacketSize::ExtendedPacket32 as u8) => Ok(Self::ExtendedPacket32),
_ if value == (PacketSize::OutfoxRegularPacket as u8) => Ok(Self::OutfoxRegularPacket),
_ if value == (PacketSize::OutfoxAckPacket as u8) => Ok(Self::OutfoxAckPacket),
_ if value == (PacketSize::OutfoxExtendedPacket8 as u8) => {
Ok(Self::OutfoxExtendedPacket8)
}
_ if value == (PacketSize::OutfoxExtendedPacket16 as u8) => {
Ok(Self::OutfoxExtendedPacket16)
}
_ if value == (PacketSize::OutfoxExtendedPacket32 as u8) => {
Ok(Self::OutfoxExtendedPacket32)
}
v => Err(InvalidPacketSize::UnknownPacketTag { received: v }),
}
}
@@ -189,9 +160,6 @@ impl PacketSize {
PacketSize::ExtendedPacket32 => EXTENDED_PACKET_SIZE_32,
PacketSize::OutfoxRegularPacket => OUTFOX_REGULAR_PACKET_SIZE,
PacketSize::OutfoxAckPacket => OUTFOX_ACK_PACKET_SIZE,
PacketSize::OutfoxExtendedPacket8 => OUTFOX_EXTENDED_PACKET_SIZE_8,
PacketSize::OutfoxExtendedPacket16 => OUTFOX_EXTENDED_PACKET_SIZE_16,
PacketSize::OutfoxExtendedPacket32 => OUTFOX_EXTENDED_PACKET_SIZE_32,
}
}
@@ -202,11 +170,7 @@ impl PacketSize {
| PacketSize::ExtendedPacket8
| PacketSize::ExtendedPacket16
| PacketSize::ExtendedPacket32 => HEADER_SIZE,
PacketSize::OutfoxRegularPacket
| PacketSize::OutfoxAckPacket
| PacketSize::OutfoxExtendedPacket8
| PacketSize::OutfoxExtendedPacket16
| PacketSize::OutfoxExtendedPacket32 => MIX_PARAMS_LEN,
PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => MIX_PARAMS_LEN,
}
}
@@ -217,11 +181,9 @@ impl PacketSize {
| PacketSize::ExtendedPacket8
| PacketSize::ExtendedPacket16
| PacketSize::ExtendedPacket32 => PAYLOAD_OVERHEAD_SIZE,
PacketSize::OutfoxRegularPacket
| PacketSize::OutfoxAckPacket
| PacketSize::OutfoxExtendedPacket8
| PacketSize::OutfoxExtendedPacket16
| PacketSize::OutfoxExtendedPacket32 => OUTFOX_PACKET_OVERHEAD - MIX_PARAMS_LEN,
PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => {
OUTFOX_PACKET_OVERHEAD - MIX_PARAMS_LEN // Mix params are calculated into the total overhead so we take them out here
}
}
}
@@ -244,16 +206,12 @@ impl PacketSize {
Ok(PacketSize::ExtendedPacket16)
} else if PacketSize::ExtendedPacket32.size() == size {
Ok(PacketSize::ExtendedPacket32)
} else if PacketSize::OutfoxRegularPacket.size() == size {
} else if PacketSize::OutfoxRegularPacket.size() == size
|| PacketSize::OutfoxRegularPacket.size() == size + 6
{
Ok(PacketSize::OutfoxRegularPacket)
} else if PacketSize::OutfoxAckPacket.size() == size {
Ok(PacketSize::OutfoxAckPacket)
} else if PacketSize::OutfoxExtendedPacket8.size() == size {
Ok(PacketSize::OutfoxExtendedPacket8)
} else if PacketSize::OutfoxExtendedPacket16.size() == size {
Ok(PacketSize::OutfoxExtendedPacket16)
} else if PacketSize::OutfoxExtendedPacket32.size() == size {
Ok(PacketSize::OutfoxExtendedPacket32)
} else {
Err(InvalidPacketSize::UnknownPacketSize { received: size })
}
@@ -267,10 +225,7 @@ impl PacketSize {
| PacketSize::OutfoxRegularPacket => false,
PacketSize::ExtendedPacket8
| PacketSize::ExtendedPacket16
| PacketSize::ExtendedPacket32
| PacketSize::OutfoxExtendedPacket8
| PacketSize::OutfoxExtendedPacket16
| PacketSize::OutfoxExtendedPacket32 => true,
| PacketSize::ExtendedPacket32 => true,
}
}
@@ -6,6 +6,8 @@ use std::convert::TryFrom;
use std::fmt;
use thiserror::Error;
use crate::PacketSize;
#[derive(Error, Debug)]
#[error("{received} is not a valid packet mode tag")]
pub struct InvalidPacketType {
@@ -58,3 +60,17 @@ impl TryFrom<u8> for PacketType {
}
}
}
impl From<PacketSize> for PacketType {
fn from(s: PacketSize) -> Self {
match s {
PacketSize::RegularPacket => PacketType::Mix,
PacketSize::AckPacket => PacketType::Mix,
PacketSize::ExtendedPacket32 => PacketType::Mix,
PacketSize::ExtendedPacket8 => PacketType::Mix,
PacketSize::ExtendedPacket16 => PacketType::Mix,
PacketSize::OutfoxRegularPacket => PacketType::Outfox,
PacketSize::OutfoxAckPacket => PacketType::Outfox,
}
}
}
+11 -2
View File
@@ -11,12 +11,14 @@ use nym_sphinx_anonymous_replies::requests::{
ReplyMessageContent,
};
use nym_sphinx_chunking::fragment::Fragment;
use nym_sphinx_params::{PacketSize, ReplySurbKeyDigestAlgorithm};
use nym_sphinx_params::{PacketSize, PacketType, ReplySurbKeyDigestAlgorithm};
use rand::Rng;
use std::fmt::{Display, Formatter};
use thiserror::Error;
pub(crate) const ACK_OVERHEAD: usize = MAX_NODE_ADDRESS_UNPADDED_LEN + PacketSize::AckPacket.size();
pub(crate) const OUTFOX_ACK_OVERHEAD: usize =
MAX_NODE_ADDRESS_UNPADDED_LEN + PacketSize::AckPacket.size();
#[derive(Debug, Error)]
pub enum NymMessageError {
@@ -187,8 +189,15 @@ impl NymMessage {
NymMessage::Reply(_) => ReplySurbKeyDigestAlgorithm::output_size(),
};
let packet_type = PacketType::from(packet_size);
// each packet will contain an ack + variant specific data (as described above)
packet_size.plaintext_size() - ACK_OVERHEAD - variant_overhead
match packet_type {
PacketType::Outfox => {
packet_size.plaintext_size() - OUTFOX_ACK_OVERHEAD - variant_overhead
}
_ => packet_size.plaintext_size() - ACK_OVERHEAD - variant_overhead,
}
}
/// Length of the actual (from the **message** point of view) data that is available in each packet.
+15 -8
View File
@@ -1,9 +1,8 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::message::{NymMessage, ACK_OVERHEAD};
use crate::message::{NymMessage, ACK_OVERHEAD, OUTFOX_ACK_OVERHEAD};
use crate::NymPayloadBuilder;
use log::info;
use nym_crypto::asymmetric::encryption;
use nym_crypto::Digest;
use nym_sphinx_acknowledgements::surb_ack::SurbAck;
@@ -114,7 +113,10 @@ pub trait FragmentPreparer {
// each reply attaches the digest of the encryption key so that the recipient could
// lookup correct key for decryption,
let reply_overhead = ReplySurbKeyDigestAlgorithm::output_size();
let expected_plaintext = fragment.serialized_size() + ACK_OVERHEAD + reply_overhead;
let expected_plaintext = match packet_type {
PacketType::Outfox => fragment.serialized_size() + OUTFOX_ACK_OVERHEAD + reply_overhead,
_ => fragment.serialized_size() + ACK_OVERHEAD + reply_overhead,
};
// the reason we're unwrapping (or rather 'expecting') here rather than handling the error
// more gracefully is that this error should never be reached as it implies incorrect chunking
@@ -157,7 +159,7 @@ pub trait FragmentPreparer {
// well as the total delay of the ack packet.
// we don't know the delays inside the reply surbs so we use best-effort estimation from our poisson distribution
total_delay: expected_forward_delay + ack_delay,
mix_packet: MixPacket::new(first_hop_address, sphinx_packet, Default::default()),
mix_packet: MixPacket::new(first_hop_address, sphinx_packet, packet_type),
fragment_identifier,
})
}
@@ -188,12 +190,16 @@ pub trait FragmentPreparer {
packet_recipient: &Recipient,
packet_type: PacketType,
) -> Result<PreparedFragment, NymTopologyError> {
info!("Preparing {packet_type} packet for sending");
// each plain or repliable packet (i.e. not a reply) attaches an ephemeral public key so that the recipient
// could perform diffie-hellman with its own keys followed by a kdf to re-derive
// the packet encryption key
let non_reply_overhead = encryption::PUBLIC_KEY_SIZE;
let expected_plaintext = fragment.serialized_size() + ACK_OVERHEAD + non_reply_overhead;
let expected_plaintext = match packet_type {
PacketType::Outfox => {
fragment.serialized_size() + OUTFOX_ACK_OVERHEAD + non_reply_overhead
}
_ => fragment.serialized_size() + ACK_OVERHEAD + non_reply_overhead,
};
// the reason we're unwrapping (or rather 'expecting') here rather than handling the error
// more gracefully is that this error should never be reached as it implies incorrect chunking
@@ -235,7 +241,8 @@ pub trait FragmentPreparer {
PacketType::Outfox => NymPacket::outfox_build(
packet_payload,
route.as_slice(),
Some(packet_size.payload_size()),
&destination,
Some(packet_size.plaintext_size()),
)?,
PacketType::Mix => NymPacket::sphinx_build(
packet_size.payload_size(),
@@ -262,7 +269,7 @@ pub trait FragmentPreparer {
// well as the total delay of the ack packet.
// note that the last hop of the packet is a gateway that does not do any delays
total_delay: delays.iter().take(delays.len() - 1).sum::<Delay>() + ack_delay,
mix_packet: MixPacket::new(first_hop_address, packet, Default::default()),
mix_packet: MixPacket::new(first_hop_address, packet, packet_type),
fragment_identifier,
})
}
+1
View File
@@ -46,6 +46,7 @@ impl NymPayloadBuilder {
// where variant-specific data is as follows:
// for replies it would be the digest of the encryption key used
// for 'regular' messages it would be the public component used in DH later used in the KDF
Ok(NymPayload(
surb_ack_bytes
.into_iter()
+22 -4
View File
@@ -5,7 +5,7 @@ pub use nym_outfox::{
constants::MIX_PARAMS_LEN, constants::OUTFOX_PACKET_OVERHEAD, error::OutfoxError,
};
// re-exporting types and constants available in sphinx
use nym_outfox::packet::OutfoxPacket;
use nym_outfox::packet::{OutfoxPacket, OutfoxProcessedPacket};
pub use sphinx_packet::{
constants::{
self, DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, MAX_PATH_LENGTH, NODE_ADDRESS_LENGTH,
@@ -41,6 +41,11 @@ pub enum NymPacket {
Outfox(OutfoxPacket),
}
pub enum NymProcessedPacket {
Sphinx(ProcessedPacket),
Outfox(OutfoxProcessedPacket),
}
impl fmt::Debug for NymPacket {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self {
@@ -77,11 +82,13 @@ impl NymPacket {
pub fn outfox_build<M: AsRef<[u8]>>(
payload: M,
route: &[Node],
destination: &Destination,
size: Option<usize>,
) -> Result<NymPacket, NymPacketError> {
Ok(NymPacket::Outfox(OutfoxPacket::build(
payload,
route.try_into()?,
destination,
size,
)?))
}
@@ -108,10 +115,21 @@ impl NymPacket {
}
}
pub fn process(self, node_secret_key: &PrivateKey) -> Result<ProcessedPacket, NymPacketError> {
pub fn process(
self,
node_secret_key: &PrivateKey,
) -> Result<NymProcessedPacket, NymPacketError> {
match self {
NymPacket::Sphinx(packet) => Ok(packet.process(node_secret_key)?),
NymPacket::Outfox(_packet) => todo!(),
NymPacket::Sphinx(packet) => {
Ok(NymProcessedPacket::Sphinx(packet.process(node_secret_key)?))
}
NymPacket::Outfox(mut packet) => {
let next_address = packet.decode_next_layer(node_secret_key)?;
Ok(NymProcessedPacket::Outfox(OutfoxProcessedPacket::new(
packet,
next_address,
)))
}
}
}
}
@@ -499,13 +499,13 @@ impl SocksClient {
})
.unwrap();
info!(
debug!(
"Starting proxy for {} (id: {})",
remote_address.clone(),
self.connection_id
);
self.run_proxy(mix_receiver, remote_address.clone()).await;
info!(
debug!(
"Proxy for {} is finished (id: {})",
remote_address, self.connection_id
);
@@ -78,7 +78,7 @@ impl SocksRequest {
where
R: AsyncRead + Unpin,
{
log::info!("read from stream socks5");
log::trace!("read from stream socks5");
let mut packet = [0u8; 4];
// Read a byte from the stream and determine the version being requested
-1
View File
@@ -9,7 +9,6 @@ use nym_sphinx_addressing::nodes::NodeIdentity;
use rand::prelude::SliceRandom;
use nym_sphinx_types::{Node as SphinxNode, NymPacketError};
use rand::{CryptoRng, Rng};
use std::array::TryFromSliceError;
use std::collections::BTreeMap;
use std::convert::TryInto;
use std::fmt::{self, Display, Formatter};
-459
View File
@@ -3,30 +3,13 @@
version = 3
[[package]]
<<<<<<< HEAD
=======
name = "aead"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
dependencies = [
"crypto-common",
"generic-array 0.14.7",
]
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "aes"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
dependencies = [
"cfg-if",
<<<<<<< HEAD
"cipher",
=======
"cipher 0.3.0",
>>>>>>> 8c48dccac (Outfox framing)
"cpufeatures",
"ctr",
"opaque-debug 0.3.0",
@@ -38,11 +21,7 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
<<<<<<< HEAD
"getrandom 0.2.8",
=======
"getrandom 0.2.9",
>>>>>>> 8c48dccac (Outfox framing)
"once_cell",
"version_check",
]
@@ -60,15 +39,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
[[package]]
<<<<<<< HEAD
=======
name = "arrayvec"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -117,42 +87,12 @@ dependencies = [
]
[[package]]
<<<<<<< HEAD
=======
name = "blake3"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef"
dependencies = [
"arrayref",
"arrayvec",
"cc",
"cfg-if",
"constant_time_eq",
"digest 0.10.6",
]
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
<<<<<<< HEAD
"generic-array 0.14.6",
=======
"generic-array 0.14.7",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array 0.14.7",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -211,54 +151,12 @@ dependencies = [
]
[[package]]
<<<<<<< HEAD
=======
name = "chacha20"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
dependencies = [
"cfg-if",
"cipher 0.4.4",
"cpufeatures",
]
[[package]]
name = "chacha20poly1305"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
dependencies = [
"aead",
"chacha20",
"cipher 0.4.4",
"poly1305",
"zeroize",
]
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "cipher"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
dependencies = [
<<<<<<< HEAD
"generic-array 0.14.6",
=======
"generic-array 0.14.7",
]
[[package]]
name = "cipher"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
"crypto-common",
"inout",
"zeroize",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -293,15 +191,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3"
[[package]]
<<<<<<< HEAD
=======
name = "constant_time_eq"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b"
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "cosmwasm-crypto"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -362,66 +251,14 @@ dependencies = [
[[package]]
name = "cpufeatures"
<<<<<<< HEAD
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
=======
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58"
>>>>>>> 8c48dccac (Outfox framing)
dependencies = [
"libc",
]
[[package]]
<<<<<<< HEAD
=======
name = "crossbeam-channel"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
dependencies = [
"cfg-if",
]
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -433,31 +270,13 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21"
dependencies = [
<<<<<<< HEAD
"generic-array 0.14.6",
=======
"generic-array 0.14.7",
>>>>>>> 8c48dccac (Outfox framing)
"rand_core 0.6.4",
"subtle 2.4.1",
"zeroize",
]
[[package]]
<<<<<<< HEAD
=======
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array 0.14.7",
"rand_core 0.6.4",
"typenum",
]
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "crypto-mac"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -473,11 +292,7 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
dependencies = [
<<<<<<< HEAD
"generic-array 0.14.6",
=======
"generic-array 0.14.7",
>>>>>>> 8c48dccac (Outfox framing)
"subtle 2.4.1",
]
@@ -487,11 +302,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea"
dependencies = [
<<<<<<< HEAD
"cipher",
=======
"cipher 0.3.0",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -687,22 +498,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
<<<<<<< HEAD
"generic-array 0.14.6",
=======
"generic-array 0.14.7",
]
[[package]]
name = "digest"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
dependencies = [
"block-buffer 0.10.4",
"crypto-common",
"subtle 2.4.1",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -740,11 +536,7 @@ checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
dependencies = [
"curve25519-dalek",
"ed25519",
<<<<<<< HEAD
"rand 0.7.3",
=======
"rand",
>>>>>>> 8c48dccac (Outfox framing)
"serde",
"sha2",
"zeroize",
@@ -781,11 +573,7 @@ dependencies = [
"crypto-bigint",
"der",
"ff",
<<<<<<< HEAD
"generic-array 0.14.6",
=======
"generic-array 0.14.7",
>>>>>>> 8c48dccac (Outfox framing)
"group",
"rand_core 0.6.4",
"sec1",
@@ -875,7 +663,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e"
[[package]]
<<<<<<< HEAD
name = "futures"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -971,8 +758,6 @@ dependencies = [
]
[[package]]
=======
>>>>>>> 8c48dccac (Outfox framing)
name = "generic-array"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -983,15 +768,9 @@ dependencies = [
[[package]]
name = "generic-array"
<<<<<<< HEAD
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
=======
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
>>>>>>> 8c48dccac (Outfox framing)
dependencies = [
"typenum",
"version_check",
@@ -1012,7 +791,6 @@ dependencies = [
[[package]]
name = "getrandom"
<<<<<<< HEAD
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
@@ -1020,17 +798,6 @@ dependencies = [
"cfg-if",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
=======
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
"wasm-bindgen",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -1080,18 +847,6 @@ dependencies = [
[[package]]
name = "hermit-abi"
<<<<<<< HEAD
=======
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
>>>>>>> 8c48dccac (Outfox framing)
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
@@ -1149,18 +904,6 @@ dependencies = [
]
[[package]]
<<<<<<< HEAD
=======
name = "inout"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [
"generic-array 0.14.7",
]
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1175,11 +918,7 @@ version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
dependencies = [
<<<<<<< HEAD
"hermit-abi",
=======
"hermit-abi 0.3.1",
>>>>>>> 8c48dccac (Outfox framing)
"libc",
"windows-sys 0.48.0",
]
@@ -1280,15 +1019,9 @@ dependencies = [
[[package]]
name = "linux-raw-sys"
<<<<<<< HEAD
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"
=======
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf"
>>>>>>> 8c48dccac (Outfox framing)
[[package]]
name = "lioness"
@@ -1312,20 +1045,10 @@ dependencies = [
]
[[package]]
<<<<<<< HEAD
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
=======
name = "memoffset"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
dependencies = [
"autocfg",
]
>>>>>>> 8c48dccac (Outfox framing)
[[package]]
name = "mixnet-vesting-integration-tests"
@@ -1354,19 +1077,6 @@ dependencies = [
]
[[package]]
<<<<<<< HEAD
=======
name = "num_cpus"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
"hermit-abi 0.2.6",
"libc",
]
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "nym-coconut-bandwidth"
version = "0.1.0"
dependencies = [
@@ -1436,28 +1146,17 @@ dependencies = [
[[package]]
name = "nym-crypto"
<<<<<<< HEAD
version = "0.3.0"
=======
version = "0.2.0"
>>>>>>> 8c48dccac (Outfox framing)
dependencies = [
"bs58",
"ed25519-dalek",
"nym-pemstore",
"nym-sphinx-types",
<<<<<<< HEAD
"rand 0.7.3",
"subtle-encoding",
"thiserror",
"x25519-dalek",
"zeroize",
=======
"rand",
"subtle-encoding",
"thiserror",
"x25519-dalek",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -1524,7 +1223,6 @@ dependencies = [
]
[[package]]
<<<<<<< HEAD
name = "nym-name-service"
version = "0.1.0"
dependencies = [
@@ -1552,21 +1250,6 @@ dependencies = [
"cosmwasm-std",
"schemars",
"serde",
=======
name = "nym-outfox"
version = "0.1.0"
dependencies = [
"blake3",
"chacha20",
"chacha20poly1305",
"curve25519-dalek",
"getrandom 0.2.9",
"rand",
"rayon",
"sphinx-packet",
"thiserror",
"zeroize",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -1600,10 +1283,7 @@ name = "nym-service-provider-directory-common"
version = "0.1.0"
dependencies = [
"cosmwasm-std",
<<<<<<< HEAD
"schemars",
=======
>>>>>>> 8c48dccac (Outfox framing)
"serde",
]
@@ -1611,13 +1291,7 @@ dependencies = [
name = "nym-sphinx-types"
version = "0.2.0"
dependencies = [
<<<<<<< HEAD
"sphinx-packet",
=======
"nym-outfox",
"sphinx-packet",
"thiserror",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -1690,7 +1364,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]]
<<<<<<< HEAD
name = "pin-project-lite"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1703,8 +1376,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
=======
>>>>>>> 8c48dccac (Outfox framing)
name = "pkcs8"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1722,20 +1393,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
<<<<<<< HEAD
=======
name = "poly1305"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
dependencies = [
"cpufeatures",
"opaque-debug 0.3.0",
"universal-hash",
]
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1767,15 +1424,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
<<<<<<< HEAD
version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224"
=======
version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
>>>>>>> 8c48dccac (Outfox framing)
dependencies = [
"unicode-ident",
]
@@ -1832,7 +1483,6 @@ dependencies = [
]
[[package]]
<<<<<<< HEAD
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1844,8 +1494,6 @@ dependencies = [
]
[[package]]
=======
>>>>>>> 8c48dccac (Outfox framing)
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1880,11 +1528,7 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
<<<<<<< HEAD
"getrandom 0.2.8",
=======
"getrandom 0.2.9",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -1894,11 +1538,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56"
dependencies = [
"num-traits",
<<<<<<< HEAD
"rand 0.7.3",
=======
"rand",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -1911,31 +1551,6 @@ dependencies = [
]
[[package]]
<<<<<<< HEAD
=======
name = "rayon"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1971,7 +1586,6 @@ dependencies = [
]
[[package]]
<<<<<<< HEAD
name = "rstest"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1998,8 +1612,6 @@ dependencies = [
]
[[package]]
=======
>>>>>>> 8c48dccac (Outfox framing)
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2010,15 +1622,9 @@ dependencies = [
[[package]]
name = "rustix"
<<<<<<< HEAD
version = "0.37.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
=======
version = "0.37.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b864d3c18a5785a05953adeed93e2dca37ed30f18e69bba9f30079d51f363f"
>>>>>>> 8c48dccac (Outfox framing)
dependencies = [
"bitflags",
"errno",
@@ -2077,26 +1683,13 @@ dependencies = [
]
[[package]]
<<<<<<< HEAD
=======
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "sec1"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1"
dependencies = [
"der",
<<<<<<< HEAD
"generic-array 0.14.6",
=======
"generic-array 0.14.7",
>>>>>>> 8c48dccac (Outfox framing)
"pkcs8",
"subtle 2.4.1",
"zeroize",
@@ -2134,11 +1727,7 @@ checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df"
dependencies = [
"proc-macro2",
"quote",
<<<<<<< HEAD
"syn 2.0.12",
=======
"syn 2.0.15",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -2171,11 +1760,7 @@ checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab"
dependencies = [
"proc-macro2",
"quote",
<<<<<<< HEAD
"syn 2.0.12",
=======
"syn 2.0.15",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -2184,11 +1769,7 @@ version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
dependencies = [
<<<<<<< HEAD
"block-buffer",
=======
"block-buffer 0.9.0",
>>>>>>> 8c48dccac (Outfox framing)
"cfg-if",
"cpufeatures",
"digest 0.9.0",
@@ -2206,7 +1787,6 @@ dependencies = [
]
[[package]]
<<<<<<< HEAD
name = "slab"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2216,8 +1796,6 @@ dependencies = [
]
[[package]]
=======
>>>>>>> 8c48dccac (Outfox framing)
name = "sphinx-packet"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2235,11 +1813,7 @@ dependencies = [
"hmac",
"lioness",
"log",
<<<<<<< HEAD
"rand 0.7.3",
=======
"rand",
>>>>>>> 8c48dccac (Outfox framing)
"rand_distr",
"sha2",
"subtle 2.4.1",
@@ -2295,15 +1869,9 @@ dependencies = [
[[package]]
name = "syn"
<<<<<<< HEAD
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927"
=======
version = "2.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
>>>>>>> 8c48dccac (Outfox framing)
dependencies = [
"proc-macro2",
"quote",
@@ -2340,11 +1908,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
dependencies = [
"proc-macro2",
"quote",
<<<<<<< HEAD
"syn 2.0.12",
=======
"syn 2.0.15",
>>>>>>> 8c48dccac (Outfox framing)
]
[[package]]
@@ -2409,15 +1973,9 @@ dependencies = [
[[package]]
name = "unicode-bidi"
<<<<<<< HEAD
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d502c968c6a838ead8e69b2ee18ec708802f99db92a0d156705ec9ef801993b"
=======
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
>>>>>>> 8c48dccac (Outfox framing)
[[package]]
name = "unicode-ident"
@@ -2435,19 +1993,6 @@ dependencies = [
]
[[package]]
<<<<<<< HEAD
=======
name = "universal-hash"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5"
dependencies = [
"crypto-common",
"subtle 2.4.1",
]
[[package]]
>>>>>>> 8c48dccac (Outfox framing)
name = "url"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2722,9 +2267,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
<<<<<<< HEAD
"syn 2.0.12",
=======
"syn 2.0.15",
>>>>>>> 8c48dccac (Outfox framing)
]
@@ -309,7 +309,10 @@ where
async fn handle_binary(&self, bin_msg: Vec<u8>) -> Message {
// this function decrypts the request and checks the MAC
match BinaryRequest::try_from_encrypted_tagged_bytes(bin_msg, &self.client.shared_keys) {
Err(e) => RequestHandlingError::InvalidBinaryRequest(e).into_error_message(),
Err(e) => {
error!("{e}");
RequestHandlingError::InvalidBinaryRequest(e).into_error_message()
}
Ok(request) => match request {
// currently only a single type exists
BinaryRequest::ForwardSphinx(mix_packet) => self
@@ -121,7 +121,7 @@ impl<St: Storage> ConnectionHandler<St> {
fn forward_ack(&self, forward_ack: Option<MixPacket>, client_address: DestinationAddressBytes) {
if let Some(forward_ack) = forward_ack {
trace!(
debug!(
"Sending ack from packet for {} to {}",
client_address,
forward_ack.next_hop()
@@ -206,7 +206,10 @@ impl<St: Storage> ConnectionHandler<St> {
);
return;
}
None => break, // stream got closed by remote
None => {
info!("Stream go closed by remote");
break
}, // stream got closed by remote
}
}
}
+1
View File
@@ -51,6 +51,7 @@ nym-mixnet-client = { path = "../common/client-libs/mixnet-client" }
nym-mixnode-common = { path = "../common/mixnode-common" }
nym-nonexhaustive-delayqueue = { path = "../common/nonexhaustive-delayqueue" }
nym-sphinx = { path = "../common/nymsphinx" }
nym-sphinx-params = { path = "../common/nymsphinx/params" }
nym-pemstore = { path = "../common/pemstore", version = "0.2.0" }
nym-task = { path = "../common/task" }
nym-types = { path = "../common/types" }
@@ -108,7 +108,7 @@ impl ConnectionHandler {
}
Some(Err(err)) => {
error!(
"The socket connection got corrupted with error: {err}. Closing the socket",
"{remote:?} - The socket connection got corrupted with error: {err}. Closing the socket",
);
return;
}
@@ -12,7 +12,7 @@ use nym_node_tester_utils::NodeTester;
use nym_sphinx::acknowledgements::AckKey;
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::forwarding::packet::MixPacket;
use nym_sphinx::params::PacketSize;
use nym_sphinx::params::{PacketSize, PacketType};
use nym_topology::{gateway, mix};
use rand_07::{rngs::ThreadRng, seq::SliceRandom, thread_rng, Rng};
use std::collections::{HashMap, HashSet};
@@ -290,7 +290,8 @@ impl PacketPreparer {
&mut self,
route: &TestRoute,
num: usize,
packet_type: PacketType,
// TODO: Maybe do this
_packet_type: PacketType,
) -> GatewayPackets {
let mut tester = self.ephemeral_mix_tester(route);
let topology = route.topology();
@@ -360,7 +361,8 @@ impl PacketPreparer {
&mut self,
test_nonce: u64,
test_routes: &[TestRoute],
packet_type: PacketType,
// TODO: Maybe do this
_packet_type: PacketType,
) -> PreparedPackets {
// only test mixnodes that are rewarded, i.e. that will be rewarded in this interval.
// (remember that "idle" nodes are still part of that set)
+1
View File
@@ -3563,6 +3563,7 @@ dependencies = [
"chacha20poly1305",
"curve25519-dalek",
"getrandom 0.2.8",
"log",
"rand 0.7.3",
"rayon",
"sphinx-packet",
+1
View File
@@ -17,6 +17,7 @@ getrandom = { version = "*", features = ["js"] }
thiserror = "1"
sphinx-packet = "0.1.0"
rand = "0.7.3"
log = "0.4"
[dev-dependencies]
criterion = "0.4"
+4 -1
View File
@@ -1,11 +1,14 @@
pub const GROUPELEMENTBYTES: u8 = 32;
pub const TAGBYTES: u8 = 16;
pub const MIX_PARAMS_LEN: usize = 6;
pub const MIX_PARAMS_LEN: usize = DEFAULT_HOPS + 2;
pub const MIN_MESSAGE_LEN: usize = 24 * 2;
pub(crate) const CONTEXT: &str = "LIONKEYS";
pub(crate) const TAG_LEN: usize = 24;
pub const DEFAULT_ROUTING_INFO_SIZE: u8 = 32;
pub const DEFAULT_HOPS: usize = 4;
pub const ROUTING_INFORMATION_LENGTH_BY_STAGE: [u8; DEFAULT_HOPS] =
[DEFAULT_ROUTING_INFO_SIZE; DEFAULT_HOPS];
pub const MIN_PACKET_SIZE: usize = 48;
pub const OUTFOX_PACKET_OVERHEAD: usize = MIX_PARAMS_LEN
+ (groupelementbytes() + tagbytes() + DEFAULT_ROUTING_INFO_SIZE as usize) * DEFAULT_HOPS;
+1 -3
View File
@@ -1,5 +1,3 @@
use std::array::TryFromSliceError;
use crate::constants::MIN_MESSAGE_LEN;
use crate::constants::MIX_PARAMS_LEN;
use chacha20::cipher::InvalidLength;
@@ -23,7 +21,7 @@ pub enum OutfoxError {
#[error("{source}")]
TryFromSlice {
#[from]
source: TryFromSliceError,
source: std::array::TryFromSliceError,
},
#[error("Header length must be {MIX_PARAMS_LEN}, got {0}")]
InvalidHeaderLength(usize),
+12 -10
View File
@@ -62,7 +62,6 @@ use chacha20poly1305::Tag;
use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE;
use curve25519_dalek::montgomery::MontgomeryPoint;
use curve25519_dalek::scalar::Scalar;
use sphinx_packet::route::Node;
use std::convert::TryInto;
@@ -75,6 +74,7 @@ use crate::constants::DEFAULT_HOPS;
use crate::constants::DEFAULT_ROUTING_INFO_SIZE;
use crate::constants::GROUPELEMENTBYTES;
use crate::constants::MIX_PARAMS_LEN;
use crate::constants::ROUTING_INFORMATION_LENGTH_BY_STAGE;
use crate::constants::TAGBYTES;
use crate::error::OutfoxError;
use crate::lion::*;
@@ -135,7 +135,7 @@ impl MixCreationParameters {
/// The length of the buffer needed to build a packet.
pub fn total_packet_length(&self) -> usize {
let mut len = self.payload_length_bytes();
for stage_len in &self.routing_information_length_by_stage {
for stage_len in ROUTING_INFORMATION_LENGTH_BY_STAGE.iter() {
len += *stage_len as usize + groupelementbytes() + tagbytes()
}
len
@@ -143,10 +143,10 @@ impl MixCreationParameters {
/// Get the mix packet parameters for a single stage of mixing.
pub fn get_stage_params(&self, layer_number: usize) -> (Range<usize>, MixStageParameters) {
assert!(layer_number < self.routing_information_length_by_stage.len());
assert!(layer_number < ROUTING_INFORMATION_LENGTH_BY_STAGE.len());
let mut remaining_header_length_bytes = 0;
for (i, stage_len) in self.routing_information_length_by_stage.iter().enumerate() {
for (i, stage_len) in ROUTING_INFORMATION_LENGTH_BY_STAGE.iter().enumerate() {
if i == layer_number {
let params = MixStageParameters {
routing_information_length_bytes: *stage_len,
@@ -229,10 +229,11 @@ impl MixStageParameters {
&self,
buffer: &mut [u8],
user_secret_key: &[u8],
node: &Node,
node_pub_key: &[u8],
destination: &[u8; 32],
) -> Result<MontgomeryPoint, OutfoxError> {
let routing_data = node.address.as_bytes().to_vec();
let mix_public_key = MontgomeryPoint(*node.pub_key.as_bytes());
let routing_data = destination;
let mix_public_key = MontgomeryPoint(node_pub_key.try_into()?);
let user_secret_key = Scalar::from_bytes_mod_order(user_secret_key.try_into()?);
if buffer.len() != self.incoming_packet_length() {
@@ -253,7 +254,7 @@ impl MixStageParameters {
let shared_key = user_secret_key * mix_public_key;
// Copy rounting data into buffer
buffer[self.routing_data_range()].copy_from_slice(&routing_data);
buffer[self.routing_data_range()].copy_from_slice(routing_data);
// Perform the AEAD
let header_aead_key = ChaCha20Poly1305::new_from_slice(&shared_key.0[..])?;
@@ -279,7 +280,7 @@ impl MixStageParameters {
&self,
buffer: &mut [u8],
mix_secret_key: &[u8],
) -> Result<MontgomeryPoint, OutfoxError> {
) -> Result<Vec<u8>, OutfoxError> {
// Check the length of the incoming buffer is correct.
let mix_secret_key = Scalar::from_bytes_mod_order(mix_secret_key.try_into()?);
@@ -311,10 +312,11 @@ impl MixStageParameters {
)
.map_err(|e| OutfoxError::ChaCha20Poly1305Error(e.to_string()))?;
let routing_data = buffer[self.routing_data_range()].to_vec();
// Do a round of LION on the payload
lion_transform_decrypt(&mut buffer[self.payload_range()], &shared_key.0)?;
Ok(shared_key)
Ok(routing_data)
}
}
+130 -9
View File
@@ -1,13 +1,23 @@
use std::{convert::TryFrom, ops::Range};
use std::{
array::TryFromSliceError,
collections::VecDeque,
convert::{TryFrom, TryInto},
iter::FromIterator,
ops::Range,
};
use crate::{
constants::{DEFAULT_HOPS, MIX_PARAMS_LEN},
constants::{DEFAULT_HOPS, MIN_PACKET_SIZE, MIX_PARAMS_LEN},
error::OutfoxError,
format::{MixCreationParameters, MixStageParameters},
};
use rand::{rngs::OsRng, RngCore};
use sphinx_packet::{packet::builder::DEFAULT_PAYLOAD_SIZE, route::Node};
use sphinx_packet::{
crypto::PrivateKey,
packet::builder::DEFAULT_PAYLOAD_SIZE,
route::{Destination, Node},
};
#[derive(Debug)]
pub struct OutfoxPacket {
@@ -15,6 +25,28 @@ pub struct OutfoxPacket {
payload: Vec<u8>,
}
pub struct OutfoxProcessedPacket {
packet: OutfoxPacket,
next_address: [u8; 32],
}
impl OutfoxProcessedPacket {
pub fn new(packet: OutfoxPacket, next_address: [u8; 32]) -> Self {
OutfoxProcessedPacket {
packet,
next_address,
}
}
pub fn into_packet(self) -> OutfoxPacket {
self.packet
}
pub fn next_address(&self) -> &[u8; 32] {
&self.next_address
}
}
impl TryFrom<&[u8]> for OutfoxPacket {
type Error = OutfoxError;
@@ -28,8 +60,20 @@ impl TryFrom<&[u8]> for OutfoxPacket {
}
impl OutfoxPacket {
pub fn recover_plaintext(&self) -> Vec<u8> {
let plaintext = self.payload()[self.payload_range()].to_vec();
if plaintext.starts_with(&[0]) {
let mut plaintext = VecDeque::from_iter(plaintext);
while let Some(0) = plaintext.front() {
plaintext.pop_front();
}
return plaintext.make_contiguous().to_vec();
}
plaintext
}
pub fn len(&self) -> usize {
self.mix_params().total_packet_length()
self.mix_params().total_packet_length() + MIX_PARAMS_LEN
}
pub fn is_empty(&self) -> bool {
@@ -46,20 +90,54 @@ impl OutfoxPacket {
pub fn build<M: AsRef<[u8]>>(
payload: M,
route: &[Node; 4],
destination: &Destination,
packet_size: Option<usize>,
) -> Result<OutfoxPacket, OutfoxError> {
let mut secret_key = [0; 32];
OsRng.fill_bytes(&mut secret_key);
let packet_size = packet_size.unwrap_or(DEFAULT_PAYLOAD_SIZE);
let packet_size = if packet_size < MIN_PACKET_SIZE {
MIN_PACKET_SIZE
} else {
packet_size
};
let mix_params = MixCreationParameters::new(packet_size as u16);
let padding = mix_params.total_packet_length() - payload.as_ref().len();
let mut buffer = vec![0; padding];
buffer.extend_from_slice(payload.as_ref());
for (idx, node) in route.iter().rev().enumerate() {
let (range, stage_params) = mix_params.get_stage_params(idx);
stage_params.encode_mix_layer(&mut buffer[range], &secret_key, node)?;
// Last node in the route is a gateway, it will decrypt last, and get the final destination address
let (range, stage_params) = mix_params.get_stage_params(0);
stage_params.encode_mix_layer(
&mut buffer[range],
&secret_key,
route.last().unwrap().pub_key.as_bytes(),
destination.address.as_bytes_ref(),
)?;
let route = route.iter().rev().collect::<Vec<&Node>>();
// We've reversed the route, and we iterate pairs of node, first node in the pair is the destination, and the second(last) is the processing node
// Route: [N1, N2, N3, G]
// Reverse: [G, N3, N2, N1]
// Pairs: [(G, N3), (N3, N2), (N2, N1)]
// We iterate over pairs, and encode the mix layer for each pair
// For the first pair, we encode the mix layer for N3, and the destination is G
// For the second pair, we encode the mix layer for N2, and the destination is N3
// For the third pair, we encode the mix layer for N1, and the destination is N2
// Entry gateway will simply forward the packet to N1 and processing will continue from there
for (idx, nodes) in route.windows(2).enumerate() {
let (range, stage_params) = mix_params.get_stage_params(idx + 1);
// We know that we'll always get 4 nodes, so we can unwrap here
let processing_node = nodes.last().unwrap();
let destination_node = nodes.first().unwrap();
stage_params.encode_mix_layer(
&mut buffer[range],
&secret_key,
processing_node.pub_key.as_bytes(),
destination_node.address.as_bytes_ref(),
)?;
}
Ok(OutfoxPacket {
@@ -92,9 +170,52 @@ impl OutfoxPacket {
&mut self,
layer: usize,
mix_secret_key: &[u8; 32],
) -> Result<(), OutfoxError> {
) -> Result<Vec<u8>, OutfoxError> {
let (range, params) = self.stage_params(layer);
params.decode_mix_layer(&mut self.payload_mut()[range], mix_secret_key)?;
let routing_data =
params.decode_mix_layer(&mut self.payload_mut()[range], mix_secret_key)?;
Ok(routing_data)
}
pub fn update_routing_information(&mut self, layer: usize) -> Result<(), TryFromSliceError> {
let mut routing_info = self
.mix_params()
.routing_information_length_by_stage
.to_vec();
routing_info.push(0);
routing_info.swap_remove(layer);
self.mix_params.routing_information_length_by_stage = routing_info.as_slice().try_into()?;
Ok(())
}
pub fn is_final_hop(&self) -> bool {
self.mix_params()
.routing_information_length_by_stage
.iter()
.all(|x| x == &0)
}
pub fn decode_next_layer(
&mut self,
mix_secret_key: &PrivateKey,
) -> Result<[u8; 32], OutfoxError> {
let mix_secret_key = mix_secret_key.to_bytes();
let routing_lenght_by_stage = self
.mix_params()
.routing_information_length_by_stage
.as_slice();
let mut layer = DEFAULT_HOPS - 1;
for (i, length) in routing_lenght_by_stage.iter().rev().enumerate() {
if length == &32 {
layer = DEFAULT_HOPS - 1 - i;
break;
}
}
self.decode_mix_layer(layer, &mix_secret_key)?;
self.update_routing_information(layer)?;
let (range, stage_params) = self.mix_params().get_stage_params(layer);
let routing_bytes = &self.payload()[range][stage_params.routing_data_range()];
let routing_address: [u8; 32] = routing_bytes.try_into()?;
Ok(routing_address)
}
}
+30 -12
View File
@@ -14,6 +14,8 @@ mod tests {
use nym_outfox::packet::OutfoxPacket;
use sphinx_packet::constants::NODE_ADDRESS_LENGTH;
use sphinx_packet::crypto::PublicKey;
use sphinx_packet::route::Destination;
use sphinx_packet::route::DestinationAddressBytes;
use sphinx_packet::route::Node;
use sphinx_packet::route::NodeAddressBytes;
use std::convert::TryFrom;
@@ -37,6 +39,7 @@ mod tests {
let mix_public_key = (&ED25519_BASEPOINT_TABLE * &mix_secret_scalar).to_montgomery();
let routing = [0; 32];
let destination = [0; 32];
let buffer = randombytes(mix_params.incoming_packet_length());
@@ -48,7 +51,12 @@ mod tests {
let node = Node::new(node_address_bytes, mix_public_key);
let _ = mix_params
.encode_mix_layer(&mut new_buffer[..], &user_secret, &node)
.encode_mix_layer(
&mut new_buffer[..],
&user_secret,
node.pub_key.as_bytes(),
&destination,
)
.unwrap();
assert!(new_buffer[mix_params.payload_range()] != buffer[mix_params.payload_range()]);
@@ -97,17 +105,23 @@ mod tests {
node3_pub,
);
let (node4_pk, node4_pub) = sphinx_packet::crypto::keygen();
let node4 = Node::new(
let (gateway_pk, gateway_pub) = sphinx_packet::crypto::keygen();
let gateway = Node::new(
NodeAddressBytes::from_bytes([3u8; NODE_ADDRESS_LENGTH]),
node4_pub,
gateway_pub,
);
let route = [node1, node2, node3, node4];
let destination = Destination::new(
DestinationAddressBytes::from_bytes([9u8; NODE_ADDRESS_LENGTH]),
[0u8; 16],
);
let payload = randombytes(2048);
let route = [node1.clone(), node2.clone(), node3.clone(), gateway.clone()];
let packet = OutfoxPacket::build(&payload, &route, Some(2048)).unwrap();
let payload = randombytes(21);
let packet =
OutfoxPacket::build(&payload, &route, &destination, Some(payload.len())).unwrap();
let packet_bytes = packet.to_bytes().unwrap();
println!(
"packet bytes length, {}, declared {}",
@@ -117,11 +131,15 @@ mod tests {
let mut packet = OutfoxPacket::try_from(packet_bytes.as_slice()).unwrap();
packet.decode_mix_layer(3, &node1_pk.to_bytes()).unwrap();
packet.decode_mix_layer(2, &node2_pk.to_bytes()).unwrap();
packet.decode_mix_layer(1, &node3_pk.to_bytes()).unwrap();
packet.decode_mix_layer(0, &node4_pk.to_bytes()).unwrap();
let next_address = packet.decode_next_layer(&node1_pk).unwrap();
assert_eq!(next_address, node2.address.as_bytes());
let next_address = packet.decode_next_layer(&node2_pk).unwrap();
assert_eq!(next_address, node3.address.as_bytes());
let next_address = packet.decode_next_layer(&node3_pk).unwrap();
assert_eq!(next_address, gateway.address.as_bytes());
let destination_address = packet.decode_next_layer(&gateway_pk).unwrap();
assert_eq!(destination_address, destination.address.as_bytes());
assert_eq!(payload, &packet.payload()[packet.payload_range()]);
assert_eq!(payload, packet.recover_plaintext());
}
}
+747 -949
View File
File diff suppressed because it is too large Load Diff