#![cfg_attr(not(feature = "std"), no_std)]
#![deny(unsafe_code)]
#![deny(unused_qualifications)]
#![allow(clippy::doc_lazy_continuation)]
#![allow(clippy::manual_div_ceil)]
#![allow(clippy::manual_memcpy)]
#![allow(clippy::needless_range_loop)]
#![allow(clippy::unusual_byte_groupings)]
#[cfg(feature = "alloc")]
extern crate alloc;
pub use lib_q_core::{
Algorithm,
AlgorithmCategory,
Error,
Kem,
KemContext,
KemKeypair,
KemOperations,
KemPublicKey,
KemSecretKey,
Result,
};
pub mod concatenated_code;
pub mod error;
pub mod field;
pub mod hqc_correct;
pub mod hqc_kem;
pub mod hqc_pke;
pub mod params_correct;
pub mod reed_muller;
pub mod reed_solomon;
pub mod shake256_prng;
#[cfg(feature = "aes-drbg")]
pub mod aes_ctr_drbg;
#[cfg(feature = "bearssl-aes")]
pub mod bearssl_aes_ctr_drbg;
#[cfg(feature = "bearssl-aes")]
pub mod bearssl_aes_pure;
#[cfg(all(
feature = "aes-drbg",
feature = "bearssl-aes",
feature = "debug-drbg-interop"
))]
pub mod drbg_diagnostic;
pub mod internal;
pub mod simd;
pub mod kat_prng;
#[cfg(feature = "alloc")]
pub mod provider;
pub use error::HqcError;
pub use hqc_correct::*;
pub use params_correct::*;
#[cfg(feature = "alloc")]
pub use provider::LibQHqcProvider;
#[cfg(feature = "wasm")]
mod wasm;
#[cfg(feature = "std")]
pub fn available_algorithms() -> Vec<&'static str> {
vec![
#[cfg(feature = "hqc128")]
"HQC-128",
#[cfg(feature = "hqc192")]
"HQC-192",
#[cfg(feature = "hqc256")]
"HQC-256",
]
}
#[cfg(not(feature = "std"))]
pub fn available_algorithms() -> &'static [&'static str] {
&[
#[cfg(feature = "hqc128")]
"HQC-128",
#[cfg(feature = "hqc192")]
"HQC-192",
#[cfg(feature = "hqc256")]
"HQC-256",
]
}
pub fn create_kem_context(algorithm: Algorithm) -> Result<KemContext> {
if algorithm.category() != AlgorithmCategory::Kem {
return Err(Error::InvalidAlgorithm {
algorithm: "Algorithm is not a KEM algorithm",
});
}
Ok(KemContext::new())
}
#[cfg(all(test, feature = "alloc"))]
mod tests {
use super::*;
#[test]
fn test_available_algorithms() {
let algorithms = available_algorithms();
#[cfg(feature = "hqc128")]
{
assert!(
algorithms.contains(&"HQC-128"),
"HQC-128 should be available when hqc128 feature is enabled"
);
}
#[cfg(feature = "hqc192")]
{
assert!(
algorithms.contains(&"HQC-192"),
"HQC-192 should be available when hqc192 feature is enabled"
);
}
#[cfg(feature = "hqc256")]
{
assert!(
algorithms.contains(&"HQC-256"),
"HQC-256 should be available when hqc256 feature is enabled"
);
}
#[cfg(any(feature = "hqc128", feature = "hqc192", feature = "hqc256"))]
assert!(
!algorithms.is_empty(),
"Should have at least one algorithm when features are enabled"
);
#[cfg(not(any(feature = "hqc128", feature = "hqc192", feature = "hqc256")))]
assert!(
algorithms.is_empty(),
"Should have no algorithms when no features are enabled"
);
}
#[test]
fn test_create_kem_context() {
let result = create_kem_context(Algorithm::Hqc128);
assert!(
result.is_ok(),
"Context creation should succeed for valid KEM algorithm"
);
let mut ctx = result.unwrap();
let keypair_result = ctx.generate_keypair(Algorithm::Hqc128, None);
assert!(
keypair_result.is_err(),
"Keypair generation should fail without provider"
);
if let Err(err) = keypair_result {
assert!(matches!(err, Error::ProviderNotConfigured { .. }));
}
}
#[test]
fn test_create_kem_context_invalid_algorithm() {
let result = create_kem_context(Algorithm::MlDsa65);
assert!(result.is_err());
}
#[test]
fn test_algorithm_naming_consistency() {
let algorithms = available_algorithms();
for algorithm in algorithms {
assert!(
algorithm.starts_with("HQC-"),
"Algorithm name '{}' should follow NIST naming conventions",
algorithm
);
}
}
}