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}