diff --git a/common/nym-kkt-ciphersuite/src/lib.rs b/common/nym-kkt-ciphersuite/src/lib.rs index 6be109febd..e72d873a87 100644 --- a/common/nym-kkt-ciphersuite/src/lib.rs +++ b/common/nym-kkt-ciphersuite/src/lib.rs @@ -5,7 +5,7 @@ use crate::error::KKTCiphersuiteError; use num_enum::{IntoPrimitive, TryFromPrimitive}; use std::collections::HashMap; use std::fmt::Display; -use strum_macros::{EnumIter, EnumString}; +use strum_macros::{Display, EnumIter, EnumString}; pub mod error; @@ -45,12 +45,26 @@ pub mod xwing { pub const PUBLIC_KEY_LENGTH: usize = x25519::PUBLIC_KEY_LENGTH + ml_kem768::PUBLIC_KEY_LENGTH; } -pub type KEMKeyDigests = HashMap>; +pub type KEMKeyDigests = KeyDigests; +pub type SigningKeyDigests = KeyDigests; + +pub type KeyDigests = HashMap>; #[derive( - Clone, Copy, PartialEq, Eq, Hash, Debug, IntoPrimitive, TryFromPrimitive, EnumIter, EnumString, + Clone, + Copy, + PartialEq, + Eq, + Hash, + Debug, + IntoPrimitive, + TryFromPrimitive, + EnumIter, + EnumString, + Display, )] #[strum(ascii_case_insensitive)] +#[strum(serialize_all = "lowercase")] #[repr(u8)] pub enum HashFunction { Blake3 = 0, @@ -79,17 +93,6 @@ impl HashFunction { } } -impl Display for HashFunction { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - HashFunction::Blake3 => "blake3", - HashFunction::Shake128 => "shake128", - HashFunction::Shake256 => "shake256", - HashFunction::SHA256 => "sha256", - }) - } -} - #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, IntoPrimitive)] #[repr(u8)] pub enum HashLength { @@ -146,7 +149,21 @@ impl HashLength { } } -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, IntoPrimitive, TryFromPrimitive)] +#[derive( + Clone, + Copy, + PartialEq, + Eq, + Hash, + Debug, + IntoPrimitive, + TryFromPrimitive, + EnumIter, + EnumString, + Display, +)] +#[strum(ascii_case_insensitive)] +#[strum(serialize_all = "lowercase")] #[repr(u8)] pub enum SignatureScheme { Ed25519 = 0, @@ -175,18 +192,21 @@ impl SignatureScheme { } } -impl Display for SignatureScheme { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - SignatureScheme::Ed25519 => "ed25519", - }) - } -} - #[derive( - Clone, Copy, PartialEq, Eq, Hash, Debug, IntoPrimitive, TryFromPrimitive, EnumIter, EnumString, + Clone, + Copy, + PartialEq, + Eq, + Hash, + Debug, + IntoPrimitive, + TryFromPrimitive, + EnumIter, + EnumString, + Display, )] #[strum(ascii_case_insensitive)] +#[strum(serialize_all = "lowercase")] #[repr(u8)] pub enum KEM { XWing = 0, @@ -206,17 +226,6 @@ impl KEM { } } -impl Display for KEM { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - KEM::MlKem768 => "mlkem768", - KEM::XWing => "xwing", - KEM::X25519 => "x25519", - KEM::McEliece => "mceliece", - }) - } -} - #[derive(Clone, Copy, PartialEq, Debug)] pub struct Ciphersuite { hash_function: HashFunction, @@ -363,4 +372,12 @@ mod tests { assert_eq!(hash_fn, HashFunction::from_str(&display).unwrap()); } } + + #[test] + fn signature_scheme_display_consistency() { + for scheme in SignatureScheme::iter() { + let display = format!("{scheme}"); + assert_eq!(scheme, SignatureScheme::from_str(&display).unwrap()); + } + } } diff --git a/common/nym-kkt/src/key_utils.rs b/common/nym-kkt/src/key_utils.rs index e612cbe3bf..535ba8b000 100644 --- a/common/nym-kkt/src/key_utils.rs +++ b/common/nym-kkt/src/key_utils.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use classic_mceliece_rust::keypair_boxed; -use nym_kkt_ciphersuite::{DEFAULT_HASH_LEN, KEMKeyDigests}; +use nym_kkt_ciphersuite::{DEFAULT_HASH_LEN, KeyDigests}; use rand::{CryptoRng, RngCore}; pub fn generate_keypair_ed25519( @@ -78,7 +78,7 @@ pub fn hash_key_bytes( /// attempt to produce digests of the provided key using all known [HashFunction] with a default /// hash length where variable output is available -pub fn produce_key_digests(key_bytes: &[u8]) -> KEMKeyDigests { +pub fn produce_key_digests(key_bytes: &[u8]) -> KeyDigests { use strum::IntoEnumIterator; let mut digests = HashMap::new(); for hash in HashFunction::iter() { diff --git a/common/nym-lp/src/peer.rs b/common/nym-lp/src/peer.rs index ee81fd5351..93f1fb2746 100644 --- a/common/nym-lp/src/peer.rs +++ b/common/nym-lp/src/peer.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use nym_crypto::asymmetric::{ed25519, x25519}; -use nym_kkt::ciphersuite::{HashFunction, KEM}; +use nym_kkt::ciphersuite::{KEM, KEMKeyDigests, SignatureScheme, SigningKeyDigests}; use std::collections::HashMap; use std::sync::Arc; @@ -49,18 +49,26 @@ impl LpLocalPeer { let expected_kem_key_digests = match &self.kem_psq { None => HashMap::new(), Some(kem_keys) => { - let hashes = - nym_kkt::key_utils::produce_key_digests(kem_keys.public_key().as_bytes()); - let mut digests = HashMap::new(); - digests.insert(KEM::X25519, hashes); + digests.insert( + KEM::X25519, + nym_kkt::key_utils::produce_key_digests(kem_keys.public_key().as_bytes()), + ); digests } }; + + let mut expected_signing_key_digests = HashMap::new(); + expected_signing_key_digests.insert( + SignatureScheme::Ed25519, + nym_kkt::key_utils::produce_key_digests(self.ed25519.public_key().as_bytes()), + ); + LpRemotePeer { ed25519_public: *self.ed25519.public_key(), x25519_public: *self.x25519.public_key(), expected_kem_key_digests, + expected_signing_key_digests, } } @@ -85,8 +93,11 @@ pub struct LpRemotePeer { /// Remote X25519 public key (Noise static key) pub(crate) x25519_public: x25519::PublicKey, - /// Expected digest of the remote's KEM key - pub(crate) expected_kem_key_digests: HashMap>>, + /// Expected digests of the remote's KEM key + pub(crate) expected_kem_key_digests: HashMap, + + /// Expected digests of the remote's signing key + pub(crate) expected_signing_key_digests: HashMap, } impl LpRemotePeer { @@ -95,6 +106,7 @@ impl LpRemotePeer { ed25519_public, x25519_public, expected_kem_key_digests: Default::default(), + expected_signing_key_digests: Default::default(), } } @@ -107,11 +119,13 @@ impl LpRemotePeer { } #[must_use] - pub fn with_kem_key_digests( + pub fn with_key_digests( mut self, - expected_kem_key_digests: HashMap>>, + expected_kem_key_digests: HashMap, + expected_signing_key_digests: HashMap, ) -> Self { self.expected_kem_key_digests = expected_kem_key_digests; + self.expected_signing_key_digests = expected_signing_key_digests; self } } diff --git a/common/registration/src/lib.rs b/common/registration/src/lib.rs index 56a3cee0bb..96d23bcf0f 100644 --- a/common/registration/src/lib.rs +++ b/common/registration/src/lib.rs @@ -5,7 +5,7 @@ use nym_authenticator_requests::AuthenticatorVersion; use nym_crypto::asymmetric::x25519::serde_helpers::bs58_x25519_pubkey; use nym_crypto::asymmetric::{ed25519, x25519}; use nym_ip_packet_requests::IpPair; -use nym_kkt_ciphersuite::{KEM, KEMKeyDigests}; +use nym_kkt_ciphersuite::{KEM, KEMKeyDigests, SignatureScheme}; use nym_sphinx::addressing::Recipient; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -43,6 +43,7 @@ pub struct WireguardConfiguration { pub struct NymNodeLPInformation { pub address: SocketAddr, pub expected_kem_key_hashes: HashMap, + pub expected_signing_key_hashes: HashMap, pub x25519: x25519::PublicKey, } diff --git a/nym-api/nym-api-requests/src/models/described/type_translation.rs b/nym-api/nym-api-requests/src/models/described/type_translation.rs index 5f1b078cb8..94746950d3 100644 --- a/nym-api/nym-api-requests/src/models/described/type_translation.rs +++ b/nym-api/nym-api-requests/src/models/described/type_translation.rs @@ -8,7 +8,7 @@ use celes::Country; use nym_crypto::asymmetric::ed25519::serde_helpers::bs58_ed25519_pubkey; use nym_crypto::asymmetric::x25519::serde_helpers::bs58_x25519_pubkey; use nym_crypto::asymmetric::{ed25519, x25519}; -use nym_kkt_ciphersuite::{HashFunction, KEM}; +use nym_kkt_ciphersuite::{HashFunction, SignatureScheme, KEM}; use nym_network_defaults::{WG_METADATA_PORT, WG_TUNNEL_PORT}; use nym_noise_keys::VersionedNoiseKeyV1; use schemars::JsonSchema; @@ -212,6 +212,20 @@ pub struct LewesProtocolDetailsV1 { /// Digests of the KEM keys available to this node alongside hashing algorithms used /// for their computation. pub kem_keys: HashMap>>, + + /// Digests of the signing keys available to this node alongside hashing algorithms used + /// for their computation. + pub signing_keys: HashMap>>, +} + +/// Convert map of digests from `nym_node_requests` types into `nym-api-requests` types +fn translate_digests( + digests: HashMap>, +) -> HashMap> { + digests + .into_iter() + .map(|(hash_fn, digest)| (hash_fn.into(), digest)) + .collect() } #[derive( @@ -260,6 +274,26 @@ pub enum LPHashFunction { Sha256, } +#[derive( + Serialize, + Deserialize, + Debug, + Clone, + Copy, + JsonSchema, + Hash, + PartialEq, + Eq, + PartialOrd, + Display, + EnumString, + ToSchema, +)] +#[strum(serialize_all = "lowercase")] +pub enum LPSignatureScheme { + Ed25519, +} + impl From for HostInformationV1 { fn from(value: nym_node_requests::api::v1::node::models::HostInformation) -> Self { HostInformationV1 { @@ -382,15 +416,12 @@ impl From kem_keys: value .kem_keys .into_iter() - .map(|(kem, digests)| { - ( - kem.into(), - digests - .into_iter() - .map(|(hash_fn, digest)| (hash_fn.into(), digest)) - .collect(), - ) - }) + .map(|(kem, digests)| (kem.into(), translate_digests(digests))) + .collect(), + signing_keys: value + .signing_keys + .into_iter() + .map(|(scheme, digests)| (scheme.into(), translate_digests(digests))) .collect(), } } @@ -426,6 +457,18 @@ impl From fo } } +impl From + for LPSignatureScheme +{ + fn from(value: nym_node_requests::api::v1::lewes_protocol::models::LPSignatureScheme) -> Self { + match value { + nym_node_requests::api::v1::lewes_protocol::models::LPSignatureScheme::Ed25519 => { + LPSignatureScheme::Ed25519 + } + } + } +} + impl From for KEM { fn from(value: LPKEM) -> Self { match value { @@ -447,3 +490,11 @@ impl From for HashFunction { } } } + +impl From for SignatureScheme { + fn from(value: LPSignatureScheme) -> Self { + match value { + LPSignatureScheme::Ed25519 => SignatureScheme::Ed25519, + } + } +} diff --git a/nym-api/nym-api-requests/src/models/described/v2.rs b/nym-api/nym-api-requests/src/models/described/v2.rs index ac712e3d5e..bd68aa5271 100644 --- a/nym-api/nym-api-requests/src/models/described/v2.rs +++ b/nym-api/nym-api-requests/src/models/described/v2.rs @@ -247,7 +247,7 @@ impl From for NymNodeDescriptionV2 { #[cfg(test)] pub fn mock_nym_node_description(seed: u64) -> NymNodeDescriptionV2 { - use crate::models::{LPHashFunction, LPKEM}; + use crate::models::{LPHashFunction, LPSignatureScheme, LPKEM}; use nym_test_utils::helpers::{u64_seeded_rng, RngCore}; let mut rng = u64_seeded_rng(seed); @@ -257,11 +257,16 @@ pub fn mock_nym_node_description(seed: u64) -> NymNodeDescriptionV2 { // just reuse the same x25519 key for everything - this is just a data mock let x25519 = x25519::KeyPair::new(&mut rng); - let mut hashes_wrapper = std::collections::HashMap::new(); - let mut hashes = std::collections::HashMap::new(); + let mut kem_hashes_wrapper = std::collections::HashMap::new(); + let mut signing_keys_hashes_wrapper = std::collections::HashMap::new(); + let mut kem_hashes = std::collections::HashMap::new(); + let mut signing_keys_hashes = std::collections::HashMap::new(); - hashes.insert(LPHashFunction::Sha256, vec![(seed % 256) as u8; 32]); - hashes_wrapper.insert(LPKEM::X25519, hashes); + kem_hashes.insert(LPHashFunction::Sha256, vec![(seed % 256) as u8; 32]); + kem_hashes_wrapper.insert(LPKEM::X25519, kem_hashes); + + signing_keys_hashes.insert(LPHashFunction::Sha256, vec![(seed % 256) as u8; 32]); + signing_keys_hashes_wrapper.insert(LPSignatureScheme::Ed25519, signing_keys_hashes); NymNodeDescriptionV2 { node_id: rng.next_u32(), @@ -332,7 +337,8 @@ pub fn mock_nym_node_description(seed: u64) -> NymNodeDescriptionV2 { enabled: true, control_port: 1234, data_port: 2345, - kem_keys: hashes_wrapper, + kem_keys: kem_hashes_wrapper, + signing_keys: signing_keys_hashes_wrapper, }), mixnet_websockets: WebSocketsV2 { ws_port: 9000, diff --git a/nym-gateway-probe/src/lib.rs b/nym-gateway-probe/src/lib.rs index f6cdb0a7fc..50695533c1 100644 --- a/nym-gateway-probe/src/lib.rs +++ b/nym-gateway-probe/src/lib.rs @@ -64,7 +64,7 @@ use crate::bandwidth_helpers::{acquire_bandwidth, import_bandwidth}; use crate::nodes::{DirectoryNode, NymApiDirectory}; pub use mode::TestMode; use nym_crypto::asymmetric::{ed25519, x25519}; -use nym_kkt_ciphersuite::{KEM, KEMKeyDigests}; +use nym_kkt_ciphersuite::{KEM, KEMKeyDigests, SignatureScheme}; use nym_lp::peer::LpRemotePeer; use nym_node_status_client::models::AttachedTicketMaterials; use nym_registration_client::{LpRegistrationClient, NestedLpSession}; @@ -167,6 +167,7 @@ pub struct TestedNodeDetails { pub struct TestedNodeLpDetails { pub address: SocketAddr, pub expected_kem_key_hashes: HashMap, + pub expected_signing_key_hashes: HashMap, pub x25519: x25519::PublicKey, } @@ -1077,7 +1078,10 @@ async fn wg_probe( } fn to_lp_remote_peer(identity: ed25519::PublicKey, data: TestedNodeLpDetails) -> LpRemotePeer { - LpRemotePeer::new(identity, data.x25519).with_kem_key_digests(data.expected_kem_key_hashes) + LpRemotePeer::new(identity, data.x25519).with_key_digests( + data.expected_kem_key_hashes, + data.expected_signing_key_hashes, + ) } async fn lp_registration_probe( diff --git a/nym-gateway-probe/src/nodes.rs b/nym-gateway-probe/src/nodes.rs index 1eeee1657c..202e00cd15 100644 --- a/nym-gateway-probe/src/nodes.rs +++ b/nym-gateway-probe/src/nodes.rs @@ -141,6 +141,19 @@ impl DirectoryNode { ) }) .collect(), + expected_signing_key_hashes: lp_data + .signing_keys + .into_iter() + .map(|(scheme, digests)| { + ( + scheme.into(), + digests + .into_iter() + .map(|(hash_fn, digest)| (hash_fn.into(), digest)) + .collect(), + ) + }) + .collect(), x25519: noise_key.x25519_pubkey, }), _ => None, diff --git a/nym-gateway-probe/src/run.rs b/nym-gateway-probe/src/run.rs index 085aaae2b1..0ce0b98b8f 100644 --- a/nym-gateway-probe/src/run.rs +++ b/nym-gateway-probe/src/run.rs @@ -244,6 +244,9 @@ fn mode_to_flags(mode: TestMode) -> (bool, bool, bool) { } } +#[allow(clippy::todo)] +#[allow(unreachable_code, unused)] +// ^^^^ // NOTE: to be changed by @SW #[allow(clippy::unwrap_used)] pub(crate) async fn run() -> anyhow::Result { let args = CliArgs::parse(); @@ -306,6 +309,7 @@ pub(crate) async fn run() -> anyhow::Result { let entry_lp_node = TestedNodeLpDetails { address: entry_lp_addr, expected_kem_key_hashes, + expected_signing_key_hashes: todo!(), x25519: x25519_key, }; let entry_details = TestedNodeDetails::from_cli(identity, entry_lp_node); @@ -338,6 +342,7 @@ pub(crate) async fn run() -> anyhow::Result { let exit_lp_node = TestedNodeLpDetails { address: exit_lp_addr, expected_kem_key_hashes, + expected_signing_key_hashes: Default::default(), x25519: x25519_key, }; diff --git a/nym-node/nym-node-requests/src/api/v1/lewes_protocol/models.rs b/nym-node/nym-node-requests/src/api/v1/lewes_protocol/models.rs index 24848610f7..ac38f316b1 100644 --- a/nym-node/nym-node-requests/src/api/v1/lewes_protocol/models.rs +++ b/nym-node/nym-node-requests/src/api/v1/lewes_protocol/models.rs @@ -22,26 +22,28 @@ pub struct LewesProtocol { /// Digests of the KEM keys available to this node alongside hashing algorithms used /// for their computation. pub kem_keys: HashMap>>, + + /// Digests of the signing keys available to this node alongside hashing algorithms used + /// for their computation. + pub signing_keys: HashMap>>, } impl LewesProtocol { - pub fn new(enabled: bool, control_port: u16, data_port: u16) -> Self { + pub fn new( + enabled: bool, + control_port: u16, + data_port: u16, + kem_keys: HashMap>>, + signing_keys: HashMap>>, + ) -> Self { LewesProtocol { enabled, control_port, data_port, - kem_keys: Default::default(), + kem_keys, + signing_keys, } } - - pub fn with_kem_key_hashes( - mut self, - kem: LPKEM, - hashes: HashMap>, - ) -> Self { - self.kem_keys.insert(kem, hashes); - self - } } // explicitly redefine available HashFunctions and KEMs so that we would not @@ -140,9 +142,47 @@ impl From for LPHashFunction { } } +#[derive( + Serialize, + Deserialize, + Debug, + Clone, + Copy, + JsonSchema, + Hash, + PartialEq, + Eq, + PartialOrd, + Display, + EnumString, + EnumIter, +)] +#[strum(serialize_all = "lowercase")] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +pub enum LPSignatureScheme { + Ed25519, +} + +impl From for nym_kkt_ciphersuite::SignatureScheme { + fn from(lp_hash_fnction: LPSignatureScheme) -> Self { + match lp_hash_fnction { + LPSignatureScheme::Ed25519 => nym_kkt_ciphersuite::SignatureScheme::Ed25519, + } + } +} + +impl From for LPSignatureScheme { + fn from(kem: nym_kkt_ciphersuite::SignatureScheme) -> Self { + match kem { + nym_kkt_ciphersuite::SignatureScheme::Ed25519 => LPSignatureScheme::Ed25519, + } + } +} + #[cfg(test)] mod tests { use super::*; + use nym_kkt_ciphersuite::SignatureScheme; #[test] fn kem_display() { @@ -159,4 +199,9 @@ mod tests { assert_eq!(LPHashFunction::Shake256.to_string(), "shake256"); assert_eq!(LPHashFunction::Sha256.to_string(), "sha256"); } + + #[test] + fn signature_scheme_display() { + assert_eq!(SignatureScheme::Ed25519.to_string(), "ed25519"); + } } diff --git a/nym-node/src/node/mod.rs b/nym-node/src/node/mod.rs index 80eff44f06..1c9f3bb3fb 100644 --- a/nym-node/src/node/mod.rs +++ b/nym-node/src/node/mod.rs @@ -51,7 +51,9 @@ use nym_network_requester::{ }; use nym_node_metrics::NymNodeMetrics; use nym_node_metrics::events::MetricEventsSender; -use nym_node_requests::api::v1::lewes_protocol::models::{LPHashFunction, LPKEM}; +use nym_node_requests::api::v1::lewes_protocol::models::{ + LPHashFunction, LPKEM, LPSignatureScheme, +}; use nym_node_requests::api::v1::node::models::{AnnouncePorts, NodeDescription}; use nym_noise::config::{NoiseConfig, NoiseNetworkView}; use nym_noise_keys::VersionedNoiseKeyV1; @@ -774,7 +776,7 @@ impl NymNode { Ok(()) } - fn compute_kem_key_hashes(&self) -> (LPKEM, HashMap>) { + fn compute_kem_key_hashes(&self) -> HashMap>> { let kem = LPKEM::X25519; let kem_key_bytes = self.entry_gateway.psq_kem_key.public_key().as_bytes(); @@ -785,7 +787,27 @@ impl NymNode { .map(|(f, d)| (f.into(), d)) .collect(); - (kem, digests) + let mut hashes = HashMap::new(); + hashes.insert(kem, digests); + hashes + } + + fn compute_signing_key_hashes( + &self, + ) -> HashMap>> { + let scheme = LPSignatureScheme::Ed25519; + + let kem_key_bytes = self.ed25519_identity_keys.public_key().as_bytes(); + + // convert from `nym_kkt_ciphersuite` types into `nym_nodes_requests` + let digests = produce_key_digests(kem_key_bytes.as_ref()) + .into_iter() + .map(|(f, d)| (f.into(), d)) + .collect(); + + let mut hashes = HashMap::new(); + hashes.insert(scheme, digests); + hashes } pub(crate) async fn build_http_server(&self) -> Result { @@ -861,13 +883,13 @@ impl NymNode { policy: None, }; - let (kem, hashes) = self.compute_kem_key_hashes(); let lp_details = api_requests::v1::lewes_protocol::models::LewesProtocol::new( self.modes().entry, self.config.gateway_tasks.lp.announced_control_port(), self.config.gateway_tasks.lp.announced_data_port(), - ) - .with_kem_key_hashes(kem, hashes); + self.compute_kem_key_hashes(), + self.compute_signing_key_hashes(), + ); let mut config = HttpServerConfig::new() .with_landing_page_assets(self.config.http.landing_page_assets_path.as_ref()) diff --git a/nym-registration-client/src/lp_client/helpers.rs b/nym-registration-client/src/lp_client/helpers.rs index 2637ea0110..79b1b027b1 100644 --- a/nym-registration-client/src/lp_client/helpers.rs +++ b/nym-registration-client/src/lp_client/helpers.rs @@ -90,5 +90,8 @@ pub(crate) fn to_lp_remote_peer( identity: ed25519::PublicKey, data: NymNodeLPInformation, ) -> LpRemotePeer { - LpRemotePeer::new(identity, data.x25519).with_kem_key_digests(data.expected_kem_key_hashes) + LpRemotePeer::new(identity, data.x25519).with_key_digests( + data.expected_kem_key_hashes, + data.expected_signing_key_hashes, + ) } diff --git a/tools/nym-lp-client/src/client.rs b/tools/nym-lp-client/src/client.rs index 7dfd2122ee..cc1e94768b 100644 --- a/tools/nym-lp-client/src/client.rs +++ b/tools/nym-lp-client/src/client.rs @@ -118,7 +118,10 @@ impl SpeedtestClient { ); let gw_peer = LpRemotePeer::new(self.gateway.identity, self.gateway.identity.to_x25519()?) - .with_kem_key_digests(self.gateway.kem_key_hashes.clone()); + .with_key_digests( + self.gateway.kem_key_hashes.clone(), + self.gateway.signing_key_hashes.clone(), + ); let mut lp_client = LpRegistrationClient::::new_with_default_config( self.identity_keypair.clone(), @@ -161,7 +164,10 @@ impl SpeedtestClient { ); let gw_peer = LpRemotePeer::new(self.gateway.identity, self.gateway.identity.to_x25519()?) - .with_kem_key_digests(self.gateway.kem_key_hashes.clone()); + .with_key_digests( + self.gateway.kem_key_hashes.clone(), + self.gateway.signing_key_hashes.clone(), + ); let mut lp_client = LpRegistrationClient::new_with_default_config( self.identity_keypair.clone(), diff --git a/tools/nym-lp-client/src/topology.rs b/tools/nym-lp-client/src/topology.rs index ebf3d8997f..5735134317 100644 --- a/tools/nym-lp-client/src/topology.rs +++ b/tools/nym-lp-client/src/topology.rs @@ -10,7 +10,7 @@ use nym_api_requests::models::{LPHashFunction, LPKEM}; use nym_api_requests::nym_nodes::SkimmedNode; use nym_crypto::asymmetric::ed25519; use nym_http_api_client::UserAgent; -use nym_kkt_ciphersuite::{KEMKeyDigests, KEM}; +use nym_kkt_ciphersuite::{KEMKeyDigests, SignatureScheme, SigningKeyDigests, KEM}; use nym_sphinx_types::Node as SphinxNode; use nym_topology::{NymRouteProvider, NymTopology, NymTopologyMetadata}; use nym_validator_client::nym_api::NymApiClientExt; @@ -31,6 +31,7 @@ const LP_DATA_PORT: u16 = 51264; pub struct GatewayInfo { pub identity: ed25519::PublicKey, pub kem_key_hashes: HashMap, + pub signing_key_hashes: HashMap, pub sphinx_key: nym_crypto::asymmetric::x25519::PublicKey, /// Mix host (IP:port for Sphinx mixing)