Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7915e05021 | |||
| dfc12b1aaa | |||
| 5ed97fb3c9 |
Generated
+306
-349
File diff suppressed because it is too large
Load Diff
@@ -169,7 +169,7 @@ impl Client {
|
|||||||
|
|
||||||
pub async fn get_active_mixnodes(&self) -> Result<Vec<MixNodeDetails>, NymAPIError> {
|
pub async fn get_active_mixnodes(&self) -> Result<Vec<MixNodeDetails>, NymAPIError> {
|
||||||
self.query_nym_api(
|
self.query_nym_api(
|
||||||
&[routes::API_VERSION, routes::MIXNODES, routes::ACTIVE],
|
&[routes::API_VERSION, routes::MIXNODES],
|
||||||
NO_PARAMS,
|
NO_PARAMS,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use nym_sphinx_types::{
|
||||||
|
SharedSecret, RoutingKeys
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct KeyStorage(Arc<Mutex<HashMap<SharedSecret, (RoutingKeys, Option<SharedSecret>)>>>);
|
||||||
|
|
||||||
|
impl KeyStorage {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
KeyStorage(Arc::new(Mutex::new(
|
||||||
|
HashMap::new()
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn lookup(&self, key : SharedSecret) -> Option<(RoutingKeys, Option<SharedSecret>)> {
|
||||||
|
match self.0.lock() {
|
||||||
|
Ok(map) => map.get(&key).cloned(),
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn store(&self, key : SharedSecret, routing_key : RoutingKeys, blinded_shared_secret : Option<SharedSecret>) {
|
||||||
|
match self.0.lock() {
|
||||||
|
Ok(mut map) => map.insert(key, (routing_key, blinded_shared_secret)),
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3,3 +3,4 @@
|
|||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod processor;
|
pub mod processor;
|
||||||
|
mod key_storage;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
use crate::measure;
|
use crate::measure;
|
||||||
use crate::packet_processor::error::MixProcessingError;
|
use crate::packet_processor::error::MixProcessingError;
|
||||||
|
use crate::packet_processor::key_storage::KeyStorage;
|
||||||
use log::*;
|
use log::*;
|
||||||
use nym_sphinx_acknowledgements::surb_ack::SurbAck;
|
use nym_sphinx_acknowledgements::surb_ack::SurbAck;
|
||||||
use nym_sphinx_addressing::nodes::NymNodeRoutingAddress;
|
use nym_sphinx_addressing::nodes::NymNodeRoutingAddress;
|
||||||
@@ -11,7 +12,7 @@ use nym_sphinx_framing::packet::FramedSphinxPacket;
|
|||||||
use nym_sphinx_params::{PacketMode, PacketSize};
|
use nym_sphinx_params::{PacketMode, PacketSize};
|
||||||
use nym_sphinx_types::{
|
use nym_sphinx_types::{
|
||||||
Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, Payload, PrivateKey,
|
Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, Payload, PrivateKey,
|
||||||
ProcessedPacket, SphinxPacket,
|
ProcessedPacket, RoutingKeys, SharedSecret, SphinxPacket,
|
||||||
};
|
};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -38,6 +39,7 @@ pub enum MixProcessingResult {
|
|||||||
pub struct SphinxPacketProcessor {
|
pub struct SphinxPacketProcessor {
|
||||||
/// Private sphinx key of this node required to unwrap received sphinx packet.
|
/// Private sphinx key of this node required to unwrap received sphinx packet.
|
||||||
sphinx_key: Arc<PrivateKey>,
|
sphinx_key: Arc<PrivateKey>,
|
||||||
|
key_storage: KeyStorage,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SphinxPacketProcessor {
|
impl SphinxPacketProcessor {
|
||||||
@@ -45,6 +47,7 @@ impl SphinxPacketProcessor {
|
|||||||
pub fn new(sphinx_key: PrivateKey) -> Self {
|
pub fn new(sphinx_key: PrivateKey) -> Self {
|
||||||
SphinxPacketProcessor {
|
SphinxPacketProcessor {
|
||||||
sphinx_key: Arc::new(sphinx_key),
|
sphinx_key: Arc::new(sphinx_key),
|
||||||
|
key_storage: KeyStorage::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,6 +68,27 @@ impl SphinxPacketProcessor {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Performs a sphinx unwrapping using given keys.
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "cpucycles",
|
||||||
|
instrument(skip(self, packet), fields(cpucycles))
|
||||||
|
)]
|
||||||
|
fn perform_initial_sphinx_packet_processing_with_keys(
|
||||||
|
&self,
|
||||||
|
packet: SphinxPacket,
|
||||||
|
new_blinded_secret: &Option<SharedSecret>,
|
||||||
|
routing_keys: RoutingKeys,
|
||||||
|
) -> Result<ProcessedPacket, MixProcessingError> {
|
||||||
|
measure!({
|
||||||
|
packet
|
||||||
|
.process_with_derived_keys(new_blinded_secret, routing_keys)
|
||||||
|
.map_err(|err| {
|
||||||
|
debug!("Failed to unwrap Sphinx packet: {err}");
|
||||||
|
MixProcessingError::SphinxProcessingError(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Takes the received framed packet and tries to unwrap it from the sphinx encryption.
|
/// Takes the received framed packet and tries to unwrap it from the sphinx encryption.
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "cpucycles",
|
feature = "cpucycles",
|
||||||
@@ -81,8 +105,28 @@ impl SphinxPacketProcessor {
|
|||||||
if packet_mode.is_old_vpn() {
|
if packet_mode.is_old_vpn() {
|
||||||
return Err(MixProcessingError::ReceivedOldTypeVpnPacket);
|
return Err(MixProcessingError::ReceivedOldTypeVpnPacket);
|
||||||
}
|
}
|
||||||
|
//here be shared secret retrieval and hashmap lookup
|
||||||
self.perform_initial_sphinx_packet_processing(sphinx_packet)
|
if let Some((routing_keys, blinded_shared_secret)) =
|
||||||
|
self.key_storage.lookup(sphinx_packet.shared_secret())
|
||||||
|
{
|
||||||
|
trace!("Packet already seen, reusing keys");
|
||||||
|
self.perform_initial_sphinx_packet_processing_with_keys(
|
||||||
|
sphinx_packet,
|
||||||
|
&blinded_shared_secret,
|
||||||
|
routing_keys,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
trace!("New packet, deriving keys and storing them");
|
||||||
|
let key_secret = sphinx_packet.shared_secret();
|
||||||
|
let processed_packet =
|
||||||
|
self.perform_initial_sphinx_packet_processing(sphinx_packet)?;
|
||||||
|
self.key_storage.store(
|
||||||
|
key_secret,
|
||||||
|
processed_packet.routing_keys(),
|
||||||
|
processed_packet.shared_secret(),
|
||||||
|
);
|
||||||
|
Ok(processed_packet)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,12 +219,12 @@ impl SphinxPacketProcessor {
|
|||||||
packet_mode: PacketMode,
|
packet_mode: PacketMode,
|
||||||
) -> Result<MixProcessingResult, MixProcessingError> {
|
) -> Result<MixProcessingResult, MixProcessingError> {
|
||||||
match packet {
|
match packet {
|
||||||
ProcessedPacket::ForwardHop(packet, address, delay) => {
|
ProcessedPacket::ForwardHop(packet, address, delay, _) => {
|
||||||
self.process_forward_hop(*packet, address, delay, packet_mode)
|
self.process_forward_hop(*packet, address, delay, packet_mode)
|
||||||
}
|
}
|
||||||
// right now there's no use for the surb_id included in the header - probably it should get removed from the
|
// right now there's no use for the surb_id included in the header - probably it should get removed from the
|
||||||
// sphinx all together?
|
// sphinx all together?
|
||||||
ProcessedPacket::FinalHop(destination, _, payload) => {
|
ProcessedPacket::FinalHop(destination, _, payload, _) => {
|
||||||
self.process_final_hop(destination, payload, packet_size, packet_mode)
|
self.process_final_hop(destination, payload, packet_size, packet_mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ impl SurbAck {
|
|||||||
|
|
||||||
let surb_ack_packet = SphinxPacketBuilder::new()
|
let surb_ack_packet = SphinxPacketBuilder::new()
|
||||||
.with_payload_size(PacketSize::AckPacket.payload_size())
|
.with_payload_size(PacketSize::AckPacket.payload_size())
|
||||||
|
.with_initial_secret(&[42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42].into())
|
||||||
.build_packet(surb_ack_payload, &route, &destination, &delays)
|
.build_packet(surb_ack_payload, &route, &destination, &delays)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ where
|
|||||||
// once merged, that's an easy rng injection point for sphinx packets : )
|
// once merged, that's an easy rng injection point for sphinx packets : )
|
||||||
let packet = SphinxPacketBuilder::new()
|
let packet = SphinxPacketBuilder::new()
|
||||||
.with_payload_size(packet_size.payload_size())
|
.with_payload_size(packet_size.payload_size())
|
||||||
|
.with_initial_secret(&[42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42].into())
|
||||||
.build_packet(packet_payload, &route, &destination, &delays)
|
.build_packet(packet_payload, &route, &destination, &delays)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ pub trait FragmentPreparer {
|
|||||||
// there's absolutely no reason for this call to fail.
|
// there's absolutely no reason for this call to fail.
|
||||||
let sphinx_packet = SphinxPacketBuilder::new()
|
let sphinx_packet = SphinxPacketBuilder::new()
|
||||||
.with_payload_size(packet_size.payload_size())
|
.with_payload_size(packet_size.payload_size())
|
||||||
|
.with_initial_secret(&[42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42].into())
|
||||||
.build_packet(packet_payload, &route, &destination, &delays)
|
.build_packet(packet_payload, &route, &destination, &delays)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ license = { workspace = true }
|
|||||||
repository = { workspace = true }
|
repository = { workspace = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sphinx-packet = { version = "0.1.0" }
|
#sphinx-packet = { version = "0.1.0" }
|
||||||
|
sphinx-packet = { git = "https://github.com/nymtech/sphinx.git", branch = "simon/key-reuse"}
|
||||||
|
|
||||||
#[patch.crates-io]
|
#[patch.crates-io]
|
||||||
#sphinx-packet = { path = "../../../../sphinx" }
|
#sphinx-packet = { path = "../../../../sphinx" }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ pub use sphinx_packet::{
|
|||||||
PAYLOAD_KEY_SIZE,
|
PAYLOAD_KEY_SIZE,
|
||||||
},
|
},
|
||||||
crypto::{self, EphemeralSecret, PrivateKey, PublicKey, SharedSecret},
|
crypto::{self, EphemeralSecret, PrivateKey, PublicKey, SharedSecret},
|
||||||
header::{self, delays, delays::Delay, ProcessedHeader, SphinxHeader, HEADER_SIZE},
|
header::{self, delays, delays::Delay, ProcessedHeader, SphinxHeader, HEADER_SIZE, keys::RoutingKeys},
|
||||||
packet::builder::{self, DEFAULT_PAYLOAD_SIZE},
|
packet::builder::{self, DEFAULT_PAYLOAD_SIZE},
|
||||||
payload::{Payload, PAYLOAD_OVERHEAD_SIZE},
|
payload::{Payload, PAYLOAD_OVERHEAD_SIZE},
|
||||||
route::{Destination, DestinationAddressBytes, Node, NodeAddressBytes, SURBIdentifier},
|
route::{Destination, DestinationAddressBytes, Node, NodeAddressBytes, SURBIdentifier},
|
||||||
|
|||||||
Reference in New Issue
Block a user