Skip to main content

lib_q_types/
lib.rs

1//! Shared algorithm identifiers and categories for lib-Q.
2//!
3//! This crate is the lowest dependency layer: implementation crates can depend on
4//! `lib-q-types` for `Algorithm` / `AlgorithmCategory` without pulling in `lib-q-core`.
5#![no_std]
6#![deny(unsafe_code)]
7#![deny(unused_qualifications)]
8
9pub mod cbkem;
10pub mod fndsa;
11pub mod hqc;
12pub mod mldsa;
13pub mod mlkem;
14pub mod slhdsa;
15
16#[cfg(feature = "wasm")]
17use wasm_bindgen::prelude::*;
18
19/// Algorithm identifiers for cryptographic operations
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22#[cfg_attr(feature = "wasm", wasm_bindgen)]
23pub enum Algorithm {
24    // KEM algorithms
25    MlKem512,
26    MlKem768,
27    MlKem1024,
28    CbKem348864,
29    CbKem460896,
30    CbKem6688128,
31    CbKem6960119,
32    CbKem8192128,
33    Hqc128,
34    Hqc192,
35    Hqc256,
36
37    // Signature algorithms
38    MlDsa44,
39    MlDsa65,
40    MlDsa87,
41    FnDsa,
42    FnDsa512,
43    FnDsa1024,
44    SlhDsaSha256128fRobust,
45    SlhDsaSha256192fRobust,
46    SlhDsaSha256256fRobust,
47    SlhDsaShake256128fRobust,
48    SlhDsaShake256192fRobust,
49    SlhDsaShake256256fRobust,
50
51    // Hash algorithms
52    Shake128,
53    Shake256,
54    CShake128,
55    CShake256,
56    Sha3_224,
57    Sha3_256,
58    Sha3_384,
59    Sha3_512,
60    Keccak224,
61    Keccak256,
62    Keccak384,
63    Keccak512,
64    Kt128,
65    Kt256,
66    TurboShake128,
67    TurboShake256,
68    Kmac128,
69    Kmac256,
70    TupleHash128,
71    TupleHash256,
72    ParallelHash128,
73    ParallelHash256,
74
75    // SHA-2 algorithms
76    Sha224,
77    Sha256,
78    Sha384,
79    Sha512,
80    Sha512_224,
81    Sha512_256,
82
83    // AEAD algorithms
84    Saturnin,
85    Shake256Aead,
86    DuplexSpongeAead,
87    TweakAead,
88    RomulusN,
89    RomulusM,
90    RoccaS,
91
92    /// Privacy-protocol identifiers (not standalone KEM/sig/hash providers).
93    LatticeRingSignature,
94    LatticeBlindIssuance,
95    LatticeAnonymousToken,
96    LatticeNullifierRegistry,
97    /// Witness-derived nullifier mode (SHAKE256 over opening witness wire; see `lib-q-lattice-zkp`).
98    LatticeWitnessNullifier,
99    /// DualRing-LB (CCS 2021 Alg. 3 aggregated verify on Ajtai openings, `lib-q-ring-sig`).
100    LatticeDualRingLb,
101    /// ML-KEM-768 layered encapsulation with Saturnin AEAD per hop (mix-layer transport).
102    MixOnionRouting,
103    /// SHAKE256 session token and stateless retry-cookie derivation for resumption handshakes.
104    SessionResumptionBinding,
105
106    // Reserved diversity signatures (registered DISABLED; not implemented)
107    /// **Reserved** FAEST / VOLE-in-the-Head signature (symmetric-only / AES assumptions).
108    ///
109    /// An assumption-diversity hedge against a structured-lattice break of the default ML-DSA: FAEST
110    /// rests on symmetric-primitive hardness alone, with no Module-LWE/Module-SIS structure. It is
111    /// large and slow relative to ML-DSA, so it is **never a default** — it is registered with
112    /// `enabled = false` and is intended to be activated only on a lattice-cryptanalysis event.
113    /// Supersedes Picnic (deprecated). Identifier only — no signing/verification is implemented.
114    /// See `lib-q-sig/docs/FAEST_EVALUATION.md`.
115    FaestReserved,
116}
117
118impl Algorithm {
119    /// Get the security level for this algorithm
120    pub fn security_level(&self) -> u32 {
121        match self {
122            // Level 1 (128-bit security)
123            Algorithm::MlKem512 => 1,
124            Algorithm::CbKem348864 => 1,
125            Algorithm::Hqc128 => 1,
126            Algorithm::MlDsa44 => 1,
127            Algorithm::FnDsa => 1,
128            Algorithm::FnDsa512 => 1,
129            Algorithm::SlhDsaSha256128fRobust => 1,
130            Algorithm::SlhDsaShake256128fRobust => 1,
131
132            // Level 3 (192-bit security)
133            Algorithm::MlKem768 => 3,
134            Algorithm::CbKem460896 => 3,
135            Algorithm::Hqc192 => 3,
136            Algorithm::MlDsa65 => 3,
137            Algorithm::SlhDsaSha256192fRobust => 3,
138            Algorithm::SlhDsaShake256192fRobust => 3,
139
140            // Level 5. These were all returning 4, which is not a category any of them claims --
141            // it looks like "the next integer after 3" rather than a sourced value. The block was
142            // already self-contradicting: the two SLH-DSA 256f entries returned 5 while sitting
143            // under a "Level 4" heading. Each value below is the category the algorithm's own
144            // specification claims: ML-KEM-1024 FIPS 203; Classic McEliece 6688128 and 6960119
145            // per the submission (every "128"-suffixed set is Category 5); HQC-256 per the
146            // v5.0.0 spec Table 5; ML-DSA-87 FIPS 204; SLH-DSA 256f FIPS 205 11.2.1/11.2.2;
147            // FN-DSA-1024 and Classic McEliece 8192128 were already correct.
148            //
149            // NOTE: this match is a SECOND copy of the table in
150            // lib-q-core/src/algorithm_registry.rs (which itself keeps three more hand-duplicated
151            // no_std static-slice copies). The duplication is why this bug survived: fixing one
152            // copy leaves the others wrong. Change all of them together until they are unified.
153            Algorithm::MlKem1024 => 5,
154            Algorithm::CbKem6688128 => 5,
155            Algorithm::CbKem6960119 => 5,
156            Algorithm::Hqc256 => 5,
157            Algorithm::MlDsa87 => 5,
158            Algorithm::SlhDsaSha256256fRobust => 5,
159            Algorithm::SlhDsaShake256256fRobust => 5,
160            Algorithm::FnDsa1024 => 5,
161            Algorithm::CbKem8192128 => 5,
162
163            // Hash algorithms don't have security levels
164            Algorithm::Shake128 |
165            Algorithm::Shake256 |
166            Algorithm::CShake128 |
167            Algorithm::CShake256 |
168            Algorithm::Sha3_224 |
169            Algorithm::Sha3_256 |
170            Algorithm::Sha3_384 |
171            Algorithm::Sha3_512 |
172            Algorithm::Keccak224 |
173            Algorithm::Keccak256 |
174            Algorithm::Keccak384 |
175            Algorithm::Keccak512 |
176            Algorithm::Kt128 |
177            Algorithm::Kt256 |
178            Algorithm::TurboShake128 |
179            Algorithm::TurboShake256 |
180            Algorithm::Kmac128 |
181            Algorithm::Kmac256 |
182            Algorithm::TupleHash128 |
183            Algorithm::TupleHash256 |
184            Algorithm::ParallelHash128 |
185            Algorithm::ParallelHash256 |
186            Algorithm::Sha224 |
187            Algorithm::Sha256 |
188            Algorithm::Sha384 |
189            Algorithm::Sha512 |
190            Algorithm::Sha512_224 |
191            Algorithm::Sha512_256 => 0,
192
193            // AEAD algorithms
194            Algorithm::Saturnin => 1,
195            Algorithm::Shake256Aead => 1,
196            Algorithm::DuplexSpongeAead => 4,
197            Algorithm::TweakAead => 4,
198            Algorithm::RomulusN => 1,
199            Algorithm::RomulusM => 1,
200            Algorithm::RoccaS => 1,
201
202            Algorithm::LatticeRingSignature |
203            Algorithm::LatticeBlindIssuance |
204            Algorithm::LatticeAnonymousToken |
205            Algorithm::LatticeNullifierRegistry |
206            Algorithm::LatticeWitnessNullifier |
207            Algorithm::LatticeDualRingLb |
208            Algorithm::MixOnionRouting |
209            Algorithm::SessionResumptionBinding => 3,
210
211            // Reserved diversity signature (Level 3 ≈ ML-DSA-65 class)
212            Algorithm::FaestReserved => 3,
213        }
214    }
215
216    /// Get the algorithm category
217    pub fn category(&self) -> AlgorithmCategory {
218        match self {
219            Algorithm::MlKem512 |
220            Algorithm::MlKem768 |
221            Algorithm::MlKem1024 |
222            Algorithm::CbKem348864 |
223            Algorithm::CbKem460896 |
224            Algorithm::CbKem6688128 |
225            Algorithm::CbKem6960119 |
226            Algorithm::CbKem8192128 |
227            Algorithm::Hqc128 |
228            Algorithm::Hqc192 |
229            Algorithm::Hqc256 => AlgorithmCategory::Kem,
230
231            Algorithm::MlDsa44 |
232            Algorithm::MlDsa65 |
233            Algorithm::MlDsa87 |
234            Algorithm::FnDsa |
235            Algorithm::FnDsa512 |
236            Algorithm::FnDsa1024 |
237            Algorithm::SlhDsaSha256128fRobust |
238            Algorithm::SlhDsaSha256192fRobust |
239            Algorithm::SlhDsaSha256256fRobust |
240            Algorithm::SlhDsaShake256128fRobust |
241            Algorithm::SlhDsaShake256192fRobust |
242            Algorithm::SlhDsaShake256256fRobust => AlgorithmCategory::Signature,
243
244            Algorithm::Shake128 |
245            Algorithm::Shake256 |
246            Algorithm::CShake128 |
247            Algorithm::CShake256 |
248            Algorithm::Sha3_224 |
249            Algorithm::Sha3_256 |
250            Algorithm::Sha3_384 |
251            Algorithm::Sha3_512 |
252            Algorithm::Keccak224 |
253            Algorithm::Keccak256 |
254            Algorithm::Keccak384 |
255            Algorithm::Keccak512 |
256            Algorithm::Kt128 |
257            Algorithm::Kt256 |
258            Algorithm::TurboShake128 |
259            Algorithm::TurboShake256 |
260            Algorithm::Kmac128 |
261            Algorithm::Kmac256 |
262            Algorithm::TupleHash128 |
263            Algorithm::TupleHash256 |
264            Algorithm::ParallelHash128 |
265            Algorithm::ParallelHash256 |
266            Algorithm::Sha224 |
267            Algorithm::Sha256 |
268            Algorithm::Sha384 |
269            Algorithm::Sha512 |
270            Algorithm::Sha512_224 |
271            Algorithm::Sha512_256 => AlgorithmCategory::Hash,
272
273            // AEAD algorithms
274            Algorithm::Saturnin |
275            Algorithm::Shake256Aead |
276            Algorithm::DuplexSpongeAead |
277            Algorithm::TweakAead |
278            Algorithm::RomulusN |
279            Algorithm::RomulusM |
280            Algorithm::RoccaS => AlgorithmCategory::Aead,
281
282            Algorithm::LatticeRingSignature |
283            Algorithm::LatticeBlindIssuance |
284            Algorithm::LatticeAnonymousToken |
285            Algorithm::LatticeNullifierRegistry |
286            Algorithm::LatticeWitnessNullifier |
287            Algorithm::LatticeDualRingLb |
288            Algorithm::MixOnionRouting |
289            Algorithm::SessionResumptionBinding => AlgorithmCategory::PrivacyProtocol,
290
291            // Reserved diversity signature
292            Algorithm::FaestReserved => AlgorithmCategory::Signature,
293        }
294    }
295
296    /// Check if an algorithm supports a specific category
297    pub fn supports_category(&self, category: AlgorithmCategory) -> bool {
298        match self {
299            // Pure KEM algorithms
300            Algorithm::MlKem512 |
301            Algorithm::MlKem768 |
302            Algorithm::MlKem1024 |
303            Algorithm::CbKem348864 |
304            Algorithm::CbKem460896 |
305            Algorithm::CbKem6688128 |
306            Algorithm::CbKem6960119 |
307            Algorithm::CbKem8192128 |
308            Algorithm::Hqc128 |
309            Algorithm::Hqc192 |
310            Algorithm::Hqc256 => category == AlgorithmCategory::Kem,
311
312            // Pure signature algorithms
313            Algorithm::MlDsa44 |
314            Algorithm::MlDsa65 |
315            Algorithm::MlDsa87 |
316            Algorithm::FnDsa |
317            Algorithm::FnDsa512 |
318            Algorithm::FnDsa1024 |
319            Algorithm::SlhDsaSha256128fRobust |
320            Algorithm::SlhDsaSha256192fRobust |
321            Algorithm::SlhDsaSha256256fRobust |
322            Algorithm::SlhDsaShake256128fRobust |
323            Algorithm::SlhDsaShake256192fRobust |
324            Algorithm::SlhDsaShake256256fRobust => category == AlgorithmCategory::Signature,
325
326            // Pure hash algorithms
327            Algorithm::Shake128 |
328            Algorithm::Shake256 |
329            Algorithm::CShake128 |
330            Algorithm::CShake256 |
331            Algorithm::Sha3_224 |
332            Algorithm::Sha3_256 |
333            Algorithm::Sha3_384 |
334            Algorithm::Sha3_512 |
335            Algorithm::Keccak224 |
336            Algorithm::Keccak256 |
337            Algorithm::Keccak384 |
338            Algorithm::Keccak512 |
339            Algorithm::Kt128 |
340            Algorithm::Kt256 |
341            Algorithm::TurboShake128 |
342            Algorithm::TurboShake256 |
343            Algorithm::Kmac128 |
344            Algorithm::Kmac256 |
345            Algorithm::TupleHash128 |
346            Algorithm::TupleHash256 |
347            Algorithm::ParallelHash128 |
348            Algorithm::ParallelHash256 |
349            Algorithm::Sha224 |
350            Algorithm::Sha256 |
351            Algorithm::Sha384 |
352            Algorithm::Sha512 |
353            Algorithm::Sha512_224 |
354            Algorithm::Sha512_256 => category == AlgorithmCategory::Hash,
355
356            // Pure AEAD algorithms
357            Algorithm::Saturnin |
358            Algorithm::Shake256Aead |
359            Algorithm::DuplexSpongeAead |
360            Algorithm::TweakAead |
361            Algorithm::RomulusN |
362            Algorithm::RomulusM |
363            Algorithm::RoccaS => category == AlgorithmCategory::Aead,
364
365            Algorithm::LatticeRingSignature |
366            Algorithm::LatticeBlindIssuance |
367            Algorithm::LatticeAnonymousToken |
368            Algorithm::LatticeNullifierRegistry |
369            Algorithm::LatticeWitnessNullifier |
370            Algorithm::LatticeDualRingLb |
371            Algorithm::MixOnionRouting |
372            Algorithm::SessionResumptionBinding => category == AlgorithmCategory::PrivacyProtocol,
373
374            // Reserved diversity signature
375            Algorithm::FaestReserved => category == AlgorithmCategory::Signature,
376        }
377    }
378}
379
380/// Algorithm categories
381#[derive(Debug, Clone, Copy, PartialEq, Eq)]
382#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
383#[cfg_attr(feature = "wasm", wasm_bindgen)]
384pub enum AlgorithmCategory {
385    Kem,
386    Signature,
387    Hash,
388    Aead,
389    /// Anonymous credentials, mix-layer transport helpers, and related ZKP-adjacent protocols.
390    PrivacyProtocol,
391}
392
393/// Security levels for cryptographic algorithms
394#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
395#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
396#[cfg_attr(feature = "wasm", wasm_bindgen)]
397pub enum SecurityLevel {
398    Level1 = 1, // 128-bit security
399    Level3 = 3, // 192-bit security
400    Level4 = 4, // 256-bit security
401    Level5 = 5, // 256-bit security (higher performance)
402}
403
404impl SecurityLevel {
405    /// Convert from u32 to SecurityLevel
406    pub fn from_u32(level: u32) -> Option<Self> {
407        match level {
408            1 => Some(SecurityLevel::Level1),
409            3 => Some(SecurityLevel::Level3),
410            4 => Some(SecurityLevel::Level4),
411            5 => Some(SecurityLevel::Level5),
412            _ => None,
413        }
414    }
415
416    /// Convert to u32
417    pub fn as_u32(self) -> u32 {
418        self as u32
419    }
420}
421
422impl core::fmt::Display for Algorithm {
423    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
424        match self {
425            // KEM algorithms
426            Algorithm::MlKem512 => write!(f, "ML-KEM-512"),
427            Algorithm::MlKem768 => write!(f, "ML-KEM-768"),
428            Algorithm::MlKem1024 => write!(f, "ML-KEM-1024"),
429            Algorithm::CbKem348864 => write!(f, "CB-KEM-348864"),
430            Algorithm::CbKem460896 => write!(f, "CB-KEM-460896"),
431            Algorithm::CbKem6688128 => write!(f, "CB-KEM-6688128"),
432            Algorithm::CbKem6960119 => write!(f, "CB-KEM-6960119"),
433            Algorithm::CbKem8192128 => write!(f, "CB-KEM-8192128"),
434            Algorithm::Hqc128 => write!(f, "HQC-128"),
435            Algorithm::Hqc192 => write!(f, "HQC-192"),
436            Algorithm::Hqc256 => write!(f, "HQC-256"),
437
438            // Signature algorithms
439            Algorithm::MlDsa44 => write!(f, "ML-DSA-44"),
440            Algorithm::MlDsa65 => write!(f, "ML-DSA-65"),
441            Algorithm::MlDsa87 => write!(f, "ML-DSA-87"),
442            Algorithm::FnDsa => write!(f, "FN-DSA"),
443            Algorithm::FnDsa512 => write!(f, "FN-DSA-512"),
444            Algorithm::FnDsa1024 => write!(f, "FN-DSA-1024"),
445            Algorithm::SlhDsaSha256128fRobust => write!(f, "SLH-DSA-SHA256-128f-Robust"),
446            Algorithm::SlhDsaSha256192fRobust => write!(f, "SLH-DSA-SHA256-192f-Robust"),
447            Algorithm::SlhDsaSha256256fRobust => write!(f, "SLH-DSA-SHA256-256f-Robust"),
448            Algorithm::SlhDsaShake256128fRobust => write!(f, "SLH-DSA-SHAKE256-128f-Robust"),
449            Algorithm::SlhDsaShake256192fRobust => write!(f, "SLH-DSA-SHAKE256-192f-Robust"),
450            Algorithm::SlhDsaShake256256fRobust => write!(f, "SLH-DSA-SHAKE256-256f-Robust"),
451
452            // Hash algorithms
453            Algorithm::Shake128 => write!(f, "SHAKE128"),
454            Algorithm::Shake256 => write!(f, "SHAKE256"),
455            Algorithm::CShake128 => write!(f, "cSHAKE128"),
456            Algorithm::CShake256 => write!(f, "cSHAKE256"),
457            Algorithm::Sha3_224 => write!(f, "SHA3-224"),
458            Algorithm::Sha3_256 => write!(f, "SHA3-256"),
459            Algorithm::Sha3_384 => write!(f, "SHA3-384"),
460            Algorithm::Sha3_512 => write!(f, "SHA3-512"),
461            Algorithm::Keccak224 => write!(f, "Keccak-224"),
462            Algorithm::Keccak256 => write!(f, "Keccak-256"),
463            Algorithm::Keccak384 => write!(f, "Keccak-384"),
464            Algorithm::Keccak512 => write!(f, "Keccak-512"),
465            Algorithm::Sha224 => write!(f, "SHA-224"),
466            Algorithm::Sha256 => write!(f, "SHA-256"),
467            Algorithm::Sha384 => write!(f, "SHA-384"),
468            Algorithm::Sha512 => write!(f, "SHA-512"),
469            Algorithm::Sha512_224 => write!(f, "SHA-512/224"),
470            Algorithm::Sha512_256 => write!(f, "SHA-512/256"),
471
472            // AEAD algorithms
473            Algorithm::Saturnin => write!(f, "Saturnin"),
474            Algorithm::Shake256Aead => write!(f, "SHAKE256-AEAD"),
475            Algorithm::DuplexSpongeAead => write!(f, "Duplex-Sponge-AEAD"),
476            Algorithm::TweakAead => write!(f, "Tweak-AEAD"),
477            Algorithm::RomulusN => write!(f, "Romulus-N"),
478            Algorithm::RomulusM => write!(f, "Romulus-M"),
479            Algorithm::RoccaS => write!(f, "Rocca-S"),
480
481            // Additional algorithms
482            Algorithm::Kt128 => write!(f, "KT128"),
483            Algorithm::Kt256 => write!(f, "KT256"),
484            Algorithm::TurboShake128 => write!(f, "TurboShake128"),
485            Algorithm::TurboShake256 => write!(f, "TurboShake256"),
486            Algorithm::Kmac128 => write!(f, "KMAC128"),
487            Algorithm::Kmac256 => write!(f, "KMAC256"),
488            Algorithm::TupleHash128 => write!(f, "TupleHash128"),
489            Algorithm::TupleHash256 => write!(f, "TupleHash256"),
490            Algorithm::ParallelHash128 => write!(f, "ParallelHash128"),
491            Algorithm::ParallelHash256 => write!(f, "ParallelHash256"),
492
493            Algorithm::LatticeRingSignature => write!(f, "Lattice-Ring-Signature"),
494            Algorithm::LatticeBlindIssuance => write!(f, "Lattice-Blind-Issuance"),
495            Algorithm::LatticeAnonymousToken => write!(f, "Lattice-Anonymous-Token"),
496            Algorithm::LatticeNullifierRegistry => write!(f, "Lattice-Nullifier-Registry"),
497            Algorithm::LatticeWitnessNullifier => write!(f, "Lattice-Witness-Nullifier"),
498            Algorithm::LatticeDualRingLb => write!(f, "Lattice-DualRing-LB"),
499            Algorithm::MixOnionRouting => write!(f, "Mix-Onion-Routing"),
500            Algorithm::SessionResumptionBinding => write!(f, "Session-Resumption-Binding"),
501
502            // Reserved diversity signature
503            Algorithm::FaestReserved => write!(f, "FAEST-Reserved"),
504        }
505    }
506}
507
508impl core::fmt::Display for AlgorithmCategory {
509    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
510        match self {
511            AlgorithmCategory::Kem => write!(f, "KEM"),
512            AlgorithmCategory::Signature => write!(f, "Signature"),
513            AlgorithmCategory::Hash => write!(f, "Hash"),
514            AlgorithmCategory::Aead => write!(f, "AEAD"),
515            AlgorithmCategory::PrivacyProtocol => write!(f, "Privacy protocol"),
516        }
517    }
518}
519
520#[cfg(test)]
521mod tests {
522    use super::*;
523
524    #[test]
525    fn test_algorithm_categories() {
526        assert_eq!(Algorithm::MlKem512.category(), AlgorithmCategory::Kem);
527        assert_eq!(Algorithm::Shake256Aead.category(), AlgorithmCategory::Aead);
528        assert_eq!(
529            Algorithm::LatticeAnonymousToken.category(),
530            AlgorithmCategory::PrivacyProtocol
531        );
532    }
533}