use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
use super::types::{
DilithiumParams, DilithiumVariant, FalconParams, FalconVariant, HashBasedSignature,
IsogenyCrypto, KyberVariant, LWESampleGenerator, LatticeBasisReducer, McElieceParams,
ModularLatticeArithmetic, RingPoly, SphincsParams, ToyLWE, ToyLamport, ToyMerkleTree,
};
pub fn app(f: Expr, a: Expr) -> Expr {
Expr::App(Box::new(f), Box::new(a))
}
pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
app(app(f, a), b)
}
pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
app(app2(f, a, b), c)
}
pub fn cst(s: &str) -> Expr {
Expr::Const(Name::str(s), vec![])
}
pub fn prop() -> Expr {
Expr::Sort(Level::zero())
}
pub fn type0() -> Expr {
Expr::Sort(Level::succ(Level::zero()))
}
pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
}
pub fn arrow(a: Expr, b: Expr) -> Expr {
pi(BinderInfo::Default, "_", a, b)
}
pub fn nat_ty() -> Expr {
cst("Nat")
}
pub fn real_ty() -> Expr {
cst("Real")
}
pub fn bool_ty() -> Expr {
cst("Bool")
}
pub fn list_nat() -> Expr {
app(cst("List"), nat_ty())
}
pub fn bytes_ty() -> Expr {
list_nat()
}
pub fn lattice_ty() -> Expr {
arrow(nat_ty(), type0())
}
pub fn lattice_vector_ty() -> Expr {
arrow(nat_ty(), type0())
}
pub fn shortest_vector_ty() -> Expr {
arrow(
app(cst("Lattice"), nat_ty()),
arrow(app(cst("LatticeVector"), nat_ty()), prop()),
)
}
pub fn closest_vector_ty() -> Expr {
arrow(
app(cst("Lattice"), nat_ty()),
arrow(
app(cst("LatticeVector"), nat_ty()),
arrow(app(cst("LatticeVector"), nat_ty()), prop()),
),
)
}
pub fn gaussian_heuristic_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn lwe_distribution_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn lwe_hardness_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn lwe_encryption_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn lwe_regev_theorem_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn rlwe_distribution_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn rlwe_hardness_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn rlwe_to_lwe_reduction_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn ntru_params_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn ntru_public_key_ty() -> Expr {
arrow(app2(cst("NTRUParams"), nat_ty(), nat_ty()), type0())
}
pub fn ntru_hardness_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn ntru_correctness_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn kyber_params_ty() -> Expr {
type0()
}
pub fn kyber_key_pair_ty() -> Expr {
arrow(kyber_params_ty(), type0())
}
pub fn kyber_ind_cca2_ty() -> Expr {
arrow(kyber_params_ty(), prop())
}
pub fn kyber_mlwe_hardness_ty() -> Expr {
arrow(kyber_params_ty(), prop())
}
pub fn dilithium_params_ty() -> Expr {
type0()
}
pub fn dilithium_signature_ty() -> Expr {
arrow(dilithium_params_ty(), type0())
}
pub fn dilithium_euf_cma_ty() -> Expr {
arrow(dilithium_params_ty(), prop())
}
pub fn falcon_params_ty() -> Expr {
type0()
}
pub fn falcon_signature_ty() -> Expr {
arrow(falcon_params_ty(), type0())
}
pub fn falcon_euf_cma_ty() -> Expr {
arrow(falcon_params_ty(), prop())
}
pub fn lamport_params_ty() -> Expr {
arrow(nat_ty(), type0())
}
pub fn lamport_one_time_use_ty() -> Expr {
arrow(app(cst("LamportParams"), nat_ty()), prop())
}
pub fn merkle_tree_ty() -> Expr {
arrow(nat_ty(), type0())
}
pub fn merkle_signature_ty() -> Expr {
arrow(app(cst("MerkleTree"), nat_ty()), type0())
}
pub fn merkle_signature_correctness_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn sphincs_plus_params_ty() -> Expr {
type0()
}
pub fn sphincs_plus_stateless_ty() -> Expr {
arrow(sphincs_plus_params_ty(), prop())
}
pub fn sphincs_plus_euf_cma_ty() -> Expr {
arrow(sphincs_plus_params_ty(), prop())
}
pub fn binary_goppa_code_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), type0())))
}
pub fn mceliece_public_key_ty() -> Expr {
arrow(
app3(cst("BinaryGoppaCode"), nat_ty(), nat_ty(), nat_ty()),
type0(),
)
}
pub fn mceliece_hardness_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), prop())))
}
pub fn mceliece_cryptosystem_ty() -> Expr {
type0()
}
pub fn supersingular_curve_ty() -> Expr {
type0()
}
pub fn isogeny_ty() -> Expr {
arrow(
supersingular_curve_ty(),
arrow(supersingular_curve_ty(), arrow(nat_ty(), type0())),
)
}
pub fn sidh_key_exchange_ty() -> Expr {
type0()
}
pub fn sidh_broken_ty() -> Expr {
prop()
}
pub fn csidh_hardness_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn quantum_random_oracle_ty() -> Expr {
type0()
}
pub fn qrom_security_ty() -> Expr {
arrow(quantum_random_oracle_ty(), prop())
}
pub fn fiat_shamir_qrom_ty() -> Expr {
prop()
}
pub fn qrom_forking_lemma_ty() -> Expr {
prop()
}
pub fn sis_hardness_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), prop())))
}
pub fn sis_cryptosystem_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn module_lwe_distribution_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), type0())))
}
pub fn module_lwe_hardness_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn module_sis_hardness_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn niederreiter_cryptosystem_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), type0())))
}
pub fn goppa_code_decodability_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), prop())))
}
pub fn code_based_signature_ty() -> Expr {
type0()
}
pub fn syndrome_decoding_hardness_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn xmss_params_ty() -> Expr {
type0()
}
pub fn xmss_signature_ty() -> Expr {
arrow(xmss_params_ty(), type0())
}
pub fn xmss_stateful_ty() -> Expr {
arrow(xmss_params_ty(), prop())
}
pub fn lms_params_ty() -> Expr {
type0()
}
pub fn lms_signature_ty() -> Expr {
arrow(lms_params_ty(), type0())
}
pub fn hash_based_euf_cma_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn csidh_public_key_ty() -> Expr {
arrow(nat_ty(), type0())
}
pub fn csidh_group_action_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn sqisign_params_ty() -> Expr {
type0()
}
pub fn sqisign_euf_cma_ty() -> Expr {
arrow(sqisign_params_ty(), prop())
}
pub fn endomorphism_ring_hardness_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn mq_hardness_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn rainbow_signature_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn uov_signature_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn uov_security_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn multivariate_key_recovery_hardness_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn lattice_zk_proof_ty() -> Expr {
arrow(nat_ty(), type0())
}
pub fn lattice_sigma_protocol_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn lattice_soundness_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn rejection_sampling_lemma_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn lattice_zk_succinctness_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn bkz_algorithm_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn bkz_quality_bound_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn sieving_algorithm_ty() -> Expr {
arrow(nat_ty(), type0())
}
pub fn sieving_complexity_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn lattice_enumeration_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn gram_schmidt_ty() -> Expr {
arrow(nat_ty(), type0())
}
pub fn ml_kem_params_ty() -> Expr {
type0()
}
pub fn ml_kem_correctness_ty() -> Expr {
arrow(ml_kem_params_ty(), prop())
}
pub fn ml_dsa_params_ty() -> Expr {
type0()
}
pub fn ml_dsa_detached_signature_ty() -> Expr {
arrow(ml_dsa_params_ty(), type0())
}
pub fn slh_dsa_params_ty() -> Expr {
type0()
}
pub fn slh_dsa_statelessness_ty() -> Expr {
arrow(slh_dsa_params_ty(), prop())
}
pub fn nist_pqc_security_level_ty() -> Expr {
type0()
}
pub fn qrom_reduction_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn o2h_lemma_ty() -> Expr {
prop()
}
pub fn fujisaki_okamoto_qrom_ty() -> Expr {
prop()
}
pub fn quantum_secure_hash_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn hybrid_kem_ty() -> Expr {
type0()
}
pub fn hybrid_kem_security_ty() -> Expr {
arrow(hybrid_kem_ty(), prop())
}
pub fn pqc_migration_strategy_ty() -> Expr {
type0()
}
pub fn crypto_agility_ty() -> Expr {
type0()
}
pub fn tls_pqc_extension_ty() -> Expr {
prop()
}
pub fn build_post_quantum_crypto_env(env: &mut Environment) -> Result<(), String> {
let axioms: &[(&str, Expr)] = &[
("PQC.Lattice", lattice_ty()),
("PQC.LatticeVector", lattice_vector_ty()),
("PQC.ShortestVector", shortest_vector_ty()),
("PQC.ClosestVector", closest_vector_ty()),
("PQC.GaussianHeuristic", gaussian_heuristic_ty()),
("PQC.LWEDistribution", lwe_distribution_ty()),
("PQC.LWEHardness", lwe_hardness_ty()),
("PQC.LWEEncryption", lwe_encryption_ty()),
("PQC.LWERegevTheorem", lwe_regev_theorem_ty()),
("PQC.RingLWEDistribution", rlwe_distribution_ty()),
("PQC.RingLWEHardness", rlwe_hardness_ty()),
("PQC.RingLWEToLWEReduction", rlwe_to_lwe_reduction_ty()),
("PQC.NTRUParams", ntru_params_ty()),
("PQC.NTRUPublicKey", ntru_public_key_ty()),
("PQC.NTRUHardness", ntru_hardness_ty()),
("PQC.NTRUCorrectness", ntru_correctness_ty()),
("PQC.KyberParams", kyber_params_ty()),
("PQC.KyberKeyPair", kyber_key_pair_ty()),
("PQC.KyberIND_CCA2", kyber_ind_cca2_ty()),
("PQC.KyberMLWEHardness", kyber_mlwe_hardness_ty()),
("PQC.DilithiumParams", dilithium_params_ty()),
("PQC.DilithiumSignature", dilithium_signature_ty()),
("PQC.DilithiumEUF_CMA", dilithium_euf_cma_ty()),
("PQC.FalconParams", falcon_params_ty()),
("PQC.FalconSignature", falcon_signature_ty()),
("PQC.FalconEUF_CMA", falcon_euf_cma_ty()),
("PQC.LamportParams", lamport_params_ty()),
("PQC.LamportOneTimeUse", lamport_one_time_use_ty()),
("PQC.MerkleTree", merkle_tree_ty()),
("PQC.MerkleSignature", merkle_signature_ty()),
(
"PQC.MerkleSignatureCorrectness",
merkle_signature_correctness_ty(),
),
("PQC.SPHINCSPlusParams", sphincs_plus_params_ty()),
("PQC.SPHINCSPlusStateless", sphincs_plus_stateless_ty()),
("PQC.SPHINCSPlusEUF_CMA", sphincs_plus_euf_cma_ty()),
("PQC.BinaryGoppaCode", binary_goppa_code_ty()),
("PQC.McEliecePublicKey", mceliece_public_key_ty()),
("PQC.McElieceHardness", mceliece_hardness_ty()),
("PQC.McElieceCryptosystem", mceliece_cryptosystem_ty()),
("PQC.SupersingularCurve", supersingular_curve_ty()),
("PQC.Isogeny", isogeny_ty()),
("PQC.SIDHKeyExchange", sidh_key_exchange_ty()),
("PQC.SIDHBrokenByCastryckDecru", sidh_broken_ty()),
("PQC.CSIDHHardness", csidh_hardness_ty()),
("PQC.QuantumRandomOracle", quantum_random_oracle_ty()),
("PQC.QROMSecurity", qrom_security_ty()),
("PQC.FiatShamirQROM", fiat_shamir_qrom_ty()),
("PQC.QROMForkingLemma", qrom_forking_lemma_ty()),
("PQC.SISHardness", sis_hardness_ty()),
("PQC.SISCryptosystem", sis_cryptosystem_ty()),
("PQC.ModuleLWEDistribution", module_lwe_distribution_ty()),
("PQC.ModuleLWEHardness", module_lwe_hardness_ty()),
("PQC.ModuleSISHardness", module_sis_hardness_ty()),
(
"PQC.NiederreiterCryptosystem",
niederreiter_cryptosystem_ty(),
),
("PQC.GoppaCodeDecodability", goppa_code_decodability_ty()),
("PQC.CodeBasedSignature", code_based_signature_ty()),
(
"PQC.SyndromeDecodingHardness",
syndrome_decoding_hardness_ty(),
),
("PQC.XMSSParams", xmss_params_ty()),
("PQC.XMSSSignature", xmss_signature_ty()),
("PQC.XMSSStateful", xmss_stateful_ty()),
("PQC.LMSParams", lms_params_ty()),
("PQC.LMSSignature", lms_signature_ty()),
("PQC.HashBasedEUF_CMA", hash_based_euf_cma_ty()),
("PQC.CSIDHPublicKey", csidh_public_key_ty()),
("PQC.CSIDHGroupAction", csidh_group_action_ty()),
("PQC.SQISignParams", sqisign_params_ty()),
("PQC.SQISignEUF_CMA", sqisign_euf_cma_ty()),
(
"PQC.EndomorphismRingHardness",
endomorphism_ring_hardness_ty(),
),
("PQC.MQHardness", mq_hardness_ty()),
("PQC.RainbowSignature", rainbow_signature_ty()),
("PQC.UOVSignature", uov_signature_ty()),
("PQC.UOVSecurity", uov_security_ty()),
(
"PQC.MultivariateKeyRecoveryHardness",
multivariate_key_recovery_hardness_ty(),
),
("PQC.LatticeZKProof", lattice_zk_proof_ty()),
("PQC.LatticeSigmaProtocol", lattice_sigma_protocol_ty()),
("PQC.LatticeSoundness", lattice_soundness_ty()),
("PQC.RejectionSamplingLemma", rejection_sampling_lemma_ty()),
("PQC.LatticeZKSuccinctness", lattice_zk_succinctness_ty()),
("PQC.BKZAlgorithm", bkz_algorithm_ty()),
("PQC.BKZQualityBound", bkz_quality_bound_ty()),
("PQC.SievingAlgorithm", sieving_algorithm_ty()),
("PQC.SievingComplexity", sieving_complexity_ty()),
("PQC.LatticeEnumeration", lattice_enumeration_ty()),
("PQC.GramSchmidt", gram_schmidt_ty()),
("PQC.MLKEMParams", ml_kem_params_ty()),
("PQC.MLKEMCorrectness", ml_kem_correctness_ty()),
("PQC.MLDSAParams", ml_dsa_params_ty()),
("PQC.MLDSADetachedSignature", ml_dsa_detached_signature_ty()),
("PQC.SLHDSAParams", slh_dsa_params_ty()),
("PQC.SLHDSAStatelessness", slh_dsa_statelessness_ty()),
("PQC.NISTPQCSecurityLevel", nist_pqc_security_level_ty()),
("PQC.QROMReduction", qrom_reduction_ty()),
("PQC.O2HLemma", o2h_lemma_ty()),
("PQC.FujisakiOkamotoQROM", fujisaki_okamoto_qrom_ty()),
("PQC.QuantumSecureHash", quantum_secure_hash_ty()),
("PQC.HybridKEM", hybrid_kem_ty()),
("PQC.HybridKEMSecurity", hybrid_kem_security_ty()),
("PQC.PQCMigrationStrategy", pqc_migration_strategy_ty()),
("PQC.CryptoAgility", crypto_agility_ty()),
("PQC.TLSPQCExtension", tls_pqc_extension_ty()),
];
for (name, ty) in axioms {
env.add(Declaration::Axiom {
name: Name::str(*name),
univ_params: vec![],
ty: ty.clone(),
})
.ok();
}
Ok(())
}
pub(super) fn merkle_hash(a: u64, b: u64) -> u64 {
a.wrapping_mul(0x9e3779b97f4a7c15)
.wrapping_add(b)
.rotate_left(17)
.wrapping_add(0x6c62272e07bb0142)
}
#[cfg(test)]
mod tests {
use super::*;
use oxilean_kernel::Environment;
#[test]
fn test_build_env() {
let mut env = Environment::new();
let result = build_post_quantum_crypto_env(&mut env);
assert!(
result.is_ok(),
"build_post_quantum_crypto_env failed: {:?}",
result
);
}
#[test]
fn test_kyber_variants() {
assert_eq!(KyberVariant::Kyber512.k(), 2);
assert_eq!(KyberVariant::Kyber768.k(), 3);
assert_eq!(KyberVariant::Kyber1024.k(), 4);
assert_eq!(KyberVariant::Kyber512.security_bits(), 128);
assert_eq!(KyberVariant::Kyber768.security_bits(), 192);
assert_eq!(KyberVariant::Kyber1024.security_bits(), 256);
}
#[test]
fn test_dilithium_variants() {
let (k2, l2) = DilithiumVariant::Dilithium2.dimensions();
assert_eq!((k2, l2), (4, 4));
let (k5, l5) = DilithiumVariant::Dilithium5.dimensions();
assert_eq!((k5, l5), (8, 7));
assert!(
DilithiumVariant::Dilithium3.signature_bytes()
> DilithiumVariant::Dilithium2.signature_bytes()
);
}
#[test]
fn test_falcon_variants() {
assert_eq!(FalconVariant::Falcon512.degree(), 512);
assert_eq!(FalconVariant::Falcon1024.degree(), 1024);
assert_eq!(FalconVariant::Falcon512.modulus(), 12289);
assert_eq!(FalconVariant::Falcon1024.modulus(), 12289);
}
#[test]
fn test_ring_poly_add_mul() {
let _n = 4;
let q = 17i64;
let a = RingPoly {
coeffs: vec![1, 2, 3, 4],
q,
};
let b = RingPoly {
coeffs: vec![4, 3, 2, 1],
q,
};
let sum = a.add(&b);
assert_eq!(
sum.coeffs,
vec![5, 5, 5, 5],
"Polynomial addition should be coefficient-wise"
);
let diff = a.sub(&b);
assert_eq!(diff.coeffs[0], -3);
assert_eq!(diff.coeffs[2], 1);
let one = RingPoly {
coeffs: vec![0, 1, 0, 0],
q,
};
let two = RingPoly {
coeffs: vec![0, 1, 0, 0],
q,
};
let prod = one.mul(&two);
assert_eq!(
prod.coeffs[2], 1,
"x * x = x^2 coefficient at index 2 should be 1"
);
}
#[test]
fn test_lamport_sign_verify() {
let lamport = ToyLamport { n: 8 };
let kp = lamport.keygen(12345);
let msg_bits: Vec<u8> = vec![1, 0, 1, 1, 0, 0, 1, 0];
let sig = lamport.sign(&kp, &msg_bits);
assert!(
lamport.verify(&kp, &msg_bits, &sig),
"Valid Lamport signature should verify"
);
let mut bad_bits = msg_bits.clone();
bad_bits[3] = 1 - bad_bits[3];
assert!(
!lamport.verify(&kp, &bad_bits, &sig),
"Tampered message should not verify"
);
}
#[test]
fn test_merkle_tree() {
let leaves = [100u64, 200, 300, 400];
let tree = ToyMerkleTree::build(leaves);
for i in 0..4 {
let path = tree.auth_path(i);
assert!(
tree.verify_leaf(leaves[i], i, path),
"Merkle auth path verification failed for leaf {}",
i
);
}
let path0 = tree.auth_path(0);
assert!(
!tree.verify_leaf(999, 0, path0),
"Wrong leaf value should fail Merkle verification"
);
}
#[test]
fn test_axioms_registered() {
let mut env = Environment::new();
build_post_quantum_crypto_env(&mut env)
.expect("build_post_quantum_crypto_env should succeed");
let expected = [
"PQC.LWEHardness",
"PQC.RingLWEHardness",
"PQC.NTRUHardness",
"PQC.KyberIND_CCA2",
"PQC.DilithiumEUF_CMA",
"PQC.FalconEUF_CMA",
"PQC.SPHINCSPlusEUF_CMA",
"PQC.McElieceHardness",
"PQC.SIDHBrokenByCastryckDecru",
"PQC.QROMForkingLemma",
];
for name in &expected {
assert!(
env.get(&Name::str(*name)).is_some(),
"Expected axiom '{}' not found in environment",
name
);
}
}
#[test]
fn test_new_axioms_registered() {
let mut env = Environment::new();
build_post_quantum_crypto_env(&mut env)
.expect("build_post_quantum_crypto_env should succeed");
let expected = [
"PQC.SISHardness",
"PQC.ModuleLWEHardness",
"PQC.ModuleSISHardness",
"PQC.NiederreiterCryptosystem",
"PQC.SyndromeDecodingHardness",
"PQC.XMSSParams",
"PQC.LMSParams",
"PQC.HashBasedEUF_CMA",
"PQC.CSIDHGroupAction",
"PQC.SQISignEUF_CMA",
"PQC.EndomorphismRingHardness",
"PQC.MQHardness",
"PQC.UOVSecurity",
"PQC.LatticeZKProof",
"PQC.RejectionSamplingLemma",
"PQC.BKZAlgorithm",
"PQC.SievingComplexity",
"PQC.GramSchmidt",
"PQC.MLKEMParams",
"PQC.MLDSAParams",
"PQC.SLHDSAParams",
"PQC.NISTPQCSecurityLevel",
"PQC.O2HLemma",
"PQC.FujisakiOkamotoQROM",
"PQC.HybridKEM",
"PQC.HybridKEMSecurity",
"PQC.TLSPQCExtension",
];
for name in &expected {
assert!(
env.get(&Name::str(*name)).is_some(),
"Expected axiom '{}' not found in environment",
name
);
}
}
#[test]
fn test_lwe_sample_generator() {
let mut gen = LWESampleGenerator::new(8, 97, 3, 42);
let s: Vec<i64> = vec![1, 0, 1, 1, 0, 0, 1, 0];
let samples = gen.sample_many(&s, 10);
assert_eq!(samples.len(), 10);
for (a, bval) in &samples {
assert_eq!(a.len(), 8);
assert!(a.iter().all(|&x| x >= 0 && x < 97));
assert!(*bval >= 0 && *bval < 97);
}
}
#[test]
fn test_lattice_basis_reducer() {
let reducer = LatticeBasisReducer::new(0.75);
let b0 = [3i64, 1];
let b1 = [1i64, 3];
let (r0, r1) = reducer.reduce_2d(b0, b1);
let norm_orig = LatticeBasisReducer::norm_sq(b0) + LatticeBasisReducer::norm_sq(b1);
let norm_red = LatticeBasisReducer::norm_sq(r0) + LatticeBasisReducer::norm_sq(r1);
assert!(norm_red <= norm_orig, "Reduced basis should not be longer");
assert!(reducer.is_lll_reduced_2d(r0, r1));
}
#[test]
fn test_hash_based_signature_wots() {
let wots = HashBasedSignature::new(4, 8);
let kp = wots.keygen(999);
let msg: Vec<usize> = vec![0, 1, 2, 3, 0, 1, 2, 3];
let sig = wots.sign(&kp, &msg);
assert!(
wots.verify(&kp, &msg, &sig),
"WOTS+ signature should verify"
);
let bad_msg: Vec<usize> = vec![0, 1, 2, 3, 0, 1, 2, 0];
assert!(
!wots.verify(&kp, &bad_msg, &sig),
"Wrong message should not verify"
);
}
#[test]
fn test_modular_lattice_arithmetic() {
let arith = ModularLatticeArithmetic::new(4, 17);
let a = vec![1i64, 2, 3, 4];
let b = vec![4i64, 3, 2, 1];
let sum = arith.poly_add(&a, &b);
assert_eq!(sum, vec![5, 5, 5, 5]);
let diff = arith.poly_sub(&a, &b);
assert_eq!(diff[0], arith.reduce(1 - 4));
assert_eq!(diff[2], arith.reduce(3 - 2));
let x_poly = vec![0i64, 1, 0, 0];
let prod = arith.poly_mul(&x_poly, &x_poly);
assert_eq!(prod[2], 1);
assert_eq!(prod[0], 0);
let small = vec![0i64, 1, -1, 2];
assert_eq!(arith.inf_norm(&small), 2);
assert!(arith.is_small(&small, 2));
assert!(!arith.is_small(&small, 1));
let l2 = arith.l2_norm_sq(&small);
assert_eq!(l2, 0 + 1 + 1 + 4);
}
#[test]
fn test_lwe_sample_consistency() {
let n = 8;
let q = 97i64;
let b = 3i64;
let mut gen = LWESampleGenerator::new(n, q, b, 7);
let s: Vec<i64> = vec![1, 0, 0, 1, 0, 1, 1, 0];
let lwe = ToyLWE { n, q, b };
for m_bit in 0u8..=1 {
let mask: Vec<bool> = (0..n).map(|i| (i % 3) == 0).collect();
let a_rows: Vec<Vec<i64>> = (0..n).map(|_| gen.sample_a()).collect();
let b_vec: Vec<i64> = a_rows
.iter()
.map(|row| {
let inner: i64 = row
.iter()
.zip(&s)
.map(|(ai, si)| ai * si)
.sum::<i64>()
.rem_euclid(q);
(inner + gen.sample_error()).rem_euclid(q)
})
.collect();
let (c1, c2) = lwe.encrypt(&a_rows, &b_vec, m_bit, &mask);
let decrypted = lwe.decrypt(&c1, c2, &s);
assert_eq!(decrypted, m_bit, "LWE decrypt should recover bit {}", m_bit);
}
}
}
#[cfg(test)]
mod extended_pqc_tests {
use super::*;
#[test]
fn test_dilithium_params() {
let d2 = DilithiumParams::dilithium2();
assert_eq!(d2.security_level, 2);
assert_eq!(d2.n, 256);
assert!(d2.public_key_size() > 0);
}
#[test]
fn test_falcon_params() {
let f512 = FalconParams::falcon512();
assert_eq!(f512.signature_size, 666);
assert!(f512.description().contains("Falcon-512"));
}
#[test]
fn test_sphincs() {
let s = SphincsParams::sha2_128s();
assert!(s.is_stateless());
assert_eq!(s.n, 16);
}
#[test]
fn test_mceliece() {
let m = McElieceParams::kem_348864();
assert_eq!(m.error_capability(), 64);
assert!(m.rate() > 0.7 && m.rate() < 0.9);
}
#[test]
fn test_isogeny_crypto() {
let c = IsogenyCrypto::csidh_512();
assert!(c.is_post_sike);
assert!(IsogenyCrypto::note().contains("SIKE"));
}
}