use pqcrypto_mlkem::{mlkem1024, mlkem512, mlkem768};
use pqcrypto_traits::kem::{Ciphertext, PublicKey, SecretKey, SharedSecret};
use crate::bytearray::{ByteArray, SensitiveByteArray};
use crate::error::KemError;
use crate::traits::{CryptoComponent, Kem, Rng};
use crate::KeyPair;
#[derive(Clone)]
pub struct MlKem512;
#[derive(Clone)]
pub struct MlKem768;
#[derive(Clone)]
pub struct MlKem1024;
impl CryptoComponent for MlKem512 {
fn name() -> &'static str {
"MLKEM512"
}
}
impl CryptoComponent for MlKem768 {
fn name() -> &'static str {
"MLKEM768"
}
}
impl CryptoComponent for MlKem1024 {
fn name() -> &'static str {
"MLKEM1024"
}
}
macro_rules! impl_ml_kem {
($kyber:ty, $module:ident) => {
impl Kem for $kyber {
#[cfg(feature = "alloc")]
type SecretKey =
SensitiveByteArray<crate::bytearray::HeapArray<{ $module::secret_key_bytes() }>>;
#[cfg(not(feature = "alloc"))]
type SecretKey = SensitiveByteArray<[u8; $module::secret_key_bytes()]>;
#[cfg(feature = "alloc")]
type PubKey = crate::bytearray::HeapArray<{ $module::public_key_bytes() }>;
#[cfg(not(feature = "alloc"))]
type PubKey = [u8; $module::public_key_bytes()];
#[cfg(feature = "alloc")]
type Ct = crate::bytearray::HeapArray<{ $module::ciphertext_bytes() }>;
#[cfg(not(feature = "alloc"))]
type Ct = [u8; $module::ciphertext_bytes()];
type Ss = SensitiveByteArray<[u8; $module::shared_secret_bytes()]>;
fn genkey_rng<R: Rng>(
_rng: &mut R,
) -> crate::error::KemResult<crate::KeyPair<Self::PubKey, Self::SecretKey>> {
let (pk, sk) = $module::keypair();
Ok(KeyPair {
public: ByteArray::from_slice(pk.as_bytes()),
secret: SensitiveByteArray::from_slice(sk.as_bytes()),
})
}
fn encapsulate<R: Rng>(
pk: &[u8],
_rng: &mut R,
) -> crate::error::KemResult<(Self::Ct, Self::Ss)> {
let pk = $module::PublicKey::from_bytes(pk).map_err(|_| KemError::Input)?;
let (ss, ct) = $module::encapsulate(&pk);
Ok((
Self::Ct::from_slice(ct.as_bytes()),
Self::Ss::from_slice(ss.as_bytes()),
))
}
fn decapsulate(ct: &[u8], sk: &[u8]) -> crate::error::KemResult<Self::Ss> {
let sk = $module::SecretKey::from_bytes(sk).map_err(|_| KemError::Input)?;
let ct = $module::Ciphertext::from_bytes(ct).map_err(|_| KemError::Input)?;
let ss = $module::decapsulate(&ct, &sk);
Ok(Self::Ss::from_slice(&ss.as_bytes()))
}
}
};
}
impl_ml_kem!(MlKem512, mlkem512);
impl_ml_kem!(MlKem768, mlkem768);
impl_ml_kem!(MlKem1024, mlkem1024);