use crate::hybrid::kem_hybrid::{self as kem, HybridKemPublicKey, HybridKemSecretKey};
use crate::primitives::kem::ml_kem::MlKemSecurityLevel;
use crate::unified_api::error::{CoreError, Result};
pub fn generate_hybrid_keypair() -> Result<(HybridKemPublicKey, HybridKemSecretKey)> {
generate_hybrid_keypair_with_level(MlKemSecurityLevel::MlKem768)
}
pub fn generate_hybrid_keypair_with_level(
level: MlKemSecurityLevel,
) -> Result<(HybridKemPublicKey, HybridKemSecretKey)> {
super::api::fips_verify_operational()?;
kem::generate_keypair_with_level(level).map_err(|e| {
CoreError::EncryptionFailed(format!("Hybrid keypair generation failed: {}", e))
})
}
#[cfg(test)]
#[allow(clippy::panic, clippy::unwrap_used, clippy::expect_used, clippy::panic_in_result_fn)]
mod tests {
use super::*;
#[test]
fn test_hybrid_keypair_default_is_768_succeeds() -> Result<()> {
let (pk, _sk) = generate_hybrid_keypair()?;
assert_eq!(pk.ml_kem_pk().len(), 1184); assert_eq!(pk.ecdh_pk().len(), 32); assert_eq!(pk.security_level(), MlKemSecurityLevel::MlKem768);
Ok(())
}
#[test]
fn test_hybrid_keypair_512_succeeds() -> Result<()> {
let (pk, sk) = generate_hybrid_keypair_with_level(MlKemSecurityLevel::MlKem512)?;
assert_eq!(pk.ml_kem_pk().len(), 800);
assert_eq!(pk.security_level(), MlKemSecurityLevel::MlKem512);
assert_eq!(sk.security_level(), MlKemSecurityLevel::MlKem512);
Ok(())
}
#[test]
fn test_hybrid_keypair_768_succeeds() -> Result<()> {
let (pk, sk) = generate_hybrid_keypair_with_level(MlKemSecurityLevel::MlKem768)?;
assert_eq!(pk.ml_kem_pk().len(), 1184);
assert_eq!(pk.security_level(), MlKemSecurityLevel::MlKem768);
assert_eq!(sk.security_level(), MlKemSecurityLevel::MlKem768);
Ok(())
}
#[test]
fn test_hybrid_keypair_1024_succeeds() -> Result<()> {
let (pk, sk) = generate_hybrid_keypair_with_level(MlKemSecurityLevel::MlKem1024)?;
assert_eq!(pk.ml_kem_pk().len(), 1568);
assert_eq!(pk.security_level(), MlKemSecurityLevel::MlKem1024);
assert_eq!(sk.security_level(), MlKemSecurityLevel::MlKem1024);
Ok(())
}
#[test]
fn test_hybrid_keypair_non_deterministic() -> Result<()> {
let (pk1, _sk1) = generate_hybrid_keypair()?;
let (pk2, _sk2) = generate_hybrid_keypair()?;
assert_ne!(pk1.ml_kem_pk(), pk2.ml_kem_pk());
assert_ne!(pk1.ecdh_pk(), pk2.ecdh_pk());
Ok(())
}
}