From aafa99ea47067e577b0c2fd470e4c1f49f265041 Mon Sep 17 00:00:00 2001 From: Georgio Nicolas Date: Mon, 26 Jan 2026 15:01:43 +0100 Subject: [PATCH] kkt should work with different keys now --- common/nym-lp/src/session.rs | 81 ++++++++++++++++++++---------- common/nym-lp/src/state_machine.rs | 27 ++-------- 2 files changed, 57 insertions(+), 51 deletions(-) diff --git a/common/nym-lp/src/session.rs b/common/nym-lp/src/session.rs index 9ef7a23094..d841ff0d6f 100644 --- a/common/nym-lp/src/session.rs +++ b/common/nym-lp/src/session.rs @@ -19,7 +19,7 @@ use crate::replay::ReceivingKeyCounterValidator; use crate::{LpError, LpMessage, LpPacket}; use nym_crypto::asymmetric::{ed25519, x25519}; use nym_kkt::KKT_RESPONSE_AAD; -use nym_kkt::ciphersuite::{DecapsulationKey, EncapsulationKey}; +use nym_kkt::ciphersuite::{DecapsulationKey, EncapsulationKey, KEM}; use nym_kkt::context::KKTContext; use nym_kkt::encryption::{ KKTSessionSecret, decrypt_initial_kkt_frame, decrypt_kkt_frame, encrypt_initial_kkt_frame, @@ -32,6 +32,7 @@ use nym_kkt::session::{ use parking_lot::Mutex; use rand::RngCore; use snow::Builder; +use std::sync::Arc; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use std::time::{SystemTime, UNIX_EPOCH}; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -303,6 +304,23 @@ impl LpSession { self.remote_peer.ed25519_public } + pub fn local_kem_encapsulation_key(&self, kem: &KEM) -> Option> { + match kem { + KEM::MlKem768 => self + .local_peer + .mlkem + .as_ref() + .and_then(|x| Some(x.1.clone())), + KEM::McEliece => self + .local_peer + .mceliece + .as_ref() + .and_then(|x| Some(x.1.clone())), + KEM::X25519 => todo!(), + _ => None, + } + } + /// Returns the remote X25519 public key. /// /// Used for tie-breaking in simultaneous subsession initiation. @@ -597,7 +615,7 @@ impl LpSession { // georgio this needs to be moved one level up (maybe chosen in LPSession) let ciphersuite = match Ciphersuite::resolve_ciphersuite( - KEM::X25519, + KEM::MlKem768, HashFunction::Blake3, SignatureScheme::Ed25519, None, @@ -741,11 +759,7 @@ impl LpSession { /// /// * `Ok(LpMessage::KKTResponse)` - Signed KKT response ready to send /// * `Err(LpError)` - Signature verification failed or invalid request - pub fn process_kkt_request( - &self, - request_bytes: &[u8], - responder_kem_pk: &EncapsulationKey, - ) -> Result { + pub fn process_kkt_request(&self, request_bytes: &[u8]) -> Result { let mut rng = rand09::rng(); let mut kkt_state = self.kkt_state.lock(); @@ -756,33 +770,46 @@ impl LpSession { ) { Ok((session_secret, request_frame, remote_context)) => { match responder_ingest_message(&remote_context, None, None, &request_frame) { - Ok((mut context, _)) => match responder_process( - &mut context, - request_frame.session_id(), - self.local_peer.ed25519().private_key(), - responder_kem_pk, - ) { - Ok(response_frame) => match encrypt_kkt_frame( - &mut rng, - &session_secret, - &response_frame, - KKT_RESPONSE_AAD, + Ok((mut context, _)) => { + let local_kem_key: Arc = + match self.local_kem_encapsulation_key(&context.ciphersuite().kem()) { + Some(key) => key.clone(), + None => { + return Err(LpError::Internal(format!( + "KEM key for algorithm ({:?}) is not available.", + &context.ciphersuite().kem() + ))); + } + }; + + match responder_process( + &mut context, + request_frame.session_id(), + self.local_peer.ed25519().private_key(), + &local_kem_key, ) { - Ok(response_bytes) => response_bytes, + Ok(response_frame) => match encrypt_kkt_frame( + &mut rng, + &session_secret, + &response_frame, + KKT_RESPONSE_AAD, + ) { + Ok(response_bytes) => response_bytes, + Err(e) => { + return Err(LpError::Internal(format!( + "KKT response encryption failure : {:?}", + e + ))); + } + }, Err(e) => { return Err(LpError::Internal(format!( - "KKT response encryption failure : {:?}", + "KKT response generation failure : {:?}", e ))); } - }, - Err(e) => { - return Err(LpError::Internal(format!( - "KKT response generation failure : {:?}", - e - ))); } - }, + } Err(e) => { return Err(LpError::Internal(format!( "KKT request handling failure: {:?}", diff --git a/common/nym-lp/src/state_machine.rs b/common/nym-lp/src/state_machine.rs index 9bf3541c6a..2f78ba83e7 100644 --- a/common/nym-lp/src/state_machine.rs +++ b/common/nym-lp/src/state_machine.rs @@ -360,22 +360,7 @@ impl LpStateMachine { // Packet message is already parsed, match on it directly match &packet.message { LpMessage::KKTRequest(kkt_request) if !session.is_initiator() => { - // Responder processes KKT request - // Convert X25519 public key to KEM format for KKT response - use nym_kkt::ciphersuite::EncapsulationKey; - - // Get local X25519 public key by deriving from private key - let local_x25519_public = session.local_x25519_public(); - - // Convert to libcrux KEM public key - match libcrux_kem::PublicKey::decode( - libcrux_kem::Algorithm::X25519, - local_x25519_public.as_bytes(), - ) { - Ok(libcrux_public_key) => { - let responder_kem_pk = EncapsulationKey::X25519(libcrux_public_key); - - match session.process_kkt_request(&kkt_request.0, &responder_kem_pk) { + match session.process_kkt_request(&kkt_request.0) { Ok(kkt_response_message) => { match session.next_packet(kkt_response_message) { Ok(response_packet) => { @@ -396,14 +381,8 @@ impl LpStateMachine { LpState::Closed { reason } } } - } - Err(e) => { - let reason = format!("Failed to convert X25519 to KEM: {:?}", e); - let err = LpError::Internal(reason.clone()); - result_action = Some(Err(err)); - LpState::Closed { reason } - } - } + + } LpMessage::KKTResponse(kkt_response) if session.is_initiator() => { match session.process_kkt_response(&kkt_response.0) {