From 7b984a4e2991f275d3ff8d65a10ce66f56bed876 Mon Sep 17 00:00:00 2001 From: Youngjoon Lee <5462944+youngjoon-lee@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:14:34 +0700 Subject: [PATCH] Just use priv/pubkey as Node ID in the mock mix message encoding (#912) * Just use priv/pubkey as Node ID in the mock mix message encoding * do not convert private key to public key in mix service --- nomos-mix/message/src/mock/mod.rs | 54 ++++++++----------- .../data-availability/tests/src/common.rs | 4 +- nomos-services/mix/Cargo.toml | 1 - nomos-services/mix/src/lib.rs | 7 ++- tests/src/topology/configs/mix.rs | 4 +- 5 files changed, 32 insertions(+), 38 deletions(-) diff --git a/nomos-mix/message/src/mock/mod.rs b/nomos-mix/message/src/mock/mod.rs index 83c66f8b..ea8f6d5d 100644 --- a/nomos-mix/message/src/mock/mod.rs +++ b/nomos-mix/message/src/mock/mod.rs @@ -3,21 +3,20 @@ use crate::{Error, MixMessage}; // /// A mock implementation of the Sphinx encoding. -const PRIVATE_KEY_SIZE: usize = 32; -const PUBLIC_KEY_SIZE: usize = 32; +const NODE_ID_SIZE: usize = 32; const PADDED_PAYLOAD_SIZE: usize = 2048; const PAYLOAD_PADDING_SEPARATOR: u8 = 0x01; const PAYLOAD_PADDING_SEPARATOR_SIZE: usize = 1; const MAX_LAYERS: usize = 5; -pub const MESSAGE_SIZE: usize = PUBLIC_KEY_SIZE * MAX_LAYERS + PADDED_PAYLOAD_SIZE; +pub const MESSAGE_SIZE: usize = NODE_ID_SIZE * MAX_LAYERS + PADDED_PAYLOAD_SIZE; #[derive(Clone, Debug)] pub struct MockMixMessage; impl MixMessage for MockMixMessage { - type PublicKey = [u8; PUBLIC_KEY_SIZE]; - type PrivateKey = [u8; PRIVATE_KEY_SIZE]; + type PublicKey = [u8; NODE_ID_SIZE]; + type PrivateKey = [u8; NODE_ID_SIZE]; const DROP_MESSAGE: &'static [u8] = &[0; MESSAGE_SIZE]; /// The length of the encoded message is fixed to [`MESSAGE_SIZE`] bytes. @@ -25,7 +24,9 @@ impl MixMessage for MockMixMessage { /// The payload is zero-padded to the end. /// fn build_message(payload: &[u8], public_keys: &[Self::PublicKey]) -> Result, Error> { - if public_keys.is_empty() || public_keys.len() > MAX_LAYERS { + // In this mock, we don't encrypt anything. So, we use public key as just a node ID. + let node_ids = public_keys; + if node_ids.is_empty() || node_ids.len() > MAX_LAYERS { return Err(Error::InvalidNumberOfLayers); } if payload.len() > PADDED_PAYLOAD_SIZE - PAYLOAD_PADDING_SEPARATOR_SIZE { @@ -34,11 +35,11 @@ impl MixMessage for MockMixMessage { let mut message: Vec = Vec::with_capacity(MESSAGE_SIZE); - public_keys.iter().for_each(|public_key| { - message.extend(public_key); + node_ids.iter().for_each(|node_id| { + message.extend(node_id); }); // If there is any remaining layers, fill them with zeros. - (0..MAX_LAYERS - public_keys.len()).for_each(|_| message.extend(&[0; PUBLIC_KEY_SIZE])); + (0..MAX_LAYERS - node_ids.len()).for_each(|_| message.extend(&[0; NODE_ID_SIZE])); // Append payload with padding message.extend(payload); @@ -58,16 +59,15 @@ impl MixMessage for MockMixMessage { return Err(Error::InvalidMixMessage); } - let public_key = - x25519_dalek::PublicKey::from(&x25519_dalek::StaticSecret::from(*private_key)) - .to_bytes(); - if message[0..PUBLIC_KEY_SIZE] != public_key { + // In this mock, we don't decrypt anything. So, we use private key as just a node ID. + let node_id = private_key; + if &message[0..NODE_ID_SIZE] != node_id { return Err(Error::MsgUnwrapNotAllowed); } // If this is the last layer - if message[PUBLIC_KEY_SIZE..PUBLIC_KEY_SIZE * 2] == [0; PUBLIC_KEY_SIZE] { - let padded_payload = &message[PUBLIC_KEY_SIZE * MAX_LAYERS..]; + if message[NODE_ID_SIZE..NODE_ID_SIZE * 2] == [0; NODE_ID_SIZE] { + let padded_payload = &message[NODE_ID_SIZE * MAX_LAYERS..]; // remove the payload padding match padded_payload .iter() @@ -81,9 +81,9 @@ impl MixMessage for MockMixMessage { } let mut new_message: Vec = Vec::with_capacity(MESSAGE_SIZE); - new_message.extend(&message[PUBLIC_KEY_SIZE..PUBLIC_KEY_SIZE * MAX_LAYERS]); - new_message.extend(&[0; PUBLIC_KEY_SIZE]); - new_message.extend(&message[PUBLIC_KEY_SIZE * MAX_LAYERS..]); // padded payload + new_message.extend(&message[NODE_ID_SIZE..NODE_ID_SIZE * MAX_LAYERS]); + new_message.extend(&[0; NODE_ID_SIZE]); + new_message.extend(&message[NODE_ID_SIZE * MAX_LAYERS..]); // padded payload Ok((new_message, false)) } } @@ -94,31 +94,23 @@ mod tests { #[test] fn message() { - let private_keys = [ - x25519_dalek::StaticSecret::random(), - x25519_dalek::StaticSecret::random(), - x25519_dalek::StaticSecret::random(), - ]; - let public_keys = private_keys - .iter() - .map(|k| x25519_dalek::PublicKey::from(k).to_bytes()) - .collect::>(); + let node_ids = (0..3).map(|i| [i; NODE_ID_SIZE]).collect::>(); let payload = [7; 10]; - let message = MockMixMessage::build_message(&payload, &public_keys).unwrap(); + let message = MockMixMessage::build_message(&payload, &node_ids).unwrap(); assert_eq!(message.len(), MESSAGE_SIZE); let (message, is_fully_unwrapped) = - MockMixMessage::unwrap_message(&message, &private_keys[0].to_bytes()).unwrap(); + MockMixMessage::unwrap_message(&message, &node_ids[0]).unwrap(); assert!(!is_fully_unwrapped); assert_eq!(message.len(), MESSAGE_SIZE); let (message, is_fully_unwrapped) = - MockMixMessage::unwrap_message(&message, &private_keys[1].to_bytes()).unwrap(); + MockMixMessage::unwrap_message(&message, &node_ids[1]).unwrap(); assert!(!is_fully_unwrapped); assert_eq!(message.len(), MESSAGE_SIZE); let (unwrapped_payload, is_fully_unwrapped) = - MockMixMessage::unwrap_message(&message, &private_keys[2].to_bytes()).unwrap(); + MockMixMessage::unwrap_message(&message, &node_ids[2]).unwrap(); assert!(is_fully_unwrapped); assert_eq!(unwrapped_payload, payload); } diff --git a/nomos-services/data-availability/tests/src/common.rs b/nomos-services/data-availability/tests/src/common.rs index deeb1bd1..d0d72dad 100644 --- a/nomos-services/data-availability/tests/src/common.rs +++ b/nomos-services/data-availability/tests/src/common.rs @@ -337,7 +337,9 @@ pub fn new_mix_configs(listening_addresses: Vec) -> Vec>(); diff --git a/nomos-services/mix/Cargo.toml b/nomos-services/mix/Cargo.toml index c5ad3c75..4a39cfcd 100644 --- a/nomos-services/mix/Cargo.toml +++ b/nomos-services/mix/Cargo.toml @@ -20,7 +20,6 @@ serde = { version = "1.0", features = ["derive"] } tokio = { version = "1", features = ["macros", "sync"] } tokio-stream = "0.1" tracing = "0.1" -x25519-dalek = { version = "2", features = ["getrandom", "static_secrets"] } [features] default = [] diff --git a/nomos-services/mix/src/lib.rs b/nomos-services/mix/src/lib.rs index 4d4753f6..8e3bbc34 100644 --- a/nomos-services/mix/src/lib.rs +++ b/nomos-services/mix/src/lib.rs @@ -228,10 +228,9 @@ pub struct MixConfig { impl MixConfig { fn membership(&self) -> Membership { - let public_key = x25519_dalek::PublicKey::from(&x25519_dalek::StaticSecret::from( - self.message_blend.cryptographic_processor.private_key, - )) - .to_bytes(); + // We use private key as a public key because the `MockMixMessage` doesn't differentiate between them. + // TODO: Convert private key to public key properly once the real MixMessage is implemented. + let public_key = self.message_blend.cryptographic_processor.private_key; Membership::new(self.membership.clone(), public_key) } } diff --git a/tests/src/topology/configs/mix.rs b/tests/src/topology/configs/mix.rs index 35676f94..139806b7 100644 --- a/tests/src/topology/configs/mix.rs +++ b/tests/src/topology/configs/mix.rs @@ -51,7 +51,9 @@ fn mix_nodes(configs: &[GeneralMixConfig]) -> Vec