kkt should work with different keys now

This commit is contained in:
Georgio Nicolas
2026-01-26 15:01:43 +01:00
parent 4767a719f7
commit aafa99ea47
2 changed files with 57 additions and 51 deletions
+54 -27
View File
@@ -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<Arc<EncapsulationKey>> {
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<LpMessage, LpError> {
pub fn process_kkt_request(&self, request_bytes: &[u8]) -> Result<LpMessage, LpError> {
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<EncapsulationKey> =
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: {:?}",
+3 -24
View File
@@ -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) {