Skip to main content

oxilean_std/post_quantum_crypto/
functions.rs

1//! Auto-generated module
2//!
3//! πŸ€– Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
6
7use super::types::{
8    DilithiumParams, DilithiumVariant, FalconParams, FalconVariant, HashBasedSignature,
9    IsogenyCrypto, KyberVariant, LWESampleGenerator, LatticeBasisReducer, McElieceParams,
10    ModularLatticeArithmetic, RingPoly, SphincsParams, ToyLWE, ToyLamport, ToyMerkleTree,
11};
12
13pub fn app(f: Expr, a: Expr) -> Expr {
14    Expr::App(Box::new(f), Box::new(a))
15}
16pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
17    app(app(f, a), b)
18}
19pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
20    app(app2(f, a, b), c)
21}
22pub fn cst(s: &str) -> Expr {
23    Expr::Const(Name::str(s), vec![])
24}
25pub fn prop() -> Expr {
26    Expr::Sort(Level::zero())
27}
28pub fn type0() -> Expr {
29    Expr::Sort(Level::succ(Level::zero()))
30}
31pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
32    Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
33}
34pub fn arrow(a: Expr, b: Expr) -> Expr {
35    pi(BinderInfo::Default, "_", a, b)
36}
37pub fn nat_ty() -> Expr {
38    cst("Nat")
39}
40pub fn real_ty() -> Expr {
41    cst("Real")
42}
43pub fn bool_ty() -> Expr {
44    cst("Bool")
45}
46pub fn list_nat() -> Expr {
47    app(cst("List"), nat_ty())
48}
49pub fn bytes_ty() -> Expr {
50    list_nat()
51}
52/// `Lattice : Nat β†’ Type`
53///
54/// An n-dimensional integer lattice L βŠ† Z^n, represented by its basis matrix.
55pub fn lattice_ty() -> Expr {
56    arrow(nat_ty(), type0())
57}
58/// `LatticeVector : Nat β†’ Type`
59///
60/// A vector in Z^n (element of a lattice).
61pub fn lattice_vector_ty() -> Expr {
62    arrow(nat_ty(), type0())
63}
64/// `ShortestVector : Lattice n β†’ LatticeVector n β†’ Prop`
65///
66/// Shortest vector problem (SVP): the given vector is a shortest non-zero
67/// vector in the lattice. SVP is NP-hard under randomized reductions.
68pub fn shortest_vector_ty() -> Expr {
69    arrow(
70        app(cst("Lattice"), nat_ty()),
71        arrow(app(cst("LatticeVector"), nat_ty()), prop()),
72    )
73}
74/// `ClosestVector : Lattice n β†’ LatticeVector n β†’ LatticeVector n β†’ Prop`
75///
76/// Closest vector problem (CVP): find the lattice vector closest to a target.
77/// CVP is NP-hard and the basis of LWE hardness.
78pub fn closest_vector_ty() -> Expr {
79    arrow(
80        app(cst("Lattice"), nat_ty()),
81        arrow(
82            app(cst("LatticeVector"), nat_ty()),
83            arrow(app(cst("LatticeVector"), nat_ty()), prop()),
84        ),
85    )
86}
87/// `GaussianHeuristic : Nat β†’ Nat β†’ Prop`
88///
89/// The Gaussian heuristic: the length of the shortest lattice vector
90/// is approximately sqrt(n / (2Ο€e)) * det(L)^(1/n).
91pub fn gaussian_heuristic_ty() -> Expr {
92    arrow(nat_ty(), arrow(nat_ty(), prop()))
93}
94/// `LWEDistribution : Nat β†’ Nat β†’ Type`
95///
96/// The LWE distribution over Z_q^n: samples (a, b = ⟨a,s⟩ + e mod q)
97/// where a is uniform, s is a secret vector, and e is drawn from
98/// a discrete Gaussian error distribution Ο‡.
99pub fn lwe_distribution_ty() -> Expr {
100    arrow(nat_ty(), arrow(nat_ty(), type0()))
101}
102/// `LWEHardness : Nat β†’ Nat β†’ Prop`
103///
104/// Decision LWE hardness: no polynomial-time adversary can distinguish
105/// LWE samples from uniformly random samples over Z_q^n Γ— Z_q.
106/// Under quantum reductions, hardness follows from worst-case SVP on random lattices.
107pub fn lwe_hardness_ty() -> Expr {
108    arrow(nat_ty(), arrow(nat_ty(), prop()))
109}
110/// `LWEEncryption : Nat β†’ Nat β†’ Type`
111///
112/// An LWE-based public-key encryption scheme parameterized by (n, q):
113/// keygen samples s ← Ο‡^n; public key includes (A, As + e).
114pub fn lwe_encryption_ty() -> Expr {
115    arrow(nat_ty(), arrow(nat_ty(), type0()))
116}
117/// `LWERegev : Nat β†’ Nat β†’ Prop`
118///
119/// Regev's theorem: LWE with parameters (n, q, Ο‡_Οƒ) is hard if
120/// the Shortest Independent Vectors Problem (SIVP) is hard in the
121/// worst case for Ξ³-approximate factors where Ξ³ = Γ•(nΒ·q/Οƒ).
122pub fn lwe_regev_theorem_ty() -> Expr {
123    arrow(nat_ty(), arrow(nat_ty(), prop()))
124}
125/// `RingLWEDistribution : Nat β†’ Nat β†’ Type`
126///
127/// Ring-LWE distribution over Rq = Zq[x]/(x^n + 1):
128/// samples (a, b = aΒ·s + e) where a is uniform in Rq,
129/// s is secret in Rq, e is drawn from a Gaussian Ο‡ over Rq.
130pub fn rlwe_distribution_ty() -> Expr {
131    arrow(nat_ty(), arrow(nat_ty(), type0()))
132}
133/// `RingLWEHardness : Nat β†’ Nat β†’ Prop`
134///
135/// Decision Ring-LWE hardness: indistinguishability from uniform in Rq Γ— Rq,
136/// assuming ideal lattice problems are hard.
137pub fn rlwe_hardness_ty() -> Expr {
138    arrow(nat_ty(), arrow(nat_ty(), prop()))
139}
140/// `RingLWEToLWEReduction : Nat β†’ Nat β†’ Prop`
141///
142/// There is a polynomial-time reduction from worst-case problems on
143/// ideal lattices to Ring-LWE (Lyubashevsky-Peikert-Regev 2010).
144pub fn rlwe_to_lwe_reduction_ty() -> Expr {
145    arrow(nat_ty(), arrow(nat_ty(), prop()))
146}
147/// `NTRUParams : Nat β†’ Nat β†’ Type`
148///
149/// NTRU parameters (N, q): polynomial ring Z[x]/(x^N - 1), modulus q.
150/// Keys f, g are small (ternary or binary) polynomials in this ring.
151pub fn ntru_params_ty() -> Expr {
152    arrow(nat_ty(), arrow(nat_ty(), type0()))
153}
154/// `NTRUPublicKey : NTRUParams β†’ Type`
155///
156/// NTRU public key h = pΒ·gΒ·f^{-1} mod q in the ring Z_q[x]/(x^N - 1).
157pub fn ntru_public_key_ty() -> Expr {
158    arrow(app2(cst("NTRUParams"), nat_ty(), nat_ty()), type0())
159}
160/// `NTRUHardness : Nat β†’ Nat β†’ Prop`
161///
162/// NTRU hardness assumption: distinguishing the NTRU distribution from
163/// uniform is computationally hard. Related to shortest vector problems
164/// on NTRU lattices.
165pub fn ntru_hardness_ty() -> Expr {
166    arrow(nat_ty(), arrow(nat_ty(), prop()))
167}
168/// `NTRUCorrectness : Nat β†’ Nat β†’ Prop`
169///
170/// NTRU decryption correctness: if parameters are chosen so the decryption
171/// polynomial has small coefficients, decryption recovers the plaintext.
172pub fn ntru_correctness_ty() -> Expr {
173    arrow(nat_ty(), arrow(nat_ty(), prop()))
174}
175/// `KyberParams : Type`
176///
177/// CRYSTALS-Kyber parameter set: security level k (2, 3, or 4),
178/// modulus q = 3329, polynomial degree n = 256.
179pub fn kyber_params_ty() -> Expr {
180    type0()
181}
182/// `KyberKeyPair : KyberParams β†’ Type`
183///
184/// Kyber key pair: (ek, dk) where ek is the encapsulation key
185/// and dk is the decapsulation key.
186pub fn kyber_key_pair_ty() -> Expr {
187    arrow(kyber_params_ty(), type0())
188}
189/// `KyberIND_CCA2 : KyberParams β†’ Prop`
190///
191/// IND-CCA2 security of Kyber: under the Module-LWE assumption,
192/// Kyber-KEM is IND-CCA2 secure in the random oracle model.
193pub fn kyber_ind_cca2_ty() -> Expr {
194    arrow(kyber_params_ty(), prop())
195}
196/// `KyberMLWEHardness : KyberParams β†’ Prop`
197///
198/// Module-LWE hardness underlying Kyber: the Module-LWE problem
199/// with the Kyber parameters is computationally hard.
200pub fn kyber_mlwe_hardness_ty() -> Expr {
201    arrow(kyber_params_ty(), prop())
202}
203/// `DilithiumParams : Type`
204///
205/// CRYSTALS-Dilithium parameter set: module rank (k, l),
206/// modulus q = 8380417, security category.
207pub fn dilithium_params_ty() -> Expr {
208    type0()
209}
210/// `DilithiumSignature : DilithiumParams β†’ Type`
211///
212/// A Dilithium signature: (z, h, c̃) where z is the response polynomial,
213/// h is the hint vector, and c̃ is the challenge hash.
214pub fn dilithium_signature_ty() -> Expr {
215    arrow(dilithium_params_ty(), type0())
216}
217/// `DilithiumEUF_CMA : DilithiumParams β†’ Prop`
218///
219/// EUF-CMA security of Dilithium under Module-LWE and Module-SIS assumptions.
220pub fn dilithium_euf_cma_ty() -> Expr {
221    arrow(dilithium_params_ty(), prop())
222}
223/// `FalconParams : Type`
224///
225/// Falcon parameter set: NTRU degree n (512 or 1024), modulus q = 12289.
226/// Uses fast Fourier sampling over NTRU lattices (GPV framework).
227pub fn falcon_params_ty() -> Expr {
228    type0()
229}
230/// `FalconSignature : FalconParams β†’ Type`
231///
232/// A Falcon signature: a short vector in the NTRU lattice,
233/// output by the fast Fourier sampling algorithm.
234pub fn falcon_signature_ty() -> Expr {
235    arrow(falcon_params_ty(), type0())
236}
237/// `FalconEUF_CMA : FalconParams β†’ Prop`
238///
239/// EUF-CMA security of Falcon under the NTRU hardness assumption
240/// in the random oracle model.
241pub fn falcon_euf_cma_ty() -> Expr {
242    arrow(falcon_params_ty(), prop())
243}
244/// `LamportParams : Nat β†’ Type`
245///
246/// Lamport one-time signature parameters with n-bit hash output.
247/// Key generation: for each bit i ∈ {0, ..., n-1}, sample two pre-images
248/// (x[i][0], x[i][1]); public key is (H(x[i][0]), H(x[i][1])).
249pub fn lamport_params_ty() -> Expr {
250    arrow(nat_ty(), type0())
251}
252/// `LamportOneTimeUse : LamportParams β†’ Prop`
253///
254/// One-time security: reusing a Lamport key for two different messages
255/// reveals both pre-images for at least one bit position, breaking security.
256pub fn lamport_one_time_use_ty() -> Expr {
257    arrow(app(cst("LamportParams"), nat_ty()), prop())
258}
259/// `MerkleTree : Nat β†’ Type`
260///
261/// A Merkle hash tree of depth d: leaves are Lamport one-time public keys,
262/// internal nodes are hash values of their children.
263pub fn merkle_tree_ty() -> Expr {
264    arrow(nat_ty(), type0())
265}
266/// `MerkleSignature : MerkleTree β†’ Type`
267///
268/// A Merkle signature: one-time signature plus authentication path
269/// (sibling hashes from leaf to root).
270pub fn merkle_signature_ty() -> Expr {
271    arrow(app(cst("MerkleTree"), nat_ty()), type0())
272}
273/// `MerkleSignatureCorrectness : Nat β†’ Prop`
274///
275/// Merkle signature correctness: verifying a signature with the
276/// authentication path reconstructs the root hash.
277pub fn merkle_signature_correctness_ty() -> Expr {
278    arrow(nat_ty(), prop())
279}
280/// `SPHINCSPlusParams : Type`
281///
282/// SPHINCS+ parameter set: hypertree with d layers, each a Merkle tree
283/// of height h/d, using FORS for few-time signing.
284pub fn sphincs_plus_params_ty() -> Expr {
285    type0()
286}
287/// `SPHINCSPlusStateless : SPHINCSPlusParams β†’ Prop`
288///
289/// SPHINCS+ is stateless: unlike plain Merkle signatures, SPHINCS+
290/// uses a pseudorandom key index derivation so no state is needed.
291pub fn sphincs_plus_stateless_ty() -> Expr {
292    arrow(sphincs_plus_params_ty(), prop())
293}
294/// `SPHINCSPlusEUF_CMA : SPHINCSPlusParams β†’ Prop`
295///
296/// EUF-CMA security of SPHINCS+ in the (quantum) random oracle model,
297/// under the one-wayness of the hash function only.
298pub fn sphincs_plus_euf_cma_ty() -> Expr {
299    arrow(sphincs_plus_params_ty(), prop())
300}
301/// `BinaryGoppaCode : Nat β†’ Nat β†’ Nat β†’ Type`
302///
303/// A binary Goppa code with parameters (n, k, t): length n, dimension k,
304/// capable of correcting t errors. The hidden code structure is used in McEliece.
305pub fn binary_goppa_code_ty() -> Expr {
306    arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), type0())))
307}
308/// `McEliecePublicKey : BinaryGoppaCode β†’ Type`
309///
310/// McEliece public key: a disguised generator matrix obtained by
311/// scrambling the Goppa code's generator matrix with random invertible S
312/// and permutation P: Gpub = S Β· G Β· P.
313pub fn mceliece_public_key_ty() -> Expr {
314    arrow(
315        app3(cst("BinaryGoppaCode"), nat_ty(), nat_ty(), nat_ty()),
316        type0(),
317    )
318}
319/// `McElieceHardness : Nat β†’ Nat β†’ Nat β†’ Prop`
320///
321/// McEliece hardness: decoding a random linear code is NP-complete.
322/// The disguised Goppa code generator matrix is computationally
323/// indistinguishable from a random matrix.
324pub fn mceliece_hardness_ty() -> Expr {
325    arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), prop())))
326}
327/// `McElieceCryptosystem : Type`
328///
329/// The complete McEliece cryptosystem: key generation using a random
330/// binary Goppa code, encryption by adding a random error vector of
331/// weight t, decryption using the Patterson algorithm.
332pub fn mceliece_cryptosystem_ty() -> Expr {
333    type0()
334}
335/// `SupersingularCurve : Type`
336///
337/// A supersingular elliptic curve over a finite field F_{p^2}.
338/// Supersingular curves form a smaller class and have a rich
339/// isogeny graph structure used in isogeny-based cryptography.
340pub fn supersingular_curve_ty() -> Expr {
341    type0()
342}
343/// `Isogeny : SupersingularCurve β†’ SupersingularCurve β†’ Nat β†’ Type`
344///
345/// An isogeny of degree l between supersingular curves E1 and E2:
346/// a non-constant rational map Ο†: E1 β†’ E2 that is a group homomorphism.
347pub fn isogeny_ty() -> Expr {
348    arrow(
349        supersingular_curve_ty(),
350        arrow(supersingular_curve_ty(), arrow(nat_ty(), type0())),
351    )
352}
353/// `SIDHKeyExchange : Type`
354///
355/// SIDH (Supersingular Isogeny Diffie-Hellman) key exchange protocol.
356///
357/// NOTE: Classic SIKE (based on SIDH) was completely broken by the
358/// Castryck-Decru-Maino-Martindale-Panny attacks (2022), which exploit
359/// the auxiliary torsion point information in SIDH.
360///
361/// Remaining active areas: CSIDH (commutative SIDH, broken for some params),
362/// SQISign (based on quaternion algebra endomorphisms), and other variants.
363pub fn sidh_key_exchange_ty() -> Expr {
364    type0()
365}
366/// `SIDHBrokenByCastryckDecru : Prop`
367///
368/// Formal statement that the classical SIKE/SIDH is broken:
369/// the Castryck-Decru attack recovers private keys in polynomial time
370/// from the SIDH public key information including auxiliary torsion points.
371pub fn sidh_broken_ty() -> Expr {
372    prop()
373}
374/// `CSIDHHardness : Nat β†’ Prop`
375///
376/// CSIDH hardness: the commutative isogeny problem over F_p is assumed
377/// hard. CSIDH (Castryck-Lange-Martindale-Panny-Renes 2018) remains
378/// an active research direction for post-quantum key exchange.
379pub fn csidh_hardness_ty() -> Expr {
380    arrow(nat_ty(), prop())
381}
382/// `QuantumRandomOracle : Type`
383///
384/// A quantum random oracle: a function H: {0,1}^* β†’ {0,1}^n that
385/// adversaries can query in quantum superposition.
386pub fn quantum_random_oracle_ty() -> Expr {
387    type0()
388}
389/// `QROMSecurity : QuantumRandomOracle β†’ Prop`
390///
391/// Security in the QROM: a cryptographic primitive is QROM-secure if
392/// it remains secure even when the adversary can query the random oracle
393/// in quantum superposition, as modeled by Boneh et al. (2011).
394pub fn qrom_security_ty() -> Expr {
395    arrow(quantum_random_oracle_ty(), prop())
396}
397/// `FiatShamirQROM : Prop`
398///
399/// Fiat-Shamir in the QROM (Liu-Zhandry 2019): the Fiat-Shamir transform
400/// applied to a Sigma protocol with quantum-unique responses gives a
401/// QROM-secure NIZK, provided the underlying Sigma protocol has certain
402/// extractability properties.
403pub fn fiat_shamir_qrom_ty() -> Expr {
404    prop()
405}
406/// `QROMForkingLemma : Prop`
407///
408/// The quantum forking lemma (Don-Fehr-Majenz-Schaffner 2022):
409/// quantum counterpart of the classical forking lemma, enabling
410/// proofs of knowledge extraction in the QROM.
411pub fn qrom_forking_lemma_ty() -> Expr {
412    prop()
413}
414/// `SISHardness : Nat β†’ Nat β†’ Nat β†’ Prop`
415///
416/// Short Integer Solution (SIS) hardness: given a matrix A ∈ Z_q^{mΓ—n},
417/// find a short nonzero vector z with Az = 0 mod q and ||z|| ≀ Ξ².
418/// SIS is hard under worst-case assumptions on short lattice vectors.
419pub fn sis_hardness_ty() -> Expr {
420    arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), prop())))
421}
422/// `SISCryptosystem : Nat β†’ Nat β†’ Type`
423///
424/// A cryptographic scheme based on SIS: digital signatures whose
425/// security reduces to the hardness of finding short solutions.
426pub fn sis_cryptosystem_ty() -> Expr {
427    arrow(nat_ty(), arrow(nat_ty(), type0()))
428}
429/// `ModuleLWEDistribution : Nat β†’ Nat β†’ Nat β†’ Type`
430///
431/// Module-LWE distribution over rank-k modules over Rq:
432/// samples (A, b = As + e) where A is a matrix of polynomials,
433/// s is a secret vector of polynomials, and e is a small error vector.
434pub fn module_lwe_distribution_ty() -> Expr {
435    arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), type0())))
436}
437/// `ModuleLWEHardness : Nat β†’ Nat β†’ Prop`
438///
439/// Module-LWE hardness: the computational indistinguishability problem
440/// on module lattices, interpolating between LWE (k=1) and Ring-LWE (k=n).
441pub fn module_lwe_hardness_ty() -> Expr {
442    arrow(nat_ty(), arrow(nat_ty(), prop()))
443}
444/// `ModuleSISHardness : Nat β†’ Nat β†’ Prop`
445///
446/// Module-SIS hardness: finding short solutions in module lattices,
447/// underlying the security of Dilithium signature scheme.
448pub fn module_sis_hardness_ty() -> Expr {
449    arrow(nat_ty(), arrow(nat_ty(), prop()))
450}
451/// `NiederreiterCryptosystem : Nat β†’ Nat β†’ Nat β†’ Type`
452///
453/// The Niederreiter cryptosystem (dual to McEliece): public key is a
454/// parity-check matrix H_pub, encryption maps syndromes to codewords.
455/// Parameters: (n, k, t) for code length, dimension, and error capability.
456pub fn niederreiter_cryptosystem_ty() -> Expr {
457    arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), type0())))
458}
459/// `GoppaCodeDecodability : Nat β†’ Nat β†’ Nat β†’ Prop`
460///
461/// A binary Goppa code with parameters (n, k, t) can efficiently
462/// correct up to t errors using the Patterson algorithm.
463pub fn goppa_code_decodability_ty() -> Expr {
464    arrow(nat_ty(), arrow(nat_ty(), arrow(nat_ty(), prop())))
465}
466/// `CodeBasedSignatureScheme : Type`
467///
468/// A signature scheme whose security reduces to the syndrome decoding
469/// problem for random linear codes (NP-hard in the worst case).
470pub fn code_based_signature_ty() -> Expr {
471    type0()
472}
473/// `SyndromDecodingHardness : Nat β†’ Nat β†’ Prop`
474///
475/// The syndrome decoding problem: given a parity-check matrix H and
476/// a syndrome s, find a vector e of weight ≀ t with He = s.
477/// This problem is NP-complete and underlies code-based cryptography.
478pub fn syndrome_decoding_hardness_ty() -> Expr {
479    arrow(nat_ty(), arrow(nat_ty(), prop()))
480}
481/// `XMSSParams : Type`
482///
483/// XMSS (eXtended Merkle Signature Scheme) parameters:
484/// tree height h, security parameter n, Winternitz parameter w.
485/// XMSS is a stateful multi-tree hash-based signature scheme (RFC 8391).
486pub fn xmss_params_ty() -> Expr {
487    type0()
488}
489/// `XMSSSignature : XMSSParams β†’ Type`
490///
491/// An XMSS signature: consists of the WOTS+ signature for the message,
492/// plus the authentication path in the Merkle tree.
493pub fn xmss_signature_ty() -> Expr {
494    arrow(xmss_params_ty(), type0())
495}
496/// `XMSSStateful : XMSSParams β†’ Prop`
497///
498/// XMSS is stateful: each leaf key can be used exactly once.
499/// The signer must maintain a counter of the next unused leaf index.
500pub fn xmss_stateful_ty() -> Expr {
501    arrow(xmss_params_ty(), prop())
502}
503/// `LMSParams : Type`
504///
505/// LMS (Leighton-Micali Signature) parameters: tree height H,
506/// hash function output length m, LM-OTS parameters.
507/// LMS is the NIST-standardized stateful hash-based signature (SP 800-208).
508pub fn lms_params_ty() -> Expr {
509    type0()
510}
511/// `LMSSignature : LMSParams β†’ Type`
512///
513/// An LMS signature: includes the LM-OTS one-time signature plus
514/// the Merkle authentication path to the root.
515pub fn lms_signature_ty() -> Expr {
516    arrow(lms_params_ty(), type0())
517}
518/// `HashBasedEUF_CMA : Nat β†’ Prop`
519///
520/// EUF-CMA security of hash-based signature schemes (XMSS, LMS, SPHINCS+):
521/// under the one-wayness and collision-resistance of the hash function,
522/// the scheme is existentially unforgeable under chosen message attacks.
523pub fn hash_based_euf_cma_ty() -> Expr {
524    arrow(nat_ty(), prop())
525}
526/// `CSIDHPublicKey : Nat β†’ Type`
527///
528/// CSIDH (Commutative Supersingular Isogeny Diffie-Hellman) public key:
529/// a supersingular elliptic curve over F_p together with its j-invariant.
530pub fn csidh_public_key_ty() -> Expr {
531    arrow(nat_ty(), type0())
532}
533/// `CSIDHGroupAction : Nat β†’ Prop`
534///
535/// The ideal class group cl(O) acts freely and transitively on the set
536/// of supersingular curves over F_p with endomorphism ring O.
537/// This group action is the hardness foundation of CSIDH.
538pub fn csidh_group_action_ty() -> Expr {
539    arrow(nat_ty(), prop())
540}
541/// `SQISignParams : Type`
542///
543/// SQISign parameters: a supersingular elliptic curve E_0 defined over F_{p^2},
544/// together with a special endomorphism computed via quaternion algebra.
545/// SQISign is a hash-and-sign isogeny-based signature scheme.
546pub fn sqisign_params_ty() -> Expr {
547    type0()
548}
549/// `SQISignEUF_CMA : SQISignParams β†’ Prop`
550///
551/// SQISign EUF-CMA security under the quaternion endomorphism problem:
552/// computing an endomorphism of a given degree is computationally hard.
553pub fn sqisign_euf_cma_ty() -> Expr {
554    arrow(sqisign_params_ty(), prop())
555}
556/// `EndomorphismRingHardness : Nat β†’ Prop`
557///
558/// Computing the endomorphism ring of a supersingular elliptic curve
559/// is believed hard even for quantum adversaries, forming the security
560/// basis for SQISign and related schemes.
561pub fn endomorphism_ring_hardness_ty() -> Expr {
562    arrow(nat_ty(), prop())
563}
564/// `MQHardness : Nat β†’ Nat β†’ Prop`
565///
566/// Multivariate Quadratic (MQ) hardness: solving a system of m quadratic
567/// equations in n variables over a finite field is NP-complete.
568/// This forms the hardness foundation for multivariate signature schemes.
569pub fn mq_hardness_ty() -> Expr {
570    arrow(nat_ty(), arrow(nat_ty(), prop()))
571}
572/// `RainbowSignature : Nat β†’ Nat β†’ Type`
573///
574/// Rainbow multi-layer signature scheme: a layered variant of the
575/// Oil-and-Vinegar scheme with multiple layers of oil and vinegar variables.
576/// (Note: certain parameter sets were broken by the Beullens 2022 attack.)
577pub fn rainbow_signature_ty() -> Expr {
578    arrow(nat_ty(), arrow(nat_ty(), type0()))
579}
580/// `UOVSignature : Nat β†’ Nat β†’ Type`
581///
582/// Unbalanced Oil and Vinegar (UOV) signature scheme:
583/// the signer uses the structure of oil/vinegar variable separation to
584/// invert the public map efficiently.
585pub fn uov_signature_ty() -> Expr {
586    arrow(nat_ty(), arrow(nat_ty(), type0()))
587}
588/// `UOVSecurity : Nat β†’ Nat β†’ Prop`
589///
590/// UOV security: breaking UOV requires solving the MQ problem or
591/// finding the oil subspace from the public key.
592pub fn uov_security_ty() -> Expr {
593    arrow(nat_ty(), arrow(nat_ty(), prop()))
594}
595/// `MultivariateKeyRecoveryHardness : Nat β†’ Prop`
596///
597/// Key recovery hardness for multivariate schemes: recovering the
598/// secret trapdoor (the oil space or private map) from the public key
599/// is computationally hard under standard assumptions.
600pub fn multivariate_key_recovery_hardness_ty() -> Expr {
601    arrow(nat_ty(), prop())
602}
603/// `LatticeZKProof : Nat β†’ Type`
604///
605/// A zero-knowledge proof system based on lattice problems:
606/// the prover demonstrates knowledge of a short witness without
607/// revealing it, using rejection sampling over lattice distributions.
608pub fn lattice_zk_proof_ty() -> Expr {
609    arrow(nat_ty(), type0())
610}
611/// `LatticeSigmaProtocol : Nat β†’ Prop`
612///
613/// A Sigma protocol for lattice relations: 3-move protocol
614/// (commit, challenge, respond) where the prover shows knowledge
615/// of a short vector satisfying a lattice equation.
616pub fn lattice_sigma_protocol_ty() -> Expr {
617    arrow(nat_ty(), prop())
618}
619/// `LatticeSoundness : Nat β†’ Prop`
620///
621/// Soundness of lattice-based ZK: a cheating prover without knowledge
622/// of the short witness cannot succeed except with negligible probability.
623pub fn lattice_soundness_ty() -> Expr {
624    arrow(nat_ty(), prop())
625}
626/// `RejectionSamplingLemma : Nat β†’ Prop`
627///
628/// Rejection sampling (Lyubashevsky 2009): given a distribution D
629/// and a target distribution D', output D' by rejection sampling.
630/// Used in Dilithium and lattice Sigma protocols to hide the secret.
631pub fn rejection_sampling_lemma_ty() -> Expr {
632    arrow(nat_ty(), prop())
633}
634/// `LatticeZKSuccinctness : Nat β†’ Prop`
635///
636/// Succinct lattice ZK proofs: using polynomial commitments and
637/// inner product arguments, lattice proofs can achieve sub-linear
638/// communication complexity.
639pub fn lattice_zk_succinctness_ty() -> Expr {
640    arrow(nat_ty(), prop())
641}
642/// `BKZAlgorithm : Nat β†’ Nat β†’ Type`
643///
644/// BKZ (Block Korkin-Zolotarev) lattice basis reduction algorithm
645/// with block size Ξ² and lattice dimension n. BKZ-Ξ² reduces to
646/// within O(Ξ²^{n/Ξ²}) of the shortest vector in polynomial time for fixed Ξ².
647pub fn bkz_algorithm_ty() -> Expr {
648    arrow(nat_ty(), arrow(nat_ty(), type0()))
649}
650/// `BKZQualityBound : Nat β†’ Nat β†’ Prop`
651///
652/// BKZ quality bound: the first basis vector after BKZ-Ξ² reduction
653/// has length approximately Ξ΄^{n-1} Β· det(L)^{1/n} where
654/// Ξ΄_Ξ² = (Ξ²/(2Ο€e))^{1/(2Ξ²)} is the Hermite factor.
655pub fn bkz_quality_bound_ty() -> Expr {
656    arrow(nat_ty(), arrow(nat_ty(), prop()))
657}
658/// `SievingAlgorithm : Nat β†’ Type`
659///
660/// Lattice sieving algorithm (e.g., GaussSieve, HashSieve):
661/// finds short vectors in an n-dimensional lattice with heuristic
662/// running time 2^{cn} for a constant c β‰ˆ 0.292 (BKZ 2.0).
663pub fn sieving_algorithm_ty() -> Expr {
664    arrow(nat_ty(), type0())
665}
666/// `SievingComplexity : Nat β†’ Prop`
667///
668/// Sieving complexity: the best known quantum sieving algorithms
669/// run in time 2^{0.265n} (Laarhoven 2015), which determines
670/// the security levels of NIST PQC lattice schemes.
671pub fn sieving_complexity_ty() -> Expr {
672    arrow(nat_ty(), prop())
673}
674/// `LatticeEnumeration : Nat β†’ Nat β†’ Type`
675///
676/// Lattice enumeration algorithm: exhaustively searches a pruned
677/// tree of lattice vectors to find the shortest vector.
678/// Runs in time 2^{O(n log n / 2)} in practice.
679pub fn lattice_enumeration_ty() -> Expr {
680    arrow(nat_ty(), arrow(nat_ty(), type0()))
681}
682/// `GramSchmidtOrthogonalization : Nat β†’ Type`
683///
684/// Gram-Schmidt orthogonalization of a lattice basis B:
685/// computes B* = GSO(B) used in LLL and BKZ reduction quality bounds.
686pub fn gram_schmidt_ty() -> Expr {
687    arrow(nat_ty(), type0())
688}
689/// `MLKEMParams : Type`
690///
691/// ML-KEM (Module Lattice Key Encapsulation Mechanism) parameter set,
692/// formerly known as CRYSTALS-Kyber, standardized as FIPS 203.
693/// Provides IND-CCA2 KEM security based on Module-LWE.
694pub fn ml_kem_params_ty() -> Expr {
695    type0()
696}
697/// `MLKEMCorrectness : MLKEMParams β†’ Prop`
698///
699/// ML-KEM correctness: decapsulation always recovers the shared secret
700/// that was encapsulated, i.e., Dec(dk, Enc(ek, r)) = K.
701pub fn ml_kem_correctness_ty() -> Expr {
702    arrow(ml_kem_params_ty(), prop())
703}
704/// `MLDSAParams : Type`
705///
706/// ML-DSA (Module Lattice Digital Signature Algorithm) parameter set,
707/// formerly CRYSTALS-Dilithium, standardized as FIPS 204.
708/// Provides EUF-CMA security based on Module-LWE and Module-SIS.
709pub fn ml_dsa_params_ty() -> Expr {
710    type0()
711}
712/// `MLDSADetachedSignature : MLDSAParams β†’ Type`
713///
714/// An ML-DSA detached signature: does not include the message,
715/// allowing verification with a separately transmitted message.
716pub fn ml_dsa_detached_signature_ty() -> Expr {
717    arrow(ml_dsa_params_ty(), type0())
718}
719/// `SLHDSAParams : Type`
720///
721/// SLH-DSA (Stateless Hash-based Digital Signature Algorithm) parameter set,
722/// formerly SPHINCS+, standardized as FIPS 205.
723/// Provides hash-based EUF-CMA security without number-theoretic assumptions.
724pub fn slh_dsa_params_ty() -> Expr {
725    type0()
726}
727/// `SLHDSAStatelesness : SLHDSAParams β†’ Prop`
728///
729/// SLH-DSA statelessness: no signing state needs to be maintained across calls.
730/// The randomness is derived pseudorandomly from the secret key and message.
731pub fn slh_dsa_statelessness_ty() -> Expr {
732    arrow(slh_dsa_params_ty(), prop())
733}
734/// `NISTPQCStandardSecurity : Type`
735///
736/// The security levels of NIST PQC standards:
737/// Level 1 β‰₯ AES-128, Level 3 β‰₯ AES-192, Level 5 β‰₯ AES-256
738/// (classical and quantum security).
739pub fn nist_pqc_security_level_ty() -> Expr {
740    type0()
741}
742/// `QROMReduction : Nat β†’ Prop`
743///
744/// QROM reduction: a security proof that reduces the advantage of any
745/// quantum adversary attacking a scheme to the difficulty of solving
746/// an underlying hard problem, when oracles are quantum-accessible.
747pub fn qrom_reduction_ty() -> Expr {
748    arrow(nat_ty(), prop())
749}
750/// `OnewayToHidingLemma : Prop`
751///
752/// One-way-to-hiding (O2H) lemma (Ambainis-Hamburg-Unruh 2019):
753/// if H and H' differ at one point, any quantum algorithm distinguishing
754/// them gives a quantum algorithm finding the differing point.
755/// Key tool for QROM proofs of OAEP and Fujisaki-Okamoto transforms.
756pub fn o2h_lemma_ty() -> Expr {
757    prop()
758}
759/// `FujisakiOkamotoQROM : Prop`
760///
761/// Fujisaki-Okamoto transform in the QROM (Hofheinz-HΓΆvelmanns-Kiltz 2017):
762/// the FO transform converts an IND-CPA KEM into an IND-CCA2 KEM,
763/// and the proof goes through in the QROM using O2H or compressed oracles.
764pub fn fujisaki_okamoto_qrom_ty() -> Expr {
765    prop()
766}
767/// `QuantumSecureHashFunction : Nat β†’ Prop`
768///
769/// A quantum-secure hash function with output length n remains
770/// collision-resistant against BHT attack needing O(2^{n/3}) quantum queries.
771pub fn quantum_secure_hash_ty() -> Expr {
772    arrow(nat_ty(), prop())
773}
774/// `HybridKEM : Type`
775///
776/// A hybrid KEM combining a classical KEM (e.g., ECDH) and a PQC KEM
777/// (e.g., ML-KEM): the shared secret is derived from both, so security
778/// holds if either component is secure.
779pub fn hybrid_kem_ty() -> Expr {
780    type0()
781}
782/// `HybridKEMSecurity : HybridKEM β†’ Prop`
783///
784/// Hybrid KEM security: the hybrid is IND-CCA2 if at least one of the
785/// component KEMs is IND-CCA2. This covers the transition period
786/// when quantum attacks are not yet practical but must be anticipated.
787pub fn hybrid_kem_security_ty() -> Expr {
788    arrow(hybrid_kem_ty(), prop())
789}
790/// `PQCMigrationStrategy : Type`
791///
792/// A PQC migration strategy describes the phased deployment of
793/// post-quantum cryptography: hybrid deployment, legacy support,
794/// algorithm agility, and performance considerations.
795pub fn pqc_migration_strategy_ty() -> Expr {
796    type0()
797}
798/// `CryptoAgility : Type`
799///
800/// Crypto-agility: the ability to switch cryptographic algorithms
801/// without changing the overall system design, crucial for PQC migration.
802pub fn crypto_agility_ty() -> Expr {
803    type0()
804}
805/// `TLSPQCExtension : Prop`
806///
807/// The TLS 1.3 PQC extension: hybrid key exchange combining X25519
808/// with ML-KEM-768, providing post-quantum security for TLS connections
809/// while maintaining backward compatibility.
810pub fn tls_pqc_extension_ty() -> Expr {
811    prop()
812}
813/// Register all post-quantum cryptography axioms into the kernel environment.
814pub fn build_post_quantum_crypto_env(env: &mut Environment) -> Result<(), String> {
815    let axioms: &[(&str, Expr)] = &[
816        ("PQC.Lattice", lattice_ty()),
817        ("PQC.LatticeVector", lattice_vector_ty()),
818        ("PQC.ShortestVector", shortest_vector_ty()),
819        ("PQC.ClosestVector", closest_vector_ty()),
820        ("PQC.GaussianHeuristic", gaussian_heuristic_ty()),
821        ("PQC.LWEDistribution", lwe_distribution_ty()),
822        ("PQC.LWEHardness", lwe_hardness_ty()),
823        ("PQC.LWEEncryption", lwe_encryption_ty()),
824        ("PQC.LWERegevTheorem", lwe_regev_theorem_ty()),
825        ("PQC.RingLWEDistribution", rlwe_distribution_ty()),
826        ("PQC.RingLWEHardness", rlwe_hardness_ty()),
827        ("PQC.RingLWEToLWEReduction", rlwe_to_lwe_reduction_ty()),
828        ("PQC.NTRUParams", ntru_params_ty()),
829        ("PQC.NTRUPublicKey", ntru_public_key_ty()),
830        ("PQC.NTRUHardness", ntru_hardness_ty()),
831        ("PQC.NTRUCorrectness", ntru_correctness_ty()),
832        ("PQC.KyberParams", kyber_params_ty()),
833        ("PQC.KyberKeyPair", kyber_key_pair_ty()),
834        ("PQC.KyberIND_CCA2", kyber_ind_cca2_ty()),
835        ("PQC.KyberMLWEHardness", kyber_mlwe_hardness_ty()),
836        ("PQC.DilithiumParams", dilithium_params_ty()),
837        ("PQC.DilithiumSignature", dilithium_signature_ty()),
838        ("PQC.DilithiumEUF_CMA", dilithium_euf_cma_ty()),
839        ("PQC.FalconParams", falcon_params_ty()),
840        ("PQC.FalconSignature", falcon_signature_ty()),
841        ("PQC.FalconEUF_CMA", falcon_euf_cma_ty()),
842        ("PQC.LamportParams", lamport_params_ty()),
843        ("PQC.LamportOneTimeUse", lamport_one_time_use_ty()),
844        ("PQC.MerkleTree", merkle_tree_ty()),
845        ("PQC.MerkleSignature", merkle_signature_ty()),
846        (
847            "PQC.MerkleSignatureCorrectness",
848            merkle_signature_correctness_ty(),
849        ),
850        ("PQC.SPHINCSPlusParams", sphincs_plus_params_ty()),
851        ("PQC.SPHINCSPlusStateless", sphincs_plus_stateless_ty()),
852        ("PQC.SPHINCSPlusEUF_CMA", sphincs_plus_euf_cma_ty()),
853        ("PQC.BinaryGoppaCode", binary_goppa_code_ty()),
854        ("PQC.McEliecePublicKey", mceliece_public_key_ty()),
855        ("PQC.McElieceHardness", mceliece_hardness_ty()),
856        ("PQC.McElieceCryptosystem", mceliece_cryptosystem_ty()),
857        ("PQC.SupersingularCurve", supersingular_curve_ty()),
858        ("PQC.Isogeny", isogeny_ty()),
859        ("PQC.SIDHKeyExchange", sidh_key_exchange_ty()),
860        ("PQC.SIDHBrokenByCastryckDecru", sidh_broken_ty()),
861        ("PQC.CSIDHHardness", csidh_hardness_ty()),
862        ("PQC.QuantumRandomOracle", quantum_random_oracle_ty()),
863        ("PQC.QROMSecurity", qrom_security_ty()),
864        ("PQC.FiatShamirQROM", fiat_shamir_qrom_ty()),
865        ("PQC.QROMForkingLemma", qrom_forking_lemma_ty()),
866        ("PQC.SISHardness", sis_hardness_ty()),
867        ("PQC.SISCryptosystem", sis_cryptosystem_ty()),
868        ("PQC.ModuleLWEDistribution", module_lwe_distribution_ty()),
869        ("PQC.ModuleLWEHardness", module_lwe_hardness_ty()),
870        ("PQC.ModuleSISHardness", module_sis_hardness_ty()),
871        (
872            "PQC.NiederreiterCryptosystem",
873            niederreiter_cryptosystem_ty(),
874        ),
875        ("PQC.GoppaCodeDecodability", goppa_code_decodability_ty()),
876        ("PQC.CodeBasedSignature", code_based_signature_ty()),
877        (
878            "PQC.SyndromeDecodingHardness",
879            syndrome_decoding_hardness_ty(),
880        ),
881        ("PQC.XMSSParams", xmss_params_ty()),
882        ("PQC.XMSSSignature", xmss_signature_ty()),
883        ("PQC.XMSSStateful", xmss_stateful_ty()),
884        ("PQC.LMSParams", lms_params_ty()),
885        ("PQC.LMSSignature", lms_signature_ty()),
886        ("PQC.HashBasedEUF_CMA", hash_based_euf_cma_ty()),
887        ("PQC.CSIDHPublicKey", csidh_public_key_ty()),
888        ("PQC.CSIDHGroupAction", csidh_group_action_ty()),
889        ("PQC.SQISignParams", sqisign_params_ty()),
890        ("PQC.SQISignEUF_CMA", sqisign_euf_cma_ty()),
891        (
892            "PQC.EndomorphismRingHardness",
893            endomorphism_ring_hardness_ty(),
894        ),
895        ("PQC.MQHardness", mq_hardness_ty()),
896        ("PQC.RainbowSignature", rainbow_signature_ty()),
897        ("PQC.UOVSignature", uov_signature_ty()),
898        ("PQC.UOVSecurity", uov_security_ty()),
899        (
900            "PQC.MultivariateKeyRecoveryHardness",
901            multivariate_key_recovery_hardness_ty(),
902        ),
903        ("PQC.LatticeZKProof", lattice_zk_proof_ty()),
904        ("PQC.LatticeSigmaProtocol", lattice_sigma_protocol_ty()),
905        ("PQC.LatticeSoundness", lattice_soundness_ty()),
906        ("PQC.RejectionSamplingLemma", rejection_sampling_lemma_ty()),
907        ("PQC.LatticeZKSuccinctness", lattice_zk_succinctness_ty()),
908        ("PQC.BKZAlgorithm", bkz_algorithm_ty()),
909        ("PQC.BKZQualityBound", bkz_quality_bound_ty()),
910        ("PQC.SievingAlgorithm", sieving_algorithm_ty()),
911        ("PQC.SievingComplexity", sieving_complexity_ty()),
912        ("PQC.LatticeEnumeration", lattice_enumeration_ty()),
913        ("PQC.GramSchmidt", gram_schmidt_ty()),
914        ("PQC.MLKEMParams", ml_kem_params_ty()),
915        ("PQC.MLKEMCorrectness", ml_kem_correctness_ty()),
916        ("PQC.MLDSAParams", ml_dsa_params_ty()),
917        ("PQC.MLDSADetachedSignature", ml_dsa_detached_signature_ty()),
918        ("PQC.SLHDSAParams", slh_dsa_params_ty()),
919        ("PQC.SLHDSAStatelessness", slh_dsa_statelessness_ty()),
920        ("PQC.NISTPQCSecurityLevel", nist_pqc_security_level_ty()),
921        ("PQC.QROMReduction", qrom_reduction_ty()),
922        ("PQC.O2HLemma", o2h_lemma_ty()),
923        ("PQC.FujisakiOkamotoQROM", fujisaki_okamoto_qrom_ty()),
924        ("PQC.QuantumSecureHash", quantum_secure_hash_ty()),
925        ("PQC.HybridKEM", hybrid_kem_ty()),
926        ("PQC.HybridKEMSecurity", hybrid_kem_security_ty()),
927        ("PQC.PQCMigrationStrategy", pqc_migration_strategy_ty()),
928        ("PQC.CryptoAgility", crypto_agility_ty()),
929        ("PQC.TLSPQCExtension", tls_pqc_extension_ty()),
930    ];
931    for (name, ty) in axioms {
932        env.add(Declaration::Axiom {
933            name: Name::str(*name),
934            univ_params: vec![],
935            ty: ty.clone(),
936        })
937        .ok();
938    }
939    Ok(())
940}
941/// Simple 2-to-1 hash for Merkle tree construction.
942pub(super) fn merkle_hash(a: u64, b: u64) -> u64 {
943    a.wrapping_mul(0x9e3779b97f4a7c15)
944        .wrapping_add(b)
945        .rotate_left(17)
946        .wrapping_add(0x6c62272e07bb0142)
947}
948#[cfg(test)]
949mod tests {
950    use super::*;
951    use oxilean_kernel::Environment;
952    #[test]
953    fn test_build_env() {
954        let mut env = Environment::new();
955        let result = build_post_quantum_crypto_env(&mut env);
956        assert!(
957            result.is_ok(),
958            "build_post_quantum_crypto_env failed: {:?}",
959            result
960        );
961    }
962    #[test]
963    fn test_kyber_variants() {
964        assert_eq!(KyberVariant::Kyber512.k(), 2);
965        assert_eq!(KyberVariant::Kyber768.k(), 3);
966        assert_eq!(KyberVariant::Kyber1024.k(), 4);
967        assert_eq!(KyberVariant::Kyber512.security_bits(), 128);
968        assert_eq!(KyberVariant::Kyber768.security_bits(), 192);
969        assert_eq!(KyberVariant::Kyber1024.security_bits(), 256);
970    }
971    #[test]
972    fn test_dilithium_variants() {
973        let (k2, l2) = DilithiumVariant::Dilithium2.dimensions();
974        assert_eq!((k2, l2), (4, 4));
975        let (k5, l5) = DilithiumVariant::Dilithium5.dimensions();
976        assert_eq!((k5, l5), (8, 7));
977        assert!(
978            DilithiumVariant::Dilithium3.signature_bytes()
979                > DilithiumVariant::Dilithium2.signature_bytes()
980        );
981    }
982    #[test]
983    fn test_falcon_variants() {
984        assert_eq!(FalconVariant::Falcon512.degree(), 512);
985        assert_eq!(FalconVariant::Falcon1024.degree(), 1024);
986        assert_eq!(FalconVariant::Falcon512.modulus(), 12289);
987        assert_eq!(FalconVariant::Falcon1024.modulus(), 12289);
988    }
989    #[test]
990    fn test_ring_poly_add_mul() {
991        let _n = 4;
992        let q = 17i64;
993        let a = RingPoly {
994            coeffs: vec![1, 2, 3, 4],
995            q,
996        };
997        let b = RingPoly {
998            coeffs: vec![4, 3, 2, 1],
999            q,
1000        };
1001        let sum = a.add(&b);
1002        assert_eq!(
1003            sum.coeffs,
1004            vec![5, 5, 5, 5],
1005            "Polynomial addition should be coefficient-wise"
1006        );
1007        let diff = a.sub(&b);
1008        assert_eq!(diff.coeffs[0], -3);
1009        assert_eq!(diff.coeffs[2], 1);
1010        let one = RingPoly {
1011            coeffs: vec![0, 1, 0, 0],
1012            q,
1013        };
1014        let two = RingPoly {
1015            coeffs: vec![0, 1, 0, 0],
1016            q,
1017        };
1018        let prod = one.mul(&two);
1019        assert_eq!(
1020            prod.coeffs[2], 1,
1021            "x * x = x^2 coefficient at index 2 should be 1"
1022        );
1023    }
1024    #[test]
1025    fn test_lamport_sign_verify() {
1026        let lamport = ToyLamport { n: 8 };
1027        let kp = lamport.keygen(12345);
1028        let msg_bits: Vec<u8> = vec![1, 0, 1, 1, 0, 0, 1, 0];
1029        let sig = lamport.sign(&kp, &msg_bits);
1030        assert!(
1031            lamport.verify(&kp, &msg_bits, &sig),
1032            "Valid Lamport signature should verify"
1033        );
1034        let mut bad_bits = msg_bits.clone();
1035        bad_bits[3] = 1 - bad_bits[3];
1036        assert!(
1037            !lamport.verify(&kp, &bad_bits, &sig),
1038            "Tampered message should not verify"
1039        );
1040    }
1041    #[test]
1042    fn test_merkle_tree() {
1043        let leaves = [100u64, 200, 300, 400];
1044        let tree = ToyMerkleTree::build(leaves);
1045        for i in 0..4 {
1046            let path = tree.auth_path(i);
1047            assert!(
1048                tree.verify_leaf(leaves[i], i, path),
1049                "Merkle auth path verification failed for leaf {}",
1050                i
1051            );
1052        }
1053        let path0 = tree.auth_path(0);
1054        assert!(
1055            !tree.verify_leaf(999, 0, path0),
1056            "Wrong leaf value should fail Merkle verification"
1057        );
1058    }
1059    #[test]
1060    fn test_axioms_registered() {
1061        let mut env = Environment::new();
1062        build_post_quantum_crypto_env(&mut env)
1063            .expect("build_post_quantum_crypto_env should succeed");
1064        let expected = [
1065            "PQC.LWEHardness",
1066            "PQC.RingLWEHardness",
1067            "PQC.NTRUHardness",
1068            "PQC.KyberIND_CCA2",
1069            "PQC.DilithiumEUF_CMA",
1070            "PQC.FalconEUF_CMA",
1071            "PQC.SPHINCSPlusEUF_CMA",
1072            "PQC.McElieceHardness",
1073            "PQC.SIDHBrokenByCastryckDecru",
1074            "PQC.QROMForkingLemma",
1075        ];
1076        for name in &expected {
1077            assert!(
1078                env.get(&Name::str(*name)).is_some(),
1079                "Expected axiom '{}' not found in environment",
1080                name
1081            );
1082        }
1083    }
1084    #[test]
1085    fn test_new_axioms_registered() {
1086        let mut env = Environment::new();
1087        build_post_quantum_crypto_env(&mut env)
1088            .expect("build_post_quantum_crypto_env should succeed");
1089        let expected = [
1090            "PQC.SISHardness",
1091            "PQC.ModuleLWEHardness",
1092            "PQC.ModuleSISHardness",
1093            "PQC.NiederreiterCryptosystem",
1094            "PQC.SyndromeDecodingHardness",
1095            "PQC.XMSSParams",
1096            "PQC.LMSParams",
1097            "PQC.HashBasedEUF_CMA",
1098            "PQC.CSIDHGroupAction",
1099            "PQC.SQISignEUF_CMA",
1100            "PQC.EndomorphismRingHardness",
1101            "PQC.MQHardness",
1102            "PQC.UOVSecurity",
1103            "PQC.LatticeZKProof",
1104            "PQC.RejectionSamplingLemma",
1105            "PQC.BKZAlgorithm",
1106            "PQC.SievingComplexity",
1107            "PQC.GramSchmidt",
1108            "PQC.MLKEMParams",
1109            "PQC.MLDSAParams",
1110            "PQC.SLHDSAParams",
1111            "PQC.NISTPQCSecurityLevel",
1112            "PQC.O2HLemma",
1113            "PQC.FujisakiOkamotoQROM",
1114            "PQC.HybridKEM",
1115            "PQC.HybridKEMSecurity",
1116            "PQC.TLSPQCExtension",
1117        ];
1118        for name in &expected {
1119            assert!(
1120                env.get(&Name::str(*name)).is_some(),
1121                "Expected axiom '{}' not found in environment",
1122                name
1123            );
1124        }
1125    }
1126    #[test]
1127    fn test_lwe_sample_generator() {
1128        let mut gen = LWESampleGenerator::new(8, 97, 3, 42);
1129        let s: Vec<i64> = vec![1, 0, 1, 1, 0, 0, 1, 0];
1130        let samples = gen.sample_many(&s, 10);
1131        assert_eq!(samples.len(), 10);
1132        for (a, bval) in &samples {
1133            assert_eq!(a.len(), 8);
1134            assert!(a.iter().all(|&x| x >= 0 && x < 97));
1135            assert!(*bval >= 0 && *bval < 97);
1136        }
1137    }
1138    #[test]
1139    fn test_lattice_basis_reducer() {
1140        let reducer = LatticeBasisReducer::new(0.75);
1141        let b0 = [3i64, 1];
1142        let b1 = [1i64, 3];
1143        let (r0, r1) = reducer.reduce_2d(b0, b1);
1144        let norm_orig = LatticeBasisReducer::norm_sq(b0) + LatticeBasisReducer::norm_sq(b1);
1145        let norm_red = LatticeBasisReducer::norm_sq(r0) + LatticeBasisReducer::norm_sq(r1);
1146        assert!(norm_red <= norm_orig, "Reduced basis should not be longer");
1147        assert!(reducer.is_lll_reduced_2d(r0, r1));
1148    }
1149    #[test]
1150    fn test_hash_based_signature_wots() {
1151        let wots = HashBasedSignature::new(4, 8);
1152        let kp = wots.keygen(999);
1153        let msg: Vec<usize> = vec![0, 1, 2, 3, 0, 1, 2, 3];
1154        let sig = wots.sign(&kp, &msg);
1155        assert!(
1156            wots.verify(&kp, &msg, &sig),
1157            "WOTS+ signature should verify"
1158        );
1159        let bad_msg: Vec<usize> = vec![0, 1, 2, 3, 0, 1, 2, 0];
1160        assert!(
1161            !wots.verify(&kp, &bad_msg, &sig),
1162            "Wrong message should not verify"
1163        );
1164    }
1165    #[test]
1166    fn test_modular_lattice_arithmetic() {
1167        let arith = ModularLatticeArithmetic::new(4, 17);
1168        let a = vec![1i64, 2, 3, 4];
1169        let b = vec![4i64, 3, 2, 1];
1170        let sum = arith.poly_add(&a, &b);
1171        assert_eq!(sum, vec![5, 5, 5, 5]);
1172        let diff = arith.poly_sub(&a, &b);
1173        assert_eq!(diff[0], arith.reduce(1 - 4));
1174        assert_eq!(diff[2], arith.reduce(3 - 2));
1175        let x_poly = vec![0i64, 1, 0, 0];
1176        let prod = arith.poly_mul(&x_poly, &x_poly);
1177        assert_eq!(prod[2], 1);
1178        assert_eq!(prod[0], 0);
1179        let small = vec![0i64, 1, -1, 2];
1180        assert_eq!(arith.inf_norm(&small), 2);
1181        assert!(arith.is_small(&small, 2));
1182        assert!(!arith.is_small(&small, 1));
1183        let l2 = arith.l2_norm_sq(&small);
1184        assert_eq!(l2, 0 + 1 + 1 + 4);
1185    }
1186    #[test]
1187    fn test_lwe_sample_consistency() {
1188        let n = 8;
1189        let q = 97i64;
1190        let b = 3i64;
1191        let mut gen = LWESampleGenerator::new(n, q, b, 7);
1192        let s: Vec<i64> = vec![1, 0, 0, 1, 0, 1, 1, 0];
1193        let lwe = ToyLWE { n, q, b };
1194        for m_bit in 0u8..=1 {
1195            let mask: Vec<bool> = (0..n).map(|i| (i % 3) == 0).collect();
1196            let a_rows: Vec<Vec<i64>> = (0..n).map(|_| gen.sample_a()).collect();
1197            let b_vec: Vec<i64> = a_rows
1198                .iter()
1199                .map(|row| {
1200                    let inner: i64 = row
1201                        .iter()
1202                        .zip(&s)
1203                        .map(|(ai, si)| ai * si)
1204                        .sum::<i64>()
1205                        .rem_euclid(q);
1206                    (inner + gen.sample_error()).rem_euclid(q)
1207                })
1208                .collect();
1209            let (c1, c2) = lwe.encrypt(&a_rows, &b_vec, m_bit, &mask);
1210            let decrypted = lwe.decrypt(&c1, c2, &s);
1211            assert_eq!(decrypted, m_bit, "LWE decrypt should recover bit {}", m_bit);
1212        }
1213    }
1214}
1215#[cfg(test)]
1216mod extended_pqc_tests {
1217    use super::*;
1218    #[test]
1219    fn test_dilithium_params() {
1220        let d2 = DilithiumParams::dilithium2();
1221        assert_eq!(d2.security_level, 2);
1222        assert_eq!(d2.n, 256);
1223        assert!(d2.public_key_size() > 0);
1224    }
1225    #[test]
1226    fn test_falcon_params() {
1227        let f512 = FalconParams::falcon512();
1228        assert_eq!(f512.signature_size, 666);
1229        assert!(f512.description().contains("Falcon-512"));
1230    }
1231    #[test]
1232    fn test_sphincs() {
1233        let s = SphincsParams::sha2_128s();
1234        assert!(s.is_stateless());
1235        assert_eq!(s.n, 16);
1236    }
1237    #[test]
1238    fn test_mceliece() {
1239        let m = McElieceParams::kem_348864();
1240        assert_eq!(m.error_capability(), 64);
1241        assert!(m.rate() > 0.7 && m.rate() < 0.9);
1242    }
1243    #[test]
1244    fn test_isogeny_crypto() {
1245        let c = IsogenyCrypto::csidh_512();
1246        assert!(c.is_post_sike);
1247        assert!(IsogenyCrypto::note().contains("SIKE"));
1248    }
1249}