#[cfg(feature = "alloc")]
use alloc::{
string::ToString,
vec::Vec,
};
use crate::api::{
Algorithm,
KemOperations,
};
use crate::error::Result;
use crate::security::SecurityValidator;
use crate::traits::{
KemKeypair,
KemPublicKey,
KemSecretKey,
};
#[cfg(feature = "alloc")]
#[derive(Clone)]
pub struct LibQKemProvider {
security_validator: SecurityValidator,
}
#[cfg(feature = "alloc")]
impl LibQKemProvider {
pub fn new() -> Result<Self> {
Ok(Self {
security_validator: SecurityValidator::new()?,
})
}
}
#[cfg(feature = "alloc")]
impl KemOperations for LibQKemProvider {
fn generate_keypair(
&self,
algorithm: Algorithm,
randomness: Option<&[u8]>,
) -> Result<KemKeypair> {
self.security_validator
.validate_algorithm_category(algorithm, crate::api::AlgorithmCategory::Kem)?;
if let Some(rng) = randomness {
self.security_validator.validate_randomness(rng)?;
}
match algorithm {
Algorithm::MlKem512 | Algorithm::MlKem768 | Algorithm::MlKem1024 => {
Err(crate::error::Error::NotImplemented {
feature: "ML-KEM implementations are provided by the main lib-q crate"
.to_string(),
})
}
Algorithm::Hqc128 | Algorithm::Hqc192 | Algorithm::Hqc256 => {
Err(crate::error::Error::NotImplemented {
feature: "HQC implementations are provided by the main lib-q crate".to_string(),
})
}
_ => Err(crate::error::Error::InvalidAlgorithm {
algorithm: "Algorithm not supported for KEM operations",
}),
}
}
fn encapsulate(
&self,
algorithm: Algorithm,
public_key: &KemPublicKey,
randomness: Option<&[u8]>,
) -> Result<(Vec<u8>, Vec<u8>)> {
self.security_validator
.validate_algorithm_category(algorithm, crate::api::AlgorithmCategory::Kem)?;
self.security_validator
.validate_public_key(algorithm, public_key.as_bytes())?;
if let Some(rng) = randomness {
self.security_validator.validate_randomness(rng)?;
}
match algorithm {
Algorithm::MlKem512 | Algorithm::MlKem768 | Algorithm::MlKem1024 => {
Err(crate::error::Error::NotImplemented {
feature: "ML-KEM implementations are provided by the main lib-q crate"
.to_string(),
})
}
Algorithm::Hqc128 | Algorithm::Hqc192 | Algorithm::Hqc256 => {
Err(crate::error::Error::NotImplemented {
feature: "HQC implementations are provided by the main lib-q crate".to_string(),
})
}
_ => Err(crate::error::Error::InvalidAlgorithm {
algorithm: "Algorithm not supported for KEM operations",
}),
}
}
fn decapsulate(
&self,
algorithm: Algorithm,
secret_key: &KemSecretKey,
ciphertext: &[u8],
) -> Result<Vec<u8>> {
self.security_validator
.validate_algorithm_category(algorithm, crate::api::AlgorithmCategory::Kem)?;
self.security_validator
.validate_secret_key(algorithm, secret_key.as_bytes())?;
self.security_validator
.validate_ciphertext(algorithm, ciphertext)?;
match algorithm {
Algorithm::MlKem512 | Algorithm::MlKem768 | Algorithm::MlKem1024 => {
Err(crate::error::Error::NotImplemented {
feature: "ML-KEM implementations are provided by the main lib-q crate"
.to_string(),
})
}
Algorithm::Hqc128 | Algorithm::Hqc192 | Algorithm::Hqc256 => {
Err(crate::error::Error::NotImplemented {
feature: "HQC implementations are provided by the main lib-q crate".to_string(),
})
}
_ => Err(crate::error::Error::InvalidAlgorithm {
algorithm: "Algorithm not supported for KEM operations",
}),
}
}
fn derive_public_key(
&self,
algorithm: Algorithm,
secret_key: &KemSecretKey,
) -> Result<KemPublicKey> {
self.security_validator
.validate_algorithm_category(algorithm, crate::api::AlgorithmCategory::Kem)?;
self.security_validator
.validate_secret_key(algorithm, secret_key.as_bytes())?;
match algorithm {
Algorithm::MlKem512 | Algorithm::MlKem768 | Algorithm::MlKem1024 => {
Err(crate::error::Error::NotImplemented {
feature: "ML-KEM implementations are provided by the main lib-q crate"
.to_string(),
})
}
Algorithm::Hqc128 | Algorithm::Hqc192 | Algorithm::Hqc256 => {
Err(crate::error::Error::NotImplemented {
feature: "HQC implementations are provided by the main lib-q crate".to_string(),
})
}
_ => Err(crate::error::Error::InvalidAlgorithm {
algorithm: "Algorithm not supported for KEM operations",
}),
}
}
}
#[cfg(test)]
#[cfg(feature = "alloc")]
mod tests {
use super::*;
#[test]
fn test_kem_provider_creation() {
let provider = LibQKemProvider::new();
assert!(
provider.is_ok(),
"LibQKemProvider should be created successfully"
);
}
#[test]
fn test_kem_provider_unsupported_algorithm() {
let provider = LibQKemProvider::new().unwrap();
let result = provider.generate_keypair(Algorithm::Sha3_256, None);
assert!(
result.is_err(),
"Should return error for unsupported algorithm"
);
if let Err(crate::error::Error::InvalidAlgorithm { .. }) = result {
} else {
panic!("Expected InvalidAlgorithm error");
}
}
#[test]
fn test_kem_provider_feature_flag_handling() {
let provider = LibQKemProvider::new().unwrap();
let result = provider.generate_keypair(Algorithm::MlKem512, None);
assert!(
result.is_err(),
"Should return error when feature flag is not enabled"
);
if let Err(crate::error::Error::NotImplemented { feature }) = result {
assert!(
feature.contains("ML-KEM implementations are provided by the main lib-q crate"),
"Error should mention that implementations are provided by main lib-q crate"
);
} else {
panic!("Expected NotImplemented error");
}
}
}