add xwing support

This commit is contained in:
Georgio Nicolas
2025-10-07 19:11:47 +02:00
parent d5194722cf
commit 40e07e2a0c
3 changed files with 95 additions and 26 deletions
+3
View File
@@ -72,6 +72,9 @@ pub enum NoiseError {
#[error("Handshake timeout")]
HandshakeTimeout(#[from] tokio::time::error::Elapsed),
#[error("Missing Field")]
MissingField { info: String },
#[error("PSQ Error")]
PSQError(PSQError),
}
+52 -5
View File
@@ -33,7 +33,7 @@ mod psk_gen {
use crate::{error::NoiseError, stream::Psk, NOISE_PSK_PREFIX};
use libcrux_ed25519::VerificationKey;
use libcrux_kem::{PrivateKey, PublicKey};
use libcrux_psq::impls::X25519;
use libcrux_psq::impls::{MlKem768, XWingKemDraft06, X25519};
use nym_crypto::asymmetric::ed25519;
use nympsq::{
@@ -50,6 +50,19 @@ mod psk_gen {
hasher.finalize().into()
}
pub(crate) fn psq_initiate_x25519(
initiator: &mut PSQInitiator<X25519>,
responder_pub_key: impl AsRef<[u8]>,
context: &[u8; CONTEXT_LEN],
psq_ttl: Duration,
) -> Result<Vec<u8>, NoiseError> {
let pub_key =
PublicKey::decode(libcrux_kem::Algorithm::X25519, responder_pub_key.as_ref())?;
let message =
initiator.compute_initiator_message(&mut rand::rng(), &pub_key, context, psq_ttl)?;
Ok(message)
}
pub(crate) fn psq_respond_x25519(
responder_private_key: impl AsRef<[u8]>,
responder_public_key: impl AsRef<[u8]>,
@@ -81,18 +94,52 @@ mod psk_gen {
Ok(res)
}
pub(crate) fn psq_initiate_x25519(
initiator: &mut PSQInitiator<X25519>,
pub(crate) fn psq_initiate_xwing(
initiator: &mut PSQInitiator<XWingKemDraft06>,
responder_pub_key: impl AsRef<[u8]>,
context: &[u8; CONTEXT_LEN],
psq_ttl: Duration,
) -> Result<Vec<u8>, NoiseError> {
let pub_key =
PublicKey::decode(libcrux_kem::Algorithm::X25519, responder_pub_key.as_ref())?;
let pub_key = PublicKey::decode(
libcrux_kem::Algorithm::XWingKemDraft06,
responder_pub_key.as_ref(),
)?;
let message =
initiator.compute_initiator_message(&mut rand::rng(), &pub_key, context, psq_ttl)?;
Ok(message)
}
pub(crate) fn psq_respond_xwing(
responder_private_key: impl AsRef<[u8]>,
responder_public_key: impl AsRef<[u8]>,
initiator_verification_key: &ed25519::PublicKey,
initiator_message: &mut [u8],
context: &[u8; CONTEXT_LEN],
psq_ttl: Duration,
psk_handle: &[u8; PSK_HANDLE_LEN],
) -> Result<(Psk, Vec<u8>), PSQError> {
let kem_private_key = PrivateKey::decode(
libcrux_kem::Algorithm::XWingKemDraft06,
responder_private_key.as_ref(),
)?;
let kem_public_key = PublicKey::decode(
libcrux_kem::Algorithm::XWingKemDraft06,
responder_public_key.as_ref(),
)?;
let responder: PSQResponder<XWingKemDraft06> =
PSQResponder::init(&kem_private_key, &kem_public_key);
let res = responder.compute_responder_message(
&VerificationKey::from_bytes(initiator_verification_key.to_bytes()),
initiator_message,
context,
psq_ttl,
psk_handle,
)?;
Ok(res)
}
}
pub async fn upgrade_noise_initiator(
+40 -21
View File
@@ -58,7 +58,7 @@ impl<C> NoiseStreamBuilder<C> {
.remote_public_key(remote_pub_key.as_ref())
.build_initiator()?;
let payload = match version {
let payload: Vec<u8> = match version {
NoiseVersion::V1 => {
handshake.set_psk(
pattern.psk_position() as usize,
@@ -81,9 +81,25 @@ impl<C> NoiseStreamBuilder<C> {
)?;
payload
}
_ => panic!("no keypair in v2"),
(None, None) => {
return Err(NoiseError::MissingField {
info: format!("Missing Local Signing Key and Local Verification Key"),
})
}
(None, _) => {
return Err(NoiseError::MissingField {
info: format!("Local Signing Key"),
})
}
(_, None) => {
return Err(NoiseError::MissingField {
info: format!("Local Verification Key"),
})
}
},
NoiseVersion::Unknown(_) => todo!(),
NoiseVersion::Unknown(version) => {
return Err(NoiseError::UnknownVersion { encoded: version })
}
};
self.perform_handshake(handshake, payload, version, pattern)
@@ -166,27 +182,30 @@ impl<C> NoiseStreamBuilder<C> {
)?;
vec![]
}
NoiseVersion::V2 => {
match initiator_verification_key {
Some(verif_key) => {
let (psk, message) = psq_respond_x25519(
&local_private_key,
&local_public_key,
&verif_key,
&mut buf,
NOISE_PSQ_DEFAULT_CONTEXT,
Duration::from_secs(NOISE_PSQ_DEFAULT_DURATION_SECS),
&[1; PSK_HANDLE_LEN],
)?;
handshake.set_psk(pattern.psk_position() as usize, psk.as_slice())?;
NoiseVersion::V2 => match initiator_verification_key {
Some(verif_key) => {
let (psk, message) = psq_respond_x25519(
&local_private_key,
&local_public_key,
&verif_key,
&mut buf,
NOISE_PSQ_DEFAULT_CONTEXT,
Duration::from_secs(NOISE_PSQ_DEFAULT_DURATION_SECS),
&[1; PSK_HANDLE_LEN],
)?;
handshake.set_psk(pattern.psk_position() as usize, psk.as_slice())?;
message
}
// error could be replaced by something else
None => return Err(NoiseError::IncorrectStateError),
message
}
None => {
return Err(NoiseError::MissingField {
info: format!("Initiator Verification Key"),
})
}
},
NoiseVersion::Unknown(version) => {
return Err(NoiseError::UnknownVersion { encoded: version })
}
NoiseVersion::Unknown(_) => todo!(),
};
// 3. run handshake to completion