#[cfg(feature = "std")]
use super::{
LibQAeadStubProvider,
LibQHashProvider,
LibQKemProvider,
LibQSignatureProvider,
};
use crate::api::{
AeadOperations,
CryptoProvider,
HashOperations,
KemOperations,
SignatureOperations,
};
use crate::error::Result;
#[cfg(feature = "std")]
#[derive(Clone)]
pub struct LibQCryptoProvider {
kem_provider: LibQKemProvider,
signature_provider: LibQSignatureProvider,
hash_provider: LibQHashProvider,
aead_provider: LibQAeadStubProvider,
}
#[cfg(not(feature = "std"))]
#[derive(Clone)]
pub struct LibQCryptoProvider {
kem_provider: WasmKemProvider,
signature_provider: WasmSignatureProvider,
hash_provider: WasmHashProvider,
aead_provider: WasmAeadProvider,
}
#[cfg(feature = "std")]
impl LibQCryptoProvider {
pub fn new() -> Result<Self> {
Ok(Self {
kem_provider: LibQKemProvider::new()?,
signature_provider: LibQSignatureProvider::new()?,
hash_provider: LibQHashProvider::new()?,
aead_provider: LibQAeadStubProvider::new()?,
})
}
pub fn kem_provider(&self) -> &LibQKemProvider {
&self.kem_provider
}
pub fn signature_provider(&self) -> &LibQSignatureProvider {
&self.signature_provider
}
pub fn hash_provider(&self) -> &LibQHashProvider {
&self.hash_provider
}
pub fn aead_provider(&self) -> &LibQAeadStubProvider {
&self.aead_provider
}
}
#[cfg(not(feature = "std"))]
impl LibQCryptoProvider {
pub fn new() -> Result<Self> {
Ok(Self {
kem_provider: WasmKemProvider::new()?,
signature_provider: WasmSignatureProvider::new()?,
hash_provider: WasmHashProvider::new()?,
aead_provider: WasmAeadProvider::new()?,
})
}
pub fn kem_provider(&self) -> &WasmKemProvider {
&self.kem_provider
}
pub fn signature_provider(&self) -> &WasmSignatureProvider {
&self.signature_provider
}
pub fn hash_provider(&self) -> &WasmHashProvider {
&self.hash_provider
}
pub fn aead_provider(&self) -> &WasmAeadProvider {
&self.aead_provider
}
}
#[cfg(feature = "std")]
impl CryptoProvider for LibQCryptoProvider {
fn kem(&self) -> Option<&dyn KemOperations> {
Some(&self.kem_provider)
}
fn signature(&self) -> Option<&dyn SignatureOperations> {
Some(&self.signature_provider)
}
fn hash(&self) -> Option<&dyn HashOperations> {
Some(&self.hash_provider)
}
fn aead(&self) -> Option<&dyn AeadOperations> {
Some(&self.aead_provider)
}
}
#[cfg(not(feature = "std"))]
impl CryptoProvider for LibQCryptoProvider {
fn kem(&self) -> Option<&dyn KemOperations> {
Some(&self.kem_provider)
}
fn signature(&self) -> Option<&dyn SignatureOperations> {
Some(&self.signature_provider)
}
fn hash(&self) -> Option<&dyn HashOperations> {
Some(&self.hash_provider)
}
fn aead(&self) -> Option<&dyn AeadOperations> {
Some(&self.aead_provider)
}
}
#[cfg(not(feature = "std"))]
use alloc::format;
#[cfg(not(feature = "std"))]
use crate::security::SecurityValidator;
#[cfg(not(feature = "std"))]
use crate::traits::{
AeadKey,
KemKeypair,
KemPublicKey,
KemSecretKey,
Nonce,
SigKeypair,
SigPublicKey,
SigSecretKey,
};
#[cfg(not(feature = "std"))]
#[derive(Clone)]
pub struct WasmKemProvider {
security_validator: SecurityValidator,
}
#[cfg(not(feature = "std"))]
impl WasmKemProvider {
pub fn new() -> Result<Self> {
Ok(Self {
security_validator: SecurityValidator::new()?,
})
}
}
#[cfg(not(feature = "std"))]
impl KemOperations for WasmKemProvider {
fn generate_keypair(
&self,
algorithm: crate::api::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)?;
}
Err(crate::error::Error::NotImplemented {
feature: format!(
"WASM KEM operations for {} - implementations are provided by the main lib-q crate",
algorithm
),
})
}
fn encapsulate(
&self,
algorithm: crate::api::Algorithm,
public_key: &KemPublicKey,
randomness: Option<&[u8]>,
) -> Result<(alloc::vec::Vec<u8>, alloc::vec::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)?;
}
Err(crate::error::Error::NotImplemented {
feature: format!(
"WASM KEM operations for {} - implementations are provided by the main lib-q crate",
algorithm
),
})
}
fn decapsulate(
&self,
algorithm: crate::api::Algorithm,
secret_key: &KemSecretKey,
ciphertext: &[u8],
) -> Result<alloc::vec::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)?;
Err(crate::error::Error::NotImplemented {
feature: format!(
"WASM KEM operations for {} - implementations are provided by the main lib-q crate",
algorithm
),
})
}
fn derive_public_key(
&self,
algorithm: crate::api::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())?;
Err(crate::error::Error::NotImplemented {
feature: format!(
"WASM KEM operations for {} - implementations are provided by the main lib-q crate",
algorithm
),
})
}
}
#[cfg(not(feature = "std"))]
#[derive(Clone)]
pub struct WasmSignatureProvider {
security_validator: SecurityValidator,
}
#[cfg(not(feature = "std"))]
impl WasmSignatureProvider {
pub fn new() -> Result<Self> {
Ok(Self {
security_validator: SecurityValidator::new()?,
})
}
}
#[cfg(not(feature = "std"))]
impl SignatureOperations for WasmSignatureProvider {
fn generate_keypair(
&self,
algorithm: crate::api::Algorithm,
randomness: Option<&[u8]>,
) -> Result<SigKeypair> {
self.security_validator
.validate_algorithm_category(algorithm, crate::api::AlgorithmCategory::Signature)?;
if let Some(rng) = randomness {
self.security_validator.validate_randomness(rng)?;
}
Err(crate::error::Error::NotImplemented {
feature: format!(
"WASM Signature operations for {} - implementations are provided by the main lib-q crate",
algorithm
),
})
}
fn sign(
&self,
algorithm: crate::api::Algorithm,
secret_key: &SigSecretKey,
message: &[u8],
randomness: Option<&[u8]>,
) -> Result<alloc::vec::Vec<u8>> {
self.security_validator
.validate_algorithm_category(algorithm, crate::api::AlgorithmCategory::Signature)?;
self.security_validator
.validate_secret_key(algorithm, secret_key.as_bytes())?;
self.security_validator
.validate_signature_message(message)?;
if let Some(rng) = randomness {
self.security_validator.validate_randomness(rng)?;
}
Err(crate::error::Error::NotImplemented {
feature: format!(
"WASM Signature operations for {} - implementations are provided by the main lib-q crate",
algorithm
),
})
}
fn verify(
&self,
algorithm: crate::api::Algorithm,
public_key: &SigPublicKey,
message: &[u8],
signature: &[u8],
) -> Result<bool> {
self.security_validator
.validate_algorithm_category(algorithm, crate::api::AlgorithmCategory::Signature)?;
self.security_validator
.validate_public_key(algorithm, public_key.as_bytes())?;
self.security_validator
.validate_signature_message(message)?;
self.security_validator
.validate_signature(algorithm, signature)?;
Err(crate::error::Error::NotImplemented {
feature: format!(
"WASM Signature operations for {} - implementations are provided by the main lib-q crate",
algorithm
),
})
}
}
#[cfg(not(feature = "std"))]
#[derive(Clone)]
pub struct WasmHashProvider {
security_validator: SecurityValidator,
}
#[cfg(not(feature = "std"))]
impl WasmHashProvider {
pub fn new() -> Result<Self> {
Ok(Self {
security_validator: SecurityValidator::new()?,
})
}
}
#[cfg(not(feature = "std"))]
impl HashOperations for WasmHashProvider {
fn hash(&self, algorithm: crate::api::Algorithm, data: &[u8]) -> Result<alloc::vec::Vec<u8>> {
self.security_validator
.validate_algorithm_category(algorithm, crate::api::AlgorithmCategory::Hash)?;
self.security_validator.validate_hash_input(data)?;
Err(crate::error::Error::NotImplemented {
feature: format!(
"WASM Hash operations for {} - implementations are provided by the main lib-q crate",
algorithm
),
})
}
}
#[cfg(not(feature = "std"))]
#[derive(Clone)]
pub struct WasmAeadProvider {
security_validator: SecurityValidator,
}
#[cfg(not(feature = "std"))]
impl WasmAeadProvider {
pub fn new() -> Result<Self> {
Ok(Self {
security_validator: SecurityValidator::new()?,
})
}
}
#[cfg(not(feature = "std"))]
impl AeadOperations for WasmAeadProvider {
fn encrypt(
&self,
algorithm: crate::api::Algorithm,
key: &AeadKey,
nonce: &Nonce,
plaintext: &[u8],
associated_data: Option<&[u8]>,
) -> Result<alloc::vec::Vec<u8>> {
self.security_validator
.validate_algorithm_category(algorithm, crate::api::AlgorithmCategory::Aead)?;
self.security_validator
.validate_key_material(key.as_bytes())?;
self.security_validator.validate_nonce(nonce.as_bytes())?;
self.security_validator.validate_aead_message(plaintext)?;
if let Some(ad) = associated_data {
self.security_validator.validate_aead_message(ad)?;
}
Err(crate::error::Error::NotImplemented {
feature: format!(
"WASM AEAD operations for {} - implementations are provided by the main lib-q crate",
algorithm
),
})
}
fn decrypt(
&self,
algorithm: crate::api::Algorithm,
key: &AeadKey,
nonce: &Nonce,
ciphertext: &[u8],
associated_data: Option<&[u8]>,
) -> Result<alloc::vec::Vec<u8>> {
self.security_validator
.validate_algorithm_category(algorithm, crate::api::AlgorithmCategory::Aead)?;
self.security_validator
.validate_key_material(key.as_bytes())?;
self.security_validator.validate_nonce(nonce.as_bytes())?;
self.security_validator
.validate_ciphertext(algorithm, ciphertext)?;
if let Some(ad) = associated_data {
self.security_validator.validate_aead_message(ad)?;
}
Err(crate::error::Error::NotImplemented {
feature: format!(
"WASM AEAD operations for {} - implementations are provided by the main lib-q crate",
algorithm
),
})
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::panic)]
use super::*;
#[test]
fn test_libq_provider_creation() {
let provider = LibQCryptoProvider::new();
assert!(
provider.is_ok(),
"LibQCryptoProvider should be created successfully"
);
}
#[test]
fn test_libq_provider_default() {
let provider = match LibQCryptoProvider::new() {
Ok(p) => p,
Err(e) => panic!("LibQCryptoProvider::new() failed: {e}"),
};
assert!(provider.kem().is_some(), "KEM provider should be available");
assert!(
provider.signature().is_some(),
"Signature provider should be available"
);
assert!(
provider.hash().is_some(),
"Hash provider should be available"
);
assert!(
provider.aead().is_some(),
"AEAD provider should be available"
);
}
#[test]
fn test_libq_provider_operations() {
let provider = match LibQCryptoProvider::new() {
Ok(p) => p,
Err(e) => panic!("LibQCryptoProvider::new() failed: {e}"),
};
assert!(provider.kem().is_some());
assert!(provider.signature().is_some());
assert!(provider.hash().is_some());
assert!(provider.aead().is_some());
}
}