Compare commits

...

3 Commits

Author SHA1 Message Date
Simon Wicky 7915e05021 change log level for key storage 2023-06-05 13:34:25 +02:00
Simon Wicky dfc12b1aaa freeze secret for packet gen 2023-05-30 14:44:39 +00:00
Simon Wicky 5ed97fb3c9 add rey reuse 2023-05-30 13:50:10 +00:00
10 changed files with 401 additions and 357 deletions
Generated
+306 -349
View File
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> {
self.query_nym_api(
&[routes::API_VERSION, routes::MIXNODES, routes::ACTIVE],
&[routes::API_VERSION, routes::MIXNODES],
NO_PARAMS,
)
.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 processor;
mod key_storage;
@@ -3,6 +3,7 @@
use crate::measure;
use crate::packet_processor::error::MixProcessingError;
use crate::packet_processor::key_storage::KeyStorage;
use log::*;
use nym_sphinx_acknowledgements::surb_ack::SurbAck;
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_types::{
Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, Payload, PrivateKey,
ProcessedPacket, SphinxPacket,
ProcessedPacket, RoutingKeys, SharedSecret, SphinxPacket,
};
use std::convert::TryFrom;
use std::sync::Arc;
@@ -38,6 +39,7 @@ pub enum MixProcessingResult {
pub struct SphinxPacketProcessor {
/// Private sphinx key of this node required to unwrap received sphinx packet.
sphinx_key: Arc<PrivateKey>,
key_storage: KeyStorage,
}
impl SphinxPacketProcessor {
@@ -45,6 +47,7 @@ impl SphinxPacketProcessor {
pub fn new(sphinx_key: PrivateKey) -> Self {
SphinxPacketProcessor {
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.
#[cfg_attr(
feature = "cpucycles",
@@ -81,8 +105,28 @@ impl SphinxPacketProcessor {
if packet_mode.is_old_vpn() {
return Err(MixProcessingError::ReceivedOldTypeVpnPacket);
}
self.perform_initial_sphinx_packet_processing(sphinx_packet)
//here be shared secret retrieval and hashmap lookup
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,
) -> Result<MixProcessingResult, MixProcessingError> {
match packet {
ProcessedPacket::ForwardHop(packet, address, delay) => {
ProcessedPacket::ForwardHop(packet, address, delay, _) => {
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
// sphinx all together?
ProcessedPacket::FinalHop(destination, _, payload) => {
ProcessedPacket::FinalHop(destination, _, payload, _) => {
self.process_final_hop(destination, payload, packet_size, packet_mode)
}
}
@@ -60,6 +60,7 @@ impl SurbAck {
let surb_ack_packet = SphinxPacketBuilder::new()
.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)
.unwrap();
+1
View File
@@ -113,6 +113,7 @@ where
// once merged, that's an easy rng injection point for sphinx packets : )
let packet = SphinxPacketBuilder::new()
.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)
.unwrap();
+1
View File
@@ -208,6 +208,7 @@ pub trait FragmentPreparer {
// there's absolutely no reason for this call to fail.
let sphinx_packet = SphinxPacketBuilder::new()
.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)
.unwrap();
+2 -1
View File
@@ -8,7 +8,8 @@ license = { workspace = true }
repository = { workspace = true }
[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]
#sphinx-packet = { path = "../../../../sphinx" }
+1 -1
View File
@@ -8,7 +8,7 @@ pub use sphinx_packet::{
PAYLOAD_KEY_SIZE,
},
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},
payload::{Payload, PAYLOAD_OVERHEAD_SIZE},
route::{Destination, DestinationAddressBytes, Node, NodeAddressBytes, SURBIdentifier},