Compare commits
3 Commits
base
...
simon/key-reuse
| 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> {
|
||||
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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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},
|
||||
|
||||
Reference in New Issue
Block a user