diff --git a/libcrux-kem/src/kem.rs b/libcrux-kem/src/kem.rs index 7ad465ce4..39d102435 100644 --- a/libcrux-kem/src/kem.rs +++ b/libcrux-kem/src/kem.rs @@ -147,18 +147,18 @@ pub struct X25519MlKem768Draft00PrivateKey { impl X25519MlKem768Draft00PrivateKey { pub fn decode(bytes: &[u8]) -> Result { 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 { - 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 } } @@ -218,22 +218,22 @@ impl X25519MlKem768Draft00PublicKey { pub fn decode(bytes: &[u8]) -> Result { 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 { - 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 } } @@ -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 @@ -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) => { @@ -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) => { @@ -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)?, diff --git a/src/hpke/hpke.rs b/src/hpke/hpke.rs index 455343ec7..e42bbeebc 100644 --- a/src/hpke/hpke.rs +++ b/src/hpke/hpke.rs @@ -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()),