Compare commits
4 Commits
ls
...
sphinx_benchmarks
| Author | SHA1 | Date | |
|---|---|---|---|
| 5f758f47ba | |||
| e0274bb394 | |||
| 607d4dc743 | |||
| 25f7b7a083 |
Generated
+1
@@ -3924,6 +3924,7 @@ dependencies = [
|
||||
name = "nymsphinx"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"criterion 0.3.6",
|
||||
"crypto",
|
||||
"mixnet-contract-common",
|
||||
"nymsphinx-acknowledgements",
|
||||
|
||||
@@ -27,6 +27,11 @@ topology = { path = "../topology" }
|
||||
|
||||
[dev-dependencies]
|
||||
mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
|
||||
criterion = "0.3"
|
||||
|
||||
[[bench]]
|
||||
name = "benchmarks"
|
||||
harness = false
|
||||
|
||||
# do not include this when compiling into wasm as it somehow when combined together with reqwest, it will require
|
||||
# net2 via tokio-util -> tokio -> mio -> net2
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use criterion::{black_box, Criterion, criterion_group, criterion_main};
|
||||
|
||||
use crypto::asymmetric::{encryption, identity};
|
||||
use crypto::asymmetric::encryption::{KeyPair, PrivateKey};
|
||||
use crypto::asymmetric::identity::PublicKey;
|
||||
use mixnet_contract_common::Layer;
|
||||
use nymsphinx::{delays, Node, NODE_ADDRESS_LENGTH, NodeAddressBytes, NymsphinxPayloadBuilder, PAYLOAD_OVERHEAD_SIZE, SphinxPacket};
|
||||
use nymsphinx::acknowledgements::AckKey;
|
||||
use nymsphinx::acknowledgements::surb_ack::SurbAck;
|
||||
use nymsphinx::addressing::clients::Recipient;
|
||||
use nymsphinx::builder::SphinxPacketBuilder;
|
||||
use nymsphinx::chunking::fragment::{Fragment, FragmentHeader, FragmentIdentifier};
|
||||
use nymsphinx::cover::generate_loop_cover_packet;
|
||||
use nymsphinx::crypto::keygen;
|
||||
use nymsphinx::params::packet_sizes::PacketSize::{ExtendedPacket16, ExtendedPacket32, ExtendedPacket8, RegularPacket};
|
||||
use nymsphinx::params::PacketSize;
|
||||
use topology::{gateway, mix, MixLayer, NymTopology};
|
||||
|
||||
const REGULAR_PACKET_SIZE: usize = PAYLOAD_OVERHEAD_SIZE + 2 * 1024;
|
||||
const EXTENDED_PACKET_SIZE_8: usize = PAYLOAD_OVERHEAD_SIZE + 8 * 1024;
|
||||
const EXTENDED_PACKET_SIZE_16: usize = PAYLOAD_OVERHEAD_SIZE + 16 * 1024;
|
||||
const EXTENDED_PACKET_SIZE_32: usize = PAYLOAD_OVERHEAD_SIZE + 32 * 1024;
|
||||
|
||||
struct BenchCase {
|
||||
packet_size: PacketSize,
|
||||
}
|
||||
|
||||
fn feature_topology(sender_gateway_id: PublicKey, recipient_gateway_id: PublicKey) -> (NymTopology, KeyPair) {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let gateway1 = gateway::Node {
|
||||
owner: "N/A".to_string(),
|
||||
stake: 1000,
|
||||
location: "N/A".to_string(),
|
||||
host: "1.1.1.1".parse().unwrap(),
|
||||
mix_host: "1.1.1.1:1789".parse().unwrap(),
|
||||
clients_port: 8888,
|
||||
identity_key: sender_gateway_id,
|
||||
sphinx_key: encryption::PublicKey::from_base58_string(
|
||||
"C7cown6dYCLZpLiMFC1PaBmhvLvmJmLDJGeRTbPD45bX",
|
||||
)
|
||||
.unwrap(),
|
||||
version: "0.x.0".to_string(),
|
||||
};
|
||||
|
||||
let gateway2 = gateway::Node {
|
||||
identity_key: recipient_gateway_id,
|
||||
..gateway1.clone()
|
||||
};
|
||||
|
||||
let node1_enc_keys = KeyPair::new(&mut rng);
|
||||
let node1 = mix::Node {
|
||||
mix_id: 42,
|
||||
owner: "N/A".to_string(),
|
||||
host: "3.3.3.3".parse().unwrap(),
|
||||
mix_host: "3.3.3.3:1789".parse().unwrap(),
|
||||
identity_key: identity::PublicKey::from_base58_string(
|
||||
"3ebjp1Fb9hdcS1AR6AZihgeJiMHkB5jjJUsvqNnfQwU7",
|
||||
)
|
||||
.unwrap(),
|
||||
sphinx_key: *node1_enc_keys.public_key(),
|
||||
layer: Layer::One,
|
||||
version: "0.x.0".to_string(),
|
||||
};
|
||||
|
||||
let node2 = mix::Node {
|
||||
owner: "Alice".to_string(),
|
||||
..node1.clone()
|
||||
};
|
||||
|
||||
let node3 = mix::Node {
|
||||
owner: "Bob".to_string(),
|
||||
..node1.clone()
|
||||
};
|
||||
|
||||
let mut mixes: HashMap<MixLayer, Vec<mix::Node>> = HashMap::new();
|
||||
mixes.insert(1, vec![node1]);
|
||||
mixes.insert(2, vec![node2]);
|
||||
mixes.insert(3, vec![node3]);
|
||||
|
||||
let topology = NymTopology::new(mixes, vec![gateway1, gateway2]);
|
||||
(topology, node1_enc_keys)
|
||||
}
|
||||
|
||||
fn make_packet_copy(packet: &SphinxPacket) -> SphinxPacket {
|
||||
SphinxPacket::from_bytes(&packet.to_bytes()).unwrap()
|
||||
}
|
||||
|
||||
fn bench_loop_packet_create(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("benchmark-sphinx");
|
||||
// group.sample_size(200);
|
||||
group.measurement_time(Duration::from_secs(500));
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
let case = BenchCase {
|
||||
packet_size: RegularPacket,
|
||||
};
|
||||
|
||||
// create sender
|
||||
let sender_client_id_pair = identity::KeyPair::new(&mut rng);
|
||||
let sender_client_enc_pair = encryption::KeyPair::new(&mut rng);
|
||||
let sender_gateway_id_pair = identity::KeyPair::new(&mut rng);
|
||||
let packet_sender = Recipient::new(
|
||||
*sender_client_id_pair.public_key(),
|
||||
*sender_client_enc_pair.public_key(),
|
||||
*sender_gateway_id_pair.public_key(),
|
||||
);
|
||||
|
||||
// build topology
|
||||
let (topology, node_keypair) = feature_topology(*sender_gateway_id_pair.public_key(), *sender_gateway_id_pair.public_key());
|
||||
// generate the encryption key for the ack
|
||||
let ack_key = AckKey::new(&mut rng);
|
||||
|
||||
group.bench_function(
|
||||
&format!(
|
||||
"[Sphinx] create_loop_cover_packet_with_payload_size_{}",
|
||||
case.packet_size.payload_size(),
|
||||
),
|
||||
|b| {
|
||||
b.iter(|| {
|
||||
generate_loop_cover_packet(
|
||||
&mut rng,
|
||||
&topology,
|
||||
&ack_key,
|
||||
&packet_sender,
|
||||
Duration::from_millis(50),
|
||||
Duration::from_millis(50),
|
||||
case.packet_size)
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
// let's create the packet to later benchmark the processing
|
||||
let packet = generate_loop_cover_packet(
|
||||
&mut rng,
|
||||
&topology,
|
||||
&ack_key,
|
||||
&packet_sender,
|
||||
Duration::from_millis(50),
|
||||
Duration::from_millis(50),
|
||||
case.packet_size).unwrap();
|
||||
|
||||
group.bench_function(
|
||||
&format!(
|
||||
"[Sphinx] process_loop_cover_packet_with_payload_size_{}",
|
||||
case.packet_size.payload_size(),
|
||||
),
|
||||
|b| {
|
||||
b.iter(|| {
|
||||
make_packet_copy(&packet.sphinx_packet).process(&node_keypair.private_key().into())
|
||||
})
|
||||
},
|
||||
);
|
||||
// let new_packet = packet.sphinx_packet.process(&node_keypair.private_key().into());
|
||||
}
|
||||
|
||||
fn bench_new_no_surb(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("benchmark-sphinx");
|
||||
// group.sample_size(200);
|
||||
group.measurement_time(Duration::from_secs(500));
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
let case = BenchCase {
|
||||
packet_size: ExtendedPacket8,
|
||||
};
|
||||
|
||||
// create sender
|
||||
let sender_client_id_pair = identity::KeyPair::new(&mut rng);
|
||||
let sender_client_enc_pair = encryption::KeyPair::new(&mut rng);
|
||||
let sender_gateway_id_pair = identity::KeyPair::new(&mut rng);
|
||||
let packet_sender = Recipient::new(
|
||||
*sender_client_id_pair.public_key(),
|
||||
*sender_client_enc_pair.public_key(),
|
||||
*sender_gateway_id_pair.public_key(),
|
||||
);
|
||||
|
||||
// create recipient
|
||||
let recipient_client_id_pair = identity::KeyPair::new(&mut rng);
|
||||
let recipient_client_enc_pair = encryption::KeyPair::new(&mut rng);
|
||||
let recipient_gateway_id_pair = identity::KeyPair::new(&mut rng);
|
||||
let packet_recipient = Recipient::new(
|
||||
*recipient_client_id_pair.public_key(),
|
||||
*recipient_client_enc_pair.public_key(),
|
||||
*recipient_gateway_id_pair.public_key(),
|
||||
);
|
||||
|
||||
// build topology
|
||||
let (topology, node_keypair) = feature_topology(*sender_gateway_id_pair.public_key(), *recipient_gateway_id_pair.public_key());
|
||||
|
||||
// generate pseudorandom route for the packet
|
||||
let route = topology.random_route_to_gateway(
|
||||
&mut rng,
|
||||
3,
|
||||
packet_recipient.gateway(),
|
||||
).unwrap();
|
||||
|
||||
// generate some payload
|
||||
let mlen = 40;
|
||||
let mut msg = vec![0u8; mlen];
|
||||
let fragment = Fragment {
|
||||
header: FragmentHeader::try_new(
|
||||
12345,
|
||||
u8::max_value(),
|
||||
u8::max_value(),
|
||||
None,
|
||||
Some(1234),
|
||||
)
|
||||
.unwrap(),
|
||||
payload: msg,
|
||||
};
|
||||
|
||||
|
||||
let ack_key = AckKey::new(&mut rng);
|
||||
let surb_ack = SurbAck::construct(
|
||||
&mut rng,
|
||||
&packet_sender,
|
||||
&ack_key,
|
||||
fragment.fragment_identifier().to_bytes(),
|
||||
Duration::from_millis(50),
|
||||
&topology,
|
||||
).unwrap();
|
||||
|
||||
|
||||
let packet_payload = NymsphinxPayloadBuilder::new(fragment, surb_ack)
|
||||
.build_regular(&mut rng, packet_recipient.encryption_key());
|
||||
|
||||
let delays = delays::generate_from_average_duration(route.len(), Duration::from_millis(50));
|
||||
let destination = packet_recipient.as_sphinx_destination();
|
||||
|
||||
group.bench_function(
|
||||
&format!(
|
||||
"[Sphinx] create_packet_no_reply_surbs_with_payload_size_{}",
|
||||
case.packet_size.payload_size(),
|
||||
),
|
||||
|b| {
|
||||
b.iter(|| {
|
||||
SphinxPacketBuilder::new()
|
||||
.with_payload_size(case.packet_size.payload_size())
|
||||
.build_packet(packet_payload.clone(), &route, &destination, &delays)
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
// let's create the packet to later benchmark the processing
|
||||
let sphinx_packet = SphinxPacketBuilder::new()
|
||||
.with_payload_size(case.packet_size.payload_size())
|
||||
.build_packet(packet_payload.clone(), &route, &destination, &delays)
|
||||
.unwrap();
|
||||
|
||||
group.bench_function(
|
||||
&format!(
|
||||
"[Sphinx] process_packet_with_payload_size_{}",
|
||||
case.packet_size.payload_size(),
|
||||
),
|
||||
|b| {
|
||||
b.iter(|| {
|
||||
make_packet_copy(&sphinx_packet).process(&node_keypair.private_key().into())
|
||||
})
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
criterion_group!(sphinx, bench_loop_packet_create, bench_new_no_surb);
|
||||
criterion_main!(sphinx);
|
||||
@@ -1,11 +1,13 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::ChunkingError;
|
||||
use nymsphinx_params::{SerializedFragmentIdentifier, FRAG_ID_LEN};
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
|
||||
use nymsphinx_params::{FRAG_ID_LEN, SerializedFragmentIdentifier};
|
||||
|
||||
use crate::ChunkingError;
|
||||
|
||||
// Personal reflection: In hindsight I've spent too much time on relatively too little
|
||||
// gain here, as even though I might have saved couple of bytes per packet, the gain
|
||||
// is negligible in the context of having to include SURB-ACKs and reply-SURBs in the packets.
|
||||
@@ -110,8 +112,8 @@ impl FragmentIdentifier {
|
||||
/// header used to reconstruct the message after being received.
|
||||
#[derive(PartialEq, Clone)]
|
||||
pub struct Fragment {
|
||||
header: FragmentHeader,
|
||||
payload: Vec<u8>,
|
||||
pub header: FragmentHeader,
|
||||
pub payload: Vec<u8>,
|
||||
}
|
||||
|
||||
// manual implementation to hide detailed payload that we don't care about
|
||||
@@ -290,7 +292,7 @@ impl Fragment {
|
||||
/// and for the longest messages, without upper bound, there is usually also only 7 bytes
|
||||
/// of overhead apart from first and last fragments in each set that instead have 10 bytes of overhead.
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
pub(crate) struct FragmentHeader {
|
||||
pub struct FragmentHeader {
|
||||
/// ID associated with `FragmentSet` to which this particular `Fragment` belongs.
|
||||
/// Its value is restricted to (0, i32::max_value()].
|
||||
/// Note that it *excludes* 0, but *includes* i32::max_value().
|
||||
@@ -319,7 +321,7 @@ impl FragmentHeader {
|
||||
/// Tries to create a new `FragmentHeader` using provided metadata. Bunch of logical
|
||||
/// checks are performed to see if the data is not self-contradictory,
|
||||
/// for example if current_fragment > total_fragments.
|
||||
fn try_new(
|
||||
pub fn try_new(
|
||||
id: i32,
|
||||
total_fragments: u8,
|
||||
current_fragment: u8,
|
||||
@@ -460,9 +462,11 @@ impl FragmentHeader {
|
||||
|
||||
#[cfg(test)]
|
||||
mod fragment_tests {
|
||||
use super::*;
|
||||
use rand::{RngCore, thread_rng};
|
||||
|
||||
use nymsphinx_params::packet_sizes::PacketSize;
|
||||
use rand::{thread_rng, RngCore};
|
||||
|
||||
use super::*;
|
||||
|
||||
fn max_plaintext_size() -> usize {
|
||||
PacketSize::default().plaintext_size() - PacketSize::AckPacket.size()
|
||||
@@ -585,7 +589,7 @@ mod fragment_tests {
|
||||
None,
|
||||
Some(1234),
|
||||
)
|
||||
.unwrap(),
|
||||
.unwrap(),
|
||||
payload: msg,
|
||||
};
|
||||
let packet_bytes = fragment.clone().into_bytes();
|
||||
@@ -602,7 +606,7 @@ mod fragment_tests {
|
||||
None,
|
||||
Some(1234),
|
||||
)
|
||||
.unwrap(),
|
||||
.unwrap(),
|
||||
payload: msg,
|
||||
};
|
||||
let packet_bytes = fragment.clone().into_bytes();
|
||||
@@ -644,7 +648,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_ok());
|
||||
.is_ok());
|
||||
assert!(Fragment::try_new(
|
||||
&non_full_payload,
|
||||
id,
|
||||
@@ -654,7 +658,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_ok());
|
||||
.is_ok());
|
||||
|
||||
assert!(Fragment::try_new(
|
||||
&non_full_payload2,
|
||||
@@ -665,7 +669,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_ok());
|
||||
.is_ok());
|
||||
assert!(Fragment::try_new(
|
||||
&non_full_payload2,
|
||||
id,
|
||||
@@ -675,7 +679,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_ok());
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -697,7 +701,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
assert!(Fragment::try_new(
|
||||
&non_full_payload,
|
||||
id,
|
||||
@@ -707,7 +711,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
|
||||
assert!(Fragment::try_new(
|
||||
&too_much_payload,
|
||||
@@ -718,7 +722,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
assert!(Fragment::try_new(
|
||||
&too_much_payload,
|
||||
id,
|
||||
@@ -728,7 +732,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
assert!(Fragment::try_new(
|
||||
&too_much_payload,
|
||||
id,
|
||||
@@ -738,7 +742,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
|
||||
assert!(Fragment::try_new(
|
||||
&non_full_payload2,
|
||||
@@ -749,7 +753,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
assert!(Fragment::try_new(
|
||||
&non_full_payload2,
|
||||
id,
|
||||
@@ -759,7 +763,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -780,7 +784,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_ok());
|
||||
.is_ok());
|
||||
assert!(Fragment::try_new(
|
||||
&full_payload,
|
||||
id,
|
||||
@@ -790,7 +794,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_ok());
|
||||
.is_ok());
|
||||
assert!(Fragment::try_new(
|
||||
&non_full_payload,
|
||||
id,
|
||||
@@ -800,7 +804,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_ok());
|
||||
.is_ok());
|
||||
assert!(Fragment::try_new(
|
||||
&non_full_payload2,
|
||||
id,
|
||||
@@ -810,7 +814,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_ok());
|
||||
.is_ok());
|
||||
|
||||
assert!(Fragment::try_new(
|
||||
&full_payload,
|
||||
@@ -821,7 +825,7 @@ mod fragment_tests {
|
||||
Some(link_id),
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_ok());
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -842,7 +846,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
assert!(Fragment::try_new(
|
||||
&non_full_payload2,
|
||||
id,
|
||||
@@ -852,7 +856,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
assert!(Fragment::try_new(
|
||||
&too_much_payload,
|
||||
id,
|
||||
@@ -862,7 +866,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
assert!(Fragment::try_new(
|
||||
&too_much_payload,
|
||||
id,
|
||||
@@ -872,7 +876,7 @@ mod fragment_tests {
|
||||
None,
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
|
||||
assert!(Fragment::try_new(
|
||||
&non_full_payload,
|
||||
@@ -883,7 +887,7 @@ mod fragment_tests {
|
||||
Some(link_id),
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
assert!(Fragment::try_new(
|
||||
&non_full_payload2,
|
||||
id,
|
||||
@@ -893,7 +897,7 @@ mod fragment_tests {
|
||||
Some(link_id),
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
|
||||
assert!(Fragment::try_new(
|
||||
&too_much_payload,
|
||||
@@ -904,7 +908,7 @@ mod fragment_tests {
|
||||
Some(link_id),
|
||||
max_plaintext_size(),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1008,7 +1012,7 @@ mod fragment_header {
|
||||
None,
|
||||
Some(0),
|
||||
)
|
||||
.is_err());
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1066,7 +1070,7 @@ mod fragment_header {
|
||||
None,
|
||||
Some(1234),
|
||||
)
|
||||
.is_ok());
|
||||
.is_ok());
|
||||
assert!(FragmentHeader::try_new(12345, 10, 2, Some(1234), None).is_err());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt::{self, Debug, Display, Formatter};
|
||||
|
||||
use nymsphinx_addressing::nodes::{NymNodeRoutingAddress, NymNodeRoutingAddressError};
|
||||
use nymsphinx_params::{PacketMode, PacketSize};
|
||||
use nymsphinx_types::SphinxPacket;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt::{self, Debug, Display, Formatter};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum MixPacketFormattingError {
|
||||
@@ -46,7 +47,7 @@ impl From<NymNodeRoutingAddressError> for MixPacketFormattingError {
|
||||
|
||||
pub struct MixPacket {
|
||||
next_hop: NymNodeRoutingAddress,
|
||||
sphinx_packet: SphinxPacket,
|
||||
pub sphinx_packet: SphinxPacket,
|
||||
packet_mode: PacketMode,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use rand::{CryptoRng, RngCore};
|
||||
|
||||
use crypto::aes::cipher::{KeyIvInit, StreamCipher};
|
||||
use crypto::asymmetric::encryption;
|
||||
use crypto::shared_key::new_ephemeral_shared_key;
|
||||
@@ -12,7 +14,6 @@ use nymsphinx_chunking::fragment::Fragment;
|
||||
use nymsphinx_params::{
|
||||
PacketEncryptionAlgorithm, PacketHkdfAlgorithm, ReplySurbEncryptionAlgorithm,
|
||||
};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
|
||||
pub struct NymsphinxPayloadBuilder {
|
||||
fragment: Fragment,
|
||||
@@ -27,10 +28,10 @@ impl NymsphinxPayloadBuilder {
|
||||
fn build<C>(
|
||||
self,
|
||||
packet_encryption_key: &CipherKey<C>,
|
||||
variant_data: impl IntoIterator<Item = u8>,
|
||||
variant_data: impl IntoIterator<Item=u8>,
|
||||
) -> NymsphinxPayload
|
||||
where
|
||||
C: StreamCipher + KeyIvInit,
|
||||
where
|
||||
C: StreamCipher + KeyIvInit,
|
||||
{
|
||||
let (_, surb_ack_bytes) = self.surb_ack.prepare_for_sending();
|
||||
|
||||
@@ -68,8 +69,8 @@ impl NymsphinxPayloadBuilder {
|
||||
rng: &mut R,
|
||||
recipient_encryption_key: &encryption::PublicKey,
|
||||
) -> NymsphinxPayload
|
||||
where
|
||||
R: RngCore + CryptoRng,
|
||||
where
|
||||
R: RngCore + CryptoRng,
|
||||
{
|
||||
// create keys for 'payload' encryption
|
||||
let (ephemeral_keypair, shared_key) = new_ephemeral_shared_key::<
|
||||
@@ -88,6 +89,7 @@ impl NymsphinxPayloadBuilder {
|
||||
// the actual byte data that will be put into the sphinx packet paylaod.
|
||||
// no more transformations are going to happen to it
|
||||
// TODO: use that fact for some better compile time assertions
|
||||
#[derive(Clone)]
|
||||
pub struct NymsphinxPayload(Vec<u8>);
|
||||
|
||||
impl AsRef<[u8]> for NymsphinxPayload {
|
||||
|
||||
Reference in New Issue
Block a user