Client tweaks
This commit is contained in:
+2
-1
@@ -42,4 +42,5 @@ storybook-static
|
||||
envs/qwerty.env
|
||||
.parcel-cache
|
||||
**/.DS_Store
|
||||
cpu-cycles/libcpucycles/build
|
||||
cpu-cycles/libcpucycles/build
|
||||
foxyfox.env
|
||||
@@ -91,6 +91,7 @@ impl From<Init> for OverrideConfig {
|
||||
no_cover: init_config.no_cover,
|
||||
nyxd_urls: init_config.nyxd_urls,
|
||||
enabled_credentials_mode: init_config.enabled_credentials_mode,
|
||||
outfox: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ use nym_bin_common::completions::{fig_generate, ArgShell};
|
||||
use nym_config::{NymConfig, OptionalSet};
|
||||
use nym_socks5_client_core::config::old_config_v1_1_13::OldConfigV1_1_13;
|
||||
use nym_socks5_client_core::config::{BaseConfig, Config};
|
||||
use nym_sphinx::params::PacketType;
|
||||
use std::error::Error;
|
||||
|
||||
pub mod init;
|
||||
@@ -64,6 +65,7 @@ pub(crate) struct OverrideConfig {
|
||||
no_cover: bool,
|
||||
nyxd_urls: Option<Vec<url::Url>>,
|
||||
enabled_credentials_mode: Option<bool>,
|
||||
outfox: bool,
|
||||
}
|
||||
|
||||
pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
@@ -80,9 +82,15 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Syn
|
||||
}
|
||||
|
||||
pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
||||
let packet_type = if args.outfox {
|
||||
PacketType::Outfox
|
||||
} else {
|
||||
PacketType::Mix
|
||||
};
|
||||
config
|
||||
.with_base(BaseConfig::with_high_default_traffic_volume, args.fastmode)
|
||||
.with_base(BaseConfig::with_disabled_cover_traffic, args.no_cover)
|
||||
.with_base(BaseConfig::with_packet_type, packet_type)
|
||||
.with_optional(Config::with_anonymous_replies, args.use_anonymous_replies)
|
||||
.with_optional(Config::with_port, args.port)
|
||||
.with_optional_custom_env_ext(
|
||||
|
||||
@@ -68,6 +68,9 @@ pub(crate) struct Run {
|
||||
/// with bandwidth credential requirement.
|
||||
#[clap(long, hide = true)]
|
||||
enabled_credentials_mode: Option<bool>,
|
||||
|
||||
#[clap(long, hide = true, action)]
|
||||
outfox: bool,
|
||||
}
|
||||
|
||||
impl From<Run> for OverrideConfig {
|
||||
@@ -80,6 +83,7 @@ impl From<Run> for OverrideConfig {
|
||||
no_cover: run_config.no_cover,
|
||||
nyxd_urls: run_config.nyxd_urls,
|
||||
enabled_credentials_mode: run_config.enabled_credentials_mode,
|
||||
outfox: run_config.outfox,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,6 +582,7 @@ where
|
||||
topology,
|
||||
&self.config.ack_key,
|
||||
reply_surb,
|
||||
PacketType::Mix,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
@@ -601,7 +602,13 @@ where
|
||||
|
||||
let prepared_fragment = self
|
||||
.message_preparer
|
||||
.prepare_reply_chunk_for_sending(chunk, topology, &self.config.ack_key, reply_surb)
|
||||
.prepare_reply_chunk_for_sending(
|
||||
chunk,
|
||||
topology,
|
||||
&self.config.ack_key,
|
||||
reply_surb,
|
||||
PacketType::Mix,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Ok(prepared_fragment)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
use nym_config::defaults::NymNetworkDetails;
|
||||
use nym_config::{NymConfig, OptionalSet, CRED_DB_FILE_NAME};
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_sphinx::params::PacketSize;
|
||||
use nym_sphinx::params::{PacketSize, PacketType};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::marker::PhantomData;
|
||||
use std::path::{Path, PathBuf};
|
||||
@@ -259,6 +259,11 @@ impl<T> Config<T> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_packet_type(mut self, packet_type: PacketType) -> Self {
|
||||
self.client.packet_type = Some(packet_type);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_high_default_traffic_volume(&mut self) {
|
||||
self.debug.traffic.average_packet_delay = Duration::from_millis(10);
|
||||
// basically don't really send cover messages
|
||||
@@ -446,6 +451,10 @@ impl<T> Config<T> {
|
||||
pub fn get_maximum_reply_key_age(&self) -> Duration {
|
||||
self.debug.reply_surbs.maximum_reply_key_age
|
||||
}
|
||||
|
||||
pub fn get_packet_type(&self) -> PacketType {
|
||||
self.client.packet_type.unwrap_or(PacketType::Mix)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: NymConfig> Default for Config<T> {
|
||||
@@ -568,6 +577,8 @@ pub struct Client<T> {
|
||||
|
||||
#[serde(skip)]
|
||||
pub super_struct: PhantomData<T>,
|
||||
|
||||
pub packet_type: Option<PacketType>,
|
||||
}
|
||||
|
||||
impl<T: NymConfig> Default for Client<T> {
|
||||
@@ -606,6 +617,7 @@ impl<T: NymConfig> Default for Client<T> {
|
||||
reply_surb_database_path: Default::default(),
|
||||
nym_root_directory: T::default_root_directory(),
|
||||
super_struct: Default::default(),
|
||||
packet_type: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,8 +210,8 @@ impl<T, U> From<OldConfigV1_1_13<T>> for Config<U> {
|
||||
database_path: value.client.database_path,
|
||||
reply_surb_database_path: value.client.reply_surb_database_path,
|
||||
nym_root_directory: value.client.nym_root_directory,
|
||||
|
||||
super_struct: PhantomData,
|
||||
packet_type: Some(nym_sphinx::params::PacketType::Mix),
|
||||
},
|
||||
logging: value.logging,
|
||||
debug: value.debug.into(),
|
||||
|
||||
@@ -6,7 +6,7 @@ use nym_crypto::{generic_array::typenum::Unsigned, Digest};
|
||||
use nym_sphinx_addressing::clients::Recipient;
|
||||
use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN};
|
||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||
use nym_sphinx_params::{ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
||||
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
||||
use nym_sphinx_types::{delays, NymPacket, SURBMaterial, SphinxError, SURB};
|
||||
use nym_topology::{NymTopology, NymTopologyError};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
@@ -173,6 +173,7 @@ impl ReplySurb {
|
||||
self,
|
||||
message: M,
|
||||
packet_size: PacketSize,
|
||||
_packet_type: PacketType,
|
||||
) -> Result<(NymPacket, NymNodeRoutingAddress), ReplySurbError> {
|
||||
let message_bytes = message.as_ref();
|
||||
if message_bytes.len() != packet_size.plaintext_size() {
|
||||
|
||||
@@ -148,7 +148,13 @@ mod packet_encoding {
|
||||
node3_pk,
|
||||
);
|
||||
|
||||
let route = &[node1, node2, node3];
|
||||
let (_, node4_pk) = crypto::keygen();
|
||||
let node4 = Node::new(
|
||||
NodeAddressBytes::from_bytes([2u8; NODE_ADDRESS_LENGTH]),
|
||||
node4_pk,
|
||||
);
|
||||
|
||||
let route = &[node1, node2, node3, node4];
|
||||
|
||||
let payload = vec![1; 48];
|
||||
|
||||
|
||||
@@ -287,7 +287,10 @@ impl PacketSize {
|
||||
let outfox_packet_size = plaintext_size + OUTFOX_PACKET_OVERHEAD;
|
||||
match Self::get_type(sphinx_packet_size) {
|
||||
Ok(t) => Ok(t),
|
||||
Err(_) => Self::get_type(outfox_packet_size),
|
||||
Err(_) => {
|
||||
println!("Got Outfox!");
|
||||
Self::get_type(outfox_packet_size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,4 +21,4 @@ pub use nym_sphinx_types::*;
|
||||
pub use nym_sphinx_framing as framing;
|
||||
|
||||
// TEMP UNTIL FURTHER REFACTORING
|
||||
pub use preparer::payload::NymsphinxPayloadBuilder;
|
||||
pub use preparer::payload::NymPayloadBuilder;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::message::{NymMessage, ACK_OVERHEAD};
|
||||
use crate::NymsphinxPayloadBuilder;
|
||||
use crate::NymPayloadBuilder;
|
||||
use nym_crypto::asymmetric::encryption;
|
||||
use nym_crypto::Digest;
|
||||
use nym_outfox::packet::OutfoxPacket;
|
||||
@@ -108,6 +108,7 @@ pub trait FragmentPreparer {
|
||||
ack_key: &AckKey,
|
||||
reply_surb: ReplySurb,
|
||||
packet_sender: &Recipient,
|
||||
packet_type: PacketType,
|
||||
) -> Result<PreparedFragment, NymTopologyError> {
|
||||
// each reply attaches the digest of the encryption key so that the recipient could
|
||||
// lookup correct key for decryption,
|
||||
@@ -131,7 +132,7 @@ pub trait FragmentPreparer {
|
||||
self.generate_surb_ack(packet_sender, fragment_identifier, topology, ack_key)?;
|
||||
let ack_delay = surb_ack.expected_total_delay();
|
||||
|
||||
let packet_payload = match NymsphinxPayloadBuilder::new(fragment, surb_ack)
|
||||
let packet_payload = match NymPayloadBuilder::new(fragment, surb_ack)
|
||||
.build_reply(reply_surb.encryption_key())
|
||||
{
|
||||
Ok(payload) => payload,
|
||||
@@ -140,8 +141,9 @@ pub trait FragmentPreparer {
|
||||
|
||||
// the unwrap here is fine as the failures can only originate from attempting to use invalid payload lengths
|
||||
// and we just very carefully constructed a (presumably) valid one
|
||||
let (sphinx_packet, first_hop_address) =
|
||||
reply_surb.apply_surb(packet_payload, packet_size).unwrap();
|
||||
let (sphinx_packet, first_hop_address) = reply_surb
|
||||
.apply_surb(packet_payload, packet_size, packet_type)
|
||||
.unwrap();
|
||||
|
||||
Ok(PreparedFragment {
|
||||
// the round-trip delay is the sum of delays of all hops on the forward route as
|
||||
@@ -197,7 +199,7 @@ pub trait FragmentPreparer {
|
||||
self.generate_surb_ack(packet_sender, fragment_identifier, topology, ack_key)?;
|
||||
let ack_delay = surb_ack.expected_total_delay();
|
||||
|
||||
let packet_payload = match NymsphinxPayloadBuilder::new(fragment, surb_ack)
|
||||
let packet_payload = match NymPayloadBuilder::new(fragment, surb_ack)
|
||||
.build_regular(self.rng(), packet_recipient.encryption_key())
|
||||
{
|
||||
Ok(payload) => payload,
|
||||
@@ -222,12 +224,12 @@ pub trait FragmentPreparer {
|
||||
route.as_slice().try_into()?,
|
||||
Some(packet_size.payload_size()),
|
||||
)?),
|
||||
PacketType::Mix => NymPacket::Sphinx(
|
||||
PacketType::Mix => NymPacket::Sphinx({
|
||||
SphinxPacketBuilder::new()
|
||||
.with_payload_size(packet_size.payload_size())
|
||||
.build_packet(packet_payload, &route, &destination, &delays)
|
||||
.unwrap(),
|
||||
),
|
||||
.unwrap()
|
||||
}),
|
||||
PacketType::Vpn => NymPacket::Sphinx(
|
||||
SphinxPacketBuilder::new()
|
||||
.with_payload_size(packet_size.payload_size())
|
||||
@@ -342,11 +344,18 @@ where
|
||||
topology: &NymTopology,
|
||||
ack_key: &AckKey,
|
||||
reply_surb: ReplySurb,
|
||||
packet_type: PacketType,
|
||||
) -> Result<PreparedFragment, NymTopologyError> {
|
||||
let sender = self.sender_address;
|
||||
|
||||
<Self as FragmentPreparer>::prepare_reply_chunk_for_sending(
|
||||
self, fragment, topology, ack_key, reply_surb, &sender,
|
||||
self,
|
||||
fragment,
|
||||
topology,
|
||||
ack_key,
|
||||
reply_surb,
|
||||
&sender,
|
||||
packet_type,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,21 +14,21 @@ use nym_sphinx_params::{
|
||||
};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
|
||||
pub struct NymsphinxPayloadBuilder {
|
||||
pub struct NymPayloadBuilder {
|
||||
fragment: Fragment,
|
||||
surb_ack: SurbAck,
|
||||
}
|
||||
|
||||
impl NymsphinxPayloadBuilder {
|
||||
impl NymPayloadBuilder {
|
||||
pub fn new(fragment: Fragment, surb_ack: SurbAck) -> Self {
|
||||
NymsphinxPayloadBuilder { fragment, surb_ack }
|
||||
NymPayloadBuilder { fragment, surb_ack }
|
||||
}
|
||||
|
||||
fn build<C>(
|
||||
self,
|
||||
packet_encryption_key: &CipherKey<C>,
|
||||
variant_data: impl IntoIterator<Item = u8>,
|
||||
) -> Result<NymsphinxPayload, SurbAckRecoveryError>
|
||||
) -> Result<NymPayload, SurbAckRecoveryError>
|
||||
where
|
||||
C: StreamCipher + KeyIvInit,
|
||||
{
|
||||
@@ -46,7 +46,7 @@ impl NymsphinxPayloadBuilder {
|
||||
// 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(NymsphinxPayload(
|
||||
Ok(NymPayload(
|
||||
surb_ack_bytes
|
||||
.into_iter()
|
||||
.chain(variant_data.into_iter())
|
||||
@@ -58,7 +58,7 @@ impl NymsphinxPayloadBuilder {
|
||||
pub fn build_reply(
|
||||
self,
|
||||
packet_encryption_key: &SurbEncryptionKey,
|
||||
) -> Result<NymsphinxPayload, SurbAckRecoveryError> {
|
||||
) -> Result<NymPayload, SurbAckRecoveryError> {
|
||||
let key_digest = packet_encryption_key.compute_digest();
|
||||
self.build::<ReplySurbEncryptionAlgorithm>(
|
||||
packet_encryption_key.inner(),
|
||||
@@ -70,7 +70,7 @@ impl NymsphinxPayloadBuilder {
|
||||
self,
|
||||
rng: &mut R,
|
||||
recipient_encryption_key: &encryption::PublicKey,
|
||||
) -> Result<NymsphinxPayload, SurbAckRecoveryError>
|
||||
) -> Result<NymPayload, SurbAckRecoveryError>
|
||||
where
|
||||
R: RngCore + CryptoRng,
|
||||
{
|
||||
@@ -91,9 +91,9 @@ 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
|
||||
pub struct NymsphinxPayload(Vec<u8>);
|
||||
pub struct NymPayload(Vec<u8>);
|
||||
|
||||
impl AsRef<[u8]> for NymsphinxPayload {
|
||||
impl AsRef<[u8]> for NymPayload {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub use nym_outfox::{error::OutfoxError, format::MIX_PARAMS_LEN, packet::OUTFOX_PACKET_OVERHEAD};
|
||||
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;
|
||||
pub use sphinx_packet::{
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::config::{Config, Socks5};
|
||||
use crate::error::Socks5ClientCoreError;
|
||||
use crate::socks::{
|
||||
authentication::{AuthenticationMethods, Authenticator, User},
|
||||
server::SphinxSocksServer,
|
||||
server::NymSocksServer,
|
||||
};
|
||||
use futures::channel::mpsc;
|
||||
use futures::StreamExt;
|
||||
@@ -19,6 +19,7 @@ use nym_client_core::client::replies::reply_storage::ReplyStorageBackend;
|
||||
use nym_client_core::config::DebugConfig;
|
||||
use nym_credential_storage::storage::Storage as CredentialStorage;
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
use nym_sphinx::params::PacketType;
|
||||
use nym_task::{TaskClient, TaskManager};
|
||||
use std::error::Error;
|
||||
|
||||
@@ -64,6 +65,7 @@ where
|
||||
NymClient { config, storage }
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn start_socks5_listener(
|
||||
socks5_config: &Socks5,
|
||||
debug_config: DebugConfig,
|
||||
@@ -72,6 +74,7 @@ where
|
||||
client_status: ClientState,
|
||||
self_address: Recipient,
|
||||
shutdown: TaskClient,
|
||||
packet_type: PacketType,
|
||||
) {
|
||||
info!("Starting socks5 listener...");
|
||||
let auth_methods = vec![AuthenticationMethods::NoAuth as u8];
|
||||
@@ -97,7 +100,7 @@ where
|
||||
.unwrap_or(debug_config.traffic.primary_packet_size);
|
||||
|
||||
let authenticator = Authenticator::new(auth_methods, allowed_users);
|
||||
let mut sphinx_socks = SphinxSocksServer::new(
|
||||
let mut sphinx_socks = NymSocksServer::new(
|
||||
socks5_config.get_listening_port(),
|
||||
authenticator,
|
||||
socks5_config.get_provider_mix_address(),
|
||||
@@ -112,6 +115,7 @@ where
|
||||
socks5_config.get_per_request_surbs(),
|
||||
),
|
||||
shutdown.clone(),
|
||||
packet_type,
|
||||
);
|
||||
nym_task::spawn_with_report_error(
|
||||
async move {
|
||||
@@ -209,6 +213,8 @@ where
|
||||
let client_output = started_client.client_output.register_consumer();
|
||||
let client_state = started_client.client_state;
|
||||
|
||||
info!("{:?}", self.config.get_base().get_packet_type());
|
||||
|
||||
Self::start_socks5_listener(
|
||||
self.config.get_socks5(),
|
||||
*self.config.get_debug_settings(),
|
||||
@@ -217,6 +223,7 @@ where
|
||||
client_state,
|
||||
self_address,
|
||||
started_client.task_manager.subscribe(),
|
||||
self.config.get_base().get_packet_type(),
|
||||
);
|
||||
|
||||
info!("Client startup finished!");
|
||||
|
||||
@@ -10,6 +10,7 @@ use nym_client_core::client::{
|
||||
};
|
||||
use nym_socks5_proxy_helpers::connection_controller::Controller;
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
use nym_sphinx::params::PacketType;
|
||||
use nym_task::connections::{ConnectionCommandSender, LaneQueueLengths};
|
||||
use nym_task::TaskClient;
|
||||
use std::net::SocketAddr;
|
||||
@@ -17,7 +18,7 @@ use tap::TapFallible;
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
/// A Socks5 server that listens for connections.
|
||||
pub struct SphinxSocksServer {
|
||||
pub struct NymSocksServer {
|
||||
authenticator: Authenticator,
|
||||
listening_address: SocketAddr,
|
||||
service_provider: Recipient,
|
||||
@@ -25,10 +26,12 @@ pub struct SphinxSocksServer {
|
||||
client_config: client::Config,
|
||||
lane_queue_lengths: LaneQueueLengths,
|
||||
shutdown: TaskClient,
|
||||
packet_type: PacketType,
|
||||
}
|
||||
|
||||
impl SphinxSocksServer {
|
||||
impl NymSocksServer {
|
||||
/// Create a new SphinxSocks instance
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn new(
|
||||
port: u16,
|
||||
authenticator: Authenticator,
|
||||
@@ -37,12 +40,13 @@ impl SphinxSocksServer {
|
||||
lane_queue_lengths: LaneQueueLengths,
|
||||
client_config: client::Config,
|
||||
shutdown: TaskClient,
|
||||
packet_type: PacketType,
|
||||
) -> Self {
|
||||
// hardcode ip as we (presumably) ONLY want to listen locally. If we change it, we can
|
||||
// just modify the config
|
||||
let ip = "127.0.0.1";
|
||||
info!("Listening on {}:{}", ip, port);
|
||||
SphinxSocksServer {
|
||||
NymSocksServer {
|
||||
authenticator,
|
||||
listening_address: format!("{ip}:{port}").parse().unwrap(),
|
||||
service_provider,
|
||||
@@ -50,6 +54,7 @@ impl SphinxSocksServer {
|
||||
client_config,
|
||||
lane_queue_lengths,
|
||||
shutdown,
|
||||
packet_type,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +109,7 @@ impl SphinxSocksServer {
|
||||
&self.self_address,
|
||||
self.lane_queue_lengths.clone(),
|
||||
self.shutdown.clone(),
|
||||
None
|
||||
Some(self.packet_type)
|
||||
);
|
||||
|
||||
tokio::spawn(async move {
|
||||
@@ -120,8 +125,8 @@ impl SphinxSocksServer {
|
||||
});
|
||||
},
|
||||
_ = self.shutdown.recv() => {
|
||||
log::trace!("SphinxSocksServer: Received shutdown");
|
||||
log::debug!("SphinxSocksServer: Exiting");
|
||||
log::trace!("NymSocksServer: Received shutdown");
|
||||
log::debug!("NymSocksServer: Exiting");
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
pub const GROUPELEMENTBYTES: u8 = 32;
|
||||
pub const TAGBYTES: u8 = 16;
|
||||
pub const MIX_PARAMS_LEN: usize = 6;
|
||||
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 OUTFOX_PACKET_OVERHEAD: usize = MIX_PARAMS_LEN
|
||||
+ (groupelementbytes() + tagbytes() + DEFAULT_ROUTING_INFO_SIZE as usize) * DEFAULT_HOPS;
|
||||
|
||||
pub const fn groupelementbytes() -> usize {
|
||||
GROUPELEMENTBYTES as usize
|
||||
}
|
||||
|
||||
pub const fn tagbytes() -> usize {
|
||||
TAGBYTES as usize
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::array::TryFromSliceError;
|
||||
|
||||
use crate::format::MIX_PARAMS_LEN;
|
||||
use crate::lion::MIN_MESSAGE_LEN;
|
||||
use crate::constants::MIN_MESSAGE_LEN;
|
||||
use crate::constants::MIX_PARAMS_LEN;
|
||||
use chacha20::cipher::InvalidLength;
|
||||
use thiserror::Error;
|
||||
|
||||
|
||||
+13
-19
@@ -66,24 +66,18 @@ use sphinx_packet::route::Node;
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
||||
pub const GROUPELEMENTBYTES: u8 = 32;
|
||||
pub const TAGBYTES: u8 = 16;
|
||||
pub const MIX_PARAMS_LEN: usize = 5;
|
||||
|
||||
pub const fn groupelementbytes() -> usize {
|
||||
GROUPELEMENTBYTES as usize
|
||||
}
|
||||
|
||||
pub const fn tagbytes() -> usize {
|
||||
TAGBYTES as usize
|
||||
}
|
||||
|
||||
use std::ops::Range;
|
||||
use std::u8;
|
||||
|
||||
use crate::constants::groupelementbytes;
|
||||
use crate::constants::tagbytes;
|
||||
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::TAGBYTES;
|
||||
use crate::error::OutfoxError;
|
||||
use crate::lion::*;
|
||||
use crate::packet::DEFAULT_ROUTING_INFO_SIZE;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
/// A structure that holds mix packet construction parameters. These incluse the length
|
||||
@@ -91,8 +85,8 @@ use std::convert::TryFrom;
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
pub struct MixCreationParameters {
|
||||
/// The routing length is inner first, so \[0\] is the innermost routing length, etc (in bytes)
|
||||
/// In our stratified topology this will always be 3
|
||||
pub routing_information_length_by_stage: [u8; 4],
|
||||
/// In our stratified topology this will always be 4
|
||||
pub routing_information_length_by_stage: [u8; DEFAULT_HOPS],
|
||||
/// The payload length (in bytes)
|
||||
pub payload_length_bytes: u16,
|
||||
}
|
||||
@@ -104,7 +98,7 @@ impl TryFrom<&[u8]> for MixCreationParameters {
|
||||
if v.len() != MIX_PARAMS_LEN {
|
||||
return Err(OutfoxError::InvalidHeaderLength(v.len()));
|
||||
}
|
||||
let (routing, payload) = v.split_at(3);
|
||||
let (routing, payload) = v.split_at(DEFAULT_HOPS);
|
||||
Ok(MixCreationParameters {
|
||||
routing_information_length_by_stage: routing.try_into()?,
|
||||
payload_length_bytes: u16::from_le_bytes(payload.try_into()?),
|
||||
@@ -127,7 +121,7 @@ impl MixCreationParameters {
|
||||
/// Create a set of parameters for a mix packet format.
|
||||
pub fn new(payload_length_bytes: u16) -> MixCreationParameters {
|
||||
MixCreationParameters {
|
||||
routing_information_length_by_stage: [DEFAULT_ROUTING_INFO_SIZE; 4],
|
||||
routing_information_length_by_stage: [DEFAULT_ROUTING_INFO_SIZE; DEFAULT_HOPS],
|
||||
payload_length_bytes,
|
||||
}
|
||||
}
|
||||
@@ -332,12 +326,12 @@ mod test {
|
||||
#[test]
|
||||
fn test_to_bytes() {
|
||||
let mix_params = MixCreationParameters::new(1024);
|
||||
assert_eq!(mix_params.to_bytes(), vec![32, 32, 32, 0, 4])
|
||||
assert_eq!(mix_params.to_bytes(), vec![32, 32, 32, 32, 0, 4])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_bytes() {
|
||||
let params_bytes = vec![32, 32, 32, 0, 4];
|
||||
let params_bytes = vec![32, 32, 32, 32, 0, 4];
|
||||
let mix_params = MixCreationParameters::new(1024);
|
||||
assert_eq!(
|
||||
mix_params,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod constants;
|
||||
pub mod error;
|
||||
pub mod format;
|
||||
pub mod lion;
|
||||
|
||||
@@ -36,12 +36,9 @@ use chacha20::XChaCha20;
|
||||
use chacha20::XNonce;
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use crate::constants::{CONTEXT, MIN_MESSAGE_LEN, TAG_LEN};
|
||||
use crate::error::OutfoxError;
|
||||
|
||||
pub const MIN_MESSAGE_LEN: usize = 24 * 2;
|
||||
const CONTEXT: &str = "LIONKEYS";
|
||||
const TAG_LEN: usize = 24;
|
||||
|
||||
/// The lion transform encryption function.
|
||||
///
|
||||
/// The `key` must be 32 bytes, and the `message` >= 48. The message is
|
||||
|
||||
@@ -1,26 +1,20 @@
|
||||
use std::{convert::TryFrom, ops::Range};
|
||||
|
||||
use crate::{
|
||||
constants::{DEFAULT_HOPS, MIX_PARAMS_LEN},
|
||||
error::OutfoxError,
|
||||
format::{
|
||||
groupelementbytes, tagbytes, MixCreationParameters, MixStageParameters, MIX_PARAMS_LEN,
|
||||
},
|
||||
format::{MixCreationParameters, MixStageParameters},
|
||||
};
|
||||
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
use sphinx_packet::{packet::builder::DEFAULT_PAYLOAD_SIZE, route::Node};
|
||||
|
||||
pub const OUTFOX_PACKET_OVERHEAD: usize =
|
||||
MIX_PARAMS_LEN + (groupelementbytes() + tagbytes() + DEFAULT_ROUTING_INFO_SIZE as usize) * 3;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OutfoxPacket {
|
||||
mix_params: MixCreationParameters,
|
||||
payload: Vec<u8>,
|
||||
}
|
||||
|
||||
pub const DEFAULT_ROUTING_INFO_SIZE: u8 = 32;
|
||||
|
||||
impl TryFrom<&[u8]> for OutfoxPacket {
|
||||
type Error = OutfoxError;
|
||||
|
||||
@@ -87,7 +81,7 @@ impl OutfoxPacket {
|
||||
}
|
||||
|
||||
pub fn payload_range(&self) -> Range<usize> {
|
||||
self.stage_params(2).1.payload_range()
|
||||
self.stage_params(DEFAULT_HOPS - 1).1.payload_range()
|
||||
}
|
||||
|
||||
pub fn payload_mut(&mut self) -> &mut [u8] {
|
||||
|
||||
@@ -97,7 +97,13 @@ mod tests {
|
||||
node3_pub,
|
||||
);
|
||||
|
||||
let route = [node1, node2, node3];
|
||||
let (node4_pk, node4_pub) = sphinx_packet::crypto::keygen();
|
||||
let node4 = Node::new(
|
||||
NodeAddressBytes::from_bytes([3u8; NODE_ADDRESS_LENGTH]),
|
||||
node4_pub,
|
||||
);
|
||||
|
||||
let route = [node1, node2, node3, node4];
|
||||
|
||||
let payload = randombytes(2048);
|
||||
|
||||
@@ -111,9 +117,10 @@ mod tests {
|
||||
|
||||
let mut packet = OutfoxPacket::try_from(packet_bytes.as_slice()).unwrap();
|
||||
|
||||
packet.decode_mix_layer(2, &node1_pk.to_bytes()).unwrap();
|
||||
packet.decode_mix_layer(1, &node2_pk.to_bytes()).unwrap();
|
||||
packet.decode_mix_layer(0, &node3_pk.to_bytes()).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();
|
||||
|
||||
assert_eq!(payload, &packet.payload()[packet.payload_range()]);
|
||||
}
|
||||
|
||||
@@ -509,6 +509,7 @@ where
|
||||
.clone()
|
||||
.ok_or(Error::Socks5Config { set: false })?;
|
||||
let debug_config = self.config.debug_config;
|
||||
let packet_type = self.config.packet_type();
|
||||
let (mut started_client, nym_address) = self.connect_to_mixnet_common().await?;
|
||||
let (socks5_status_tx, mut socks5_status_rx) = mpsc::channel(128);
|
||||
|
||||
@@ -524,6 +525,7 @@ where
|
||||
client_state.clone(),
|
||||
nym_address,
|
||||
started_client.task_manager.subscribe(),
|
||||
packet_type,
|
||||
);
|
||||
started_client
|
||||
.task_manager
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use nym_client_core::config::DebugConfig;
|
||||
use nym_network_defaults::NymNetworkDetails;
|
||||
use nym_sphinx::params::PacketType;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub enum KeyMode {
|
||||
@@ -34,4 +35,12 @@ pub struct Config {
|
||||
/// Flags controlling all sorts of internal client behaviour.
|
||||
/// Changing these risk compromising network anonymity!
|
||||
pub debug_config: DebugConfig,
|
||||
|
||||
pub packet_type: PacketType,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn packet_type(&self) -> PacketType {
|
||||
self.packet_type
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user