Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swap order of hybrid KEM components for X25519MlKem768 #694

Merged
merged 9 commits into from
Nov 22, 2024
28 changes: 14 additions & 14 deletions libcrux-kem/src/kem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,18 +147,18 @@ pub struct X25519MlKem768Draft00PrivateKey {
impl X25519MlKem768Draft00PrivateKey {
pub fn decode(bytes: &[u8]) -> Result<Self, Error> {
Ok(Self {
mlkem: bytes[32..]
mlkem: bytes[..2400]
.try_into()
.map_err(|_| Error::InvalidPrivateKey)?,
x25519: bytes[..32]
x25519: bytes[2400..]
.try_into()
.map_err(|_| Error::InvalidPrivateKey)?,
})
}

pub fn encode(&self) -> Vec<u8> {
let mut out = self.x25519.0.to_vec();
out.extend_from_slice(self.mlkem.as_ref());
let mut out = self.mlkem.as_ref().to_vec();
out.extend_from_slice(&self.x25519.0);
out
}
}
Expand Down Expand Up @@ -218,22 +218,22 @@ impl X25519MlKem768Draft00PublicKey {
pub fn decode(bytes: &[u8]) -> Result<Self, Error> {
Ok(Self {
mlkem: {
let key = MlKem768PublicKey::try_from(&bytes[32..])
let key = MlKem768PublicKey::try_from(&bytes[..1184])
.map_err(|_| Error::InvalidPublicKey)?;
if !mlkem768::validate_public_key(&key) {
return Err(Error::InvalidPublicKey);
}
key
},
x25519: bytes[0..32]
x25519: bytes[1184..]
.try_into()
.map_err(|_| Error::InvalidPublicKey)?,
})
}

pub fn encode(&self) -> Vec<u8> {
let mut out = self.x25519.0.to_vec();
out.extend_from_slice(self.mlkem.as_ref());
let mut out = self.mlkem.as_ref().to_vec();
out.extend_from_slice(&self.x25519.0);
out
}
}
Expand Down Expand Up @@ -444,7 +444,7 @@ pub enum Ss {
X25519PublicKey, // pk_X
),
#[cfg(feature = "kyber")]
X25519Kyber768Draft00(MlKemSharedSecret, X25519PublicKey),
X25519Kyber768Draft00(MlKemSharedSecret, X25519SharedSecret),
#[cfg(feature = "kyber")]
XWingKyberDraft02(
MlKemSharedSecret, // ss_M
Expand Down Expand Up @@ -716,8 +716,8 @@ impl Ss {
Ss::MlKem512(k) => k.as_ref().to_vec(),
Ss::MlKem768(k) => k.as_ref().to_vec(),
Ss::X25519MlKem768Draft00(kk, xk) => {
let mut out = xk.0.to_vec();
out.extend_from_slice(kk.as_ref());
let mut out = kk.to_vec();
out.extend_from_slice(xk.0.as_ref());
out
}
Ss::XWingKemDraft02(ss_m, ss_x, ct_x, pk_x) => {
Expand Down Expand Up @@ -763,8 +763,8 @@ impl Ct {
Ct::MlKem512(k) => k.as_ref().to_vec(),
Ct::MlKem768(k) => k.as_ref().to_vec(),
Ct::X25519MlKem768Draft00(kk, xk) => {
let mut out = xk.0.to_vec();
out.extend_from_slice(kk.as_ref());
let mut out = kk.as_ref().to_vec();
out.extend_from_slice(xk.0.as_ref());
out
}
Ct::XWingKemDraft02(ct_m, ct_x) => {
Expand Down Expand Up @@ -810,7 +810,7 @@ impl Ct {
Algorithm::X25519MlKem768Draft00 => {
let key: [u8; MlKem768Ciphertext::len() + 32] =
bytes.try_into().map_err(|_| Error::InvalidCiphertext)?;
let (xct, kct) = key.split_at(32);
let (kct, xct) = key.split_at(1088);
Ok(Self::X25519MlKem768Draft00(
kct.try_into().map_err(|_| Error::InvalidCiphertext)?,
xct.try_into().map_err(|_| Error::InvalidCiphertext)?,
Expand Down
10 changes: 8 additions & 2 deletions src/hpke/hpke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,8 +519,14 @@ pub fn SetupBaseR(
mlkem: kyber,
x25519,
} = X25519MlKem768Draft00PrivateKey::decode(skR).unwrap();
let ss1 = Decap(KEM::DHKEM_X25519_HKDF_SHA256, &enc[0..32], &x25519.0)?;
let ss2 = Kyber768Draft00_Decap(kyber.as_ref(), &enc[32..])?;
let Ct::X25519MlKem768Draft00(ct_mlkem, ct_x25519) =
Ct::decode(libcrux_kem::Algorithm::X25519MlKem768Draft00, &enc).unwrap()
else {
return Err(HpkeError::CryptoError);
};

let ss1 = Decap(KEM::DHKEM_X25519_HKDF_SHA256, &ct_x25519.0, &x25519.0)?;
let ss2 = Kyber768Draft00_Decap(kyber.as_ref(), ct_mlkem.as_ref())?;
let ss = crate::kem::Ss::X25519MlKem768Draft00(
ss2.as_slice().try_into().unwrap(),
libcrux_ecdh::X25519SharedSecret(ss1.try_into().unwrap()),
Expand Down
Loading