Skip to main content

lib_q_core/
algorithm_registry.rs

1//! Algorithm registry for lib-Q
2//!
3//! This module provides a centralized registry of all supported algorithms,
4//! eliminating the need for manual enumeration and providing better maintainability.
5
6#[cfg(all(not(feature = "std"), feature = "alloc"))]
7use alloc::collections::BTreeMap as HashMap;
8#[cfg(feature = "alloc")]
9use alloc::string::ToString;
10#[cfg(feature = "alloc")]
11use alloc::vec::Vec;
12#[cfg(feature = "std")]
13#[allow(clippy::disallowed_types)]
14use std::collections::HashMap;
15
16#[cfg(any(feature = "std", feature = "alloc"))]
17use crate::Result;
18use crate::{
19    Algorithm,
20    AlgorithmCategory,
21};
22
23/// Algorithm metadata
24#[derive(Debug, Clone)]
25pub struct AlgorithmMetadata {
26    pub algorithm: Algorithm,
27    pub category: AlgorithmCategory,
28    pub security_level: u32,
29    pub name: &'static str,
30    pub description: &'static str,
31    pub enabled: bool,
32}
33
34/// Central registry of all algorithms
35#[cfg(any(feature = "std", feature = "alloc"))]
36pub struct AlgorithmRegistry {
37    #[allow(clippy::disallowed_types)]
38    algorithms: HashMap<Algorithm, AlgorithmMetadata>,
39}
40
41#[cfg(any(feature = "std", feature = "alloc"))]
42impl AlgorithmRegistry {
43    /// Create a new algorithm registry
44    pub fn new() -> Self {
45        let mut registry = Self {
46            #[allow(clippy::disallowed_types)]
47            algorithms: HashMap::new(),
48        };
49        registry.register_all();
50        registry
51    }
52
53    /// Register all supported algorithms
54    fn register_all(&mut self) {
55        // KEM algorithms
56        self.register(AlgorithmMetadata {
57            algorithm: Algorithm::MlKem512,
58            category: AlgorithmCategory::Kem,
59            security_level: 1,
60            name: "ML-KEM-512",
61            description: "CRYSTALS-ML-KEM Level 1 (128-bit security)",
62            enabled: true,
63        });
64
65        self.register(AlgorithmMetadata {
66            algorithm: Algorithm::MlKem768,
67            category: AlgorithmCategory::Kem,
68            security_level: 3,
69            name: "ML-KEM-768",
70            description: "CRYSTALS-ML-KEM Level 3 (192-bit security)",
71            enabled: true,
72        });
73
74        self.register(AlgorithmMetadata {
75            algorithm: Algorithm::MlKem1024,
76            category: AlgorithmCategory::Kem,
77            security_level: 4,
78            name: "ML-KEM-1024",
79            description: "CRYSTALS-ML-KEM Level 4 (256-bit security)",
80            enabled: true,
81        });
82
83        // CB-KEM algorithms
84        self.register(AlgorithmMetadata {
85            algorithm: Algorithm::CbKem348864,
86            category: AlgorithmCategory::Kem,
87            security_level: 1,
88            name: "CB-KEM 348864",
89            description: "CB-KEM Level 1 (128-bit security)",
90            enabled: true,
91        });
92
93        self.register(AlgorithmMetadata {
94            algorithm: Algorithm::CbKem460896,
95            category: AlgorithmCategory::Kem,
96            security_level: 3,
97            name: "CB-KEM 460896",
98            description: "CB-KEM Level 3 (192-bit security)",
99            enabled: true,
100        });
101
102        self.register(AlgorithmMetadata {
103            algorithm: Algorithm::CbKem6688128,
104            category: AlgorithmCategory::Kem,
105            security_level: 4,
106            name: "CB-KEM 6688128",
107            description: "CB-KEM Level 4 (256-bit security)",
108            enabled: true,
109        });
110
111        self.register(AlgorithmMetadata {
112            algorithm: Algorithm::CbKem6960119,
113            category: AlgorithmCategory::Kem,
114            security_level: 4,
115            name: "CB-KEM 6960119",
116            description: "CB-KEM Level 4 (256-bit security)",
117            enabled: true,
118        });
119
120        self.register(AlgorithmMetadata {
121            algorithm: Algorithm::CbKem8192128,
122            category: AlgorithmCategory::Kem,
123            security_level: 5,
124            name: "CB-KEM 8192128",
125            description: "CB-KEM Level 5 (256-bit security, higher performance)",
126            enabled: true,
127        });
128
129        // HQC algorithms
130        self.register(AlgorithmMetadata {
131            algorithm: Algorithm::Hqc128,
132            category: AlgorithmCategory::Kem,
133            security_level: 1,
134            name: "HQC-128",
135            description: "HQC Level 1 (128-bit security)",
136            enabled: true,
137        });
138
139        self.register(AlgorithmMetadata {
140            algorithm: Algorithm::Hqc192,
141            category: AlgorithmCategory::Kem,
142            security_level: 3,
143            name: "HQC-192",
144            description: "HQC Level 3 (192-bit security)",
145            enabled: true,
146        });
147
148        self.register(AlgorithmMetadata {
149            algorithm: Algorithm::Hqc256,
150            category: AlgorithmCategory::Kem,
151            security_level: 4,
152            name: "HQC-256",
153            description: "HQC Level 4 (256-bit security)",
154            enabled: true,
155        });
156
157        // Signature algorithms
158        self.register(AlgorithmMetadata {
159            algorithm: Algorithm::MlDsa44,
160            category: AlgorithmCategory::Signature,
161            security_level: 1,
162            name: "ML-DSA-44",
163            description: "CRYSTALS-ML-DSA Level 1 (128-bit security)",
164            enabled: true,
165        });
166
167        self.register(AlgorithmMetadata {
168            algorithm: Algorithm::MlDsa65,
169            category: AlgorithmCategory::Signature,
170            security_level: 3,
171            name: "ML-DSA-65",
172            description: "CRYSTALS-ML-DSA Level 3 (192-bit security)",
173            enabled: true,
174        });
175
176        self.register(AlgorithmMetadata {
177            algorithm: Algorithm::MlDsa87,
178            category: AlgorithmCategory::Signature,
179            security_level: 4,
180            name: "ML-DSA-87",
181            description: "CRYSTALS-ML-DSA Level 4 (256-bit security)",
182            enabled: true,
183        });
184
185        self.register(AlgorithmMetadata {
186            algorithm: Algorithm::FnDsa,
187            category: AlgorithmCategory::Signature,
188            security_level: 1,
189            name: "FN-DSA",
190            description: "FN-DSA (FIPS 206) - Fast Fourier Transform over NTRU-Lattice-Based Digital Signature Algorithm",
191            enabled: true,
192        });
193
194        self.register(AlgorithmMetadata {
195            algorithm: Algorithm::FnDsa512,
196            category: AlgorithmCategory::Signature,
197            security_level: 1,
198            name: "FN-DSA-512",
199            description: "FN-DSA Level 1 (128-bit security) - n=512",
200            enabled: true,
201        });
202
203        self.register(AlgorithmMetadata {
204            algorithm: Algorithm::FnDsa1024,
205            category: AlgorithmCategory::Signature,
206            security_level: 5,
207            name: "FN-DSA-1024",
208            description: "FN-DSA Level 5 (256-bit security) - n=1024",
209            enabled: true,
210        });
211
212        // SLH-DSA algorithms
213        self.register(AlgorithmMetadata {
214            algorithm: Algorithm::SlhDsaSha256128fRobust,
215            category: AlgorithmCategory::Signature,
216            security_level: 1,
217            name: "SLH-DSA-SHA256-128f-Robust",
218            description: "SLH-DSA SHA256 Level 1 (128-bit security)",
219            enabled: true,
220        });
221
222        self.register(AlgorithmMetadata {
223            algorithm: Algorithm::SlhDsaSha256192fRobust,
224            category: AlgorithmCategory::Signature,
225            security_level: 3,
226            name: "SLH-DSA-SHA256-192f-Robust",
227            description: "SLH-DSA SHA256 Level 3 (192-bit security)",
228            enabled: true,
229        });
230
231        self.register(AlgorithmMetadata {
232            algorithm: Algorithm::SlhDsaSha256256fRobust,
233            category: AlgorithmCategory::Signature,
234            security_level: 4,
235            name: "SLH-DSA-SHA256-256f-Robust",
236            description: "SLH-DSA SHA256 Level 4 (256-bit security)",
237            enabled: true,
238        });
239
240        self.register(AlgorithmMetadata {
241            algorithm: Algorithm::SlhDsaShake256128fRobust,
242            category: AlgorithmCategory::Signature,
243            security_level: 1,
244            name: "SLH-DSA-SHAKE256-128f-Robust",
245            description: "SLH-DSA SHAKE256 Level 1 (128-bit security)",
246            enabled: true,
247        });
248
249        self.register(AlgorithmMetadata {
250            algorithm: Algorithm::SlhDsaShake256192fRobust,
251            category: AlgorithmCategory::Signature,
252            security_level: 3,
253            name: "SLH-DSA-SHAKE256-192f-Robust",
254            description: "SLH-DSA SHAKE256 Level 3 (192-bit security)",
255            enabled: true,
256        });
257
258        self.register(AlgorithmMetadata {
259            algorithm: Algorithm::SlhDsaShake256256fRobust,
260            category: AlgorithmCategory::Signature,
261            security_level: 4,
262            name: "SLH-DSA-SHAKE256-256f-Robust",
263            description: "SLH-DSA SHAKE256 Level 4 (256-bit security)",
264            enabled: true,
265        });
266
267        // Hash algorithms
268        self.register(AlgorithmMetadata {
269            algorithm: Algorithm::Shake128,
270            category: AlgorithmCategory::Hash,
271            security_level: 0,
272            name: "SHAKE128",
273            description: "SHAKE128 hash function",
274            enabled: true,
275        });
276
277        self.register(AlgorithmMetadata {
278            algorithm: Algorithm::Shake256,
279            category: AlgorithmCategory::Hash,
280            security_level: 0,
281            name: "SHAKE256",
282            description: "SHAKE256 hash function",
283            enabled: true,
284        });
285
286        self.register(AlgorithmMetadata {
287            algorithm: Algorithm::CShake128,
288            category: AlgorithmCategory::Hash,
289            security_level: 0,
290            name: "cSHAKE128",
291            description: "cSHAKE128 customizable hash function",
292            enabled: true,
293        });
294
295        self.register(AlgorithmMetadata {
296            algorithm: Algorithm::CShake256,
297            category: AlgorithmCategory::Hash,
298            security_level: 0,
299            name: "cSHAKE256",
300            description: "cSHAKE256 customizable hash function",
301            enabled: true,
302        });
303
304        // SHA-3 algorithms
305        self.register(AlgorithmMetadata {
306            algorithm: Algorithm::Sha3_224,
307            category: AlgorithmCategory::Hash,
308            security_level: 0,
309            name: "SHA3-224",
310            description: "SHA3-224 hash function",
311            enabled: true,
312        });
313
314        self.register(AlgorithmMetadata {
315            algorithm: Algorithm::Sha3_256,
316            category: AlgorithmCategory::Hash,
317            security_level: 0,
318            name: "SHA3-256",
319            description: "SHA3-256 hash function",
320            enabled: true,
321        });
322
323        self.register(AlgorithmMetadata {
324            algorithm: Algorithm::Sha3_384,
325            category: AlgorithmCategory::Hash,
326            security_level: 0,
327            name: "SHA3-384",
328            description: "SHA3-384 hash function",
329            enabled: true,
330        });
331
332        self.register(AlgorithmMetadata {
333            algorithm: Algorithm::Sha3_512,
334            category: AlgorithmCategory::Hash,
335            security_level: 0,
336            name: "SHA3-512",
337            description: "SHA3-512 hash function",
338            enabled: true,
339        });
340
341        // KMAC algorithms
342        self.register(AlgorithmMetadata {
343            algorithm: Algorithm::Kmac128,
344            category: AlgorithmCategory::Hash,
345            security_level: 0,
346            name: "KMAC128",
347            description: "KMAC128 keyed hash function",
348            enabled: true,
349        });
350
351        self.register(AlgorithmMetadata {
352            algorithm: Algorithm::Kmac256,
353            category: AlgorithmCategory::Hash,
354            security_level: 0,
355            name: "KMAC256",
356            description: "KMAC256 keyed hash function",
357            enabled: true,
358        });
359
360        // TupleHash algorithms
361        self.register(AlgorithmMetadata {
362            algorithm: Algorithm::TupleHash128,
363            category: AlgorithmCategory::Hash,
364            security_level: 0,
365            name: "TupleHash128",
366            description: "TupleHash128 tuple hashing",
367            enabled: true,
368        });
369
370        self.register(AlgorithmMetadata {
371            algorithm: Algorithm::TupleHash256,
372            category: AlgorithmCategory::Hash,
373            security_level: 0,
374            name: "TupleHash256",
375            description: "TupleHash256 tuple hashing",
376            enabled: true,
377        });
378
379        // ParallelHash algorithms
380        self.register(AlgorithmMetadata {
381            algorithm: Algorithm::ParallelHash128,
382            category: AlgorithmCategory::Hash,
383            security_level: 0,
384            name: "ParallelHash128",
385            description: "ParallelHash128 parallel hashing",
386            enabled: true,
387        });
388
389        self.register(AlgorithmMetadata {
390            algorithm: Algorithm::ParallelHash256,
391            category: AlgorithmCategory::Hash,
392            security_level: 0,
393            name: "ParallelHash256",
394            description: "ParallelHash256 parallel hashing",
395            enabled: true,
396        });
397
398        // Keccak algorithms
399        self.register(AlgorithmMetadata {
400            algorithm: Algorithm::Keccak224,
401            category: AlgorithmCategory::Hash,
402            security_level: 0,
403            name: "Keccak-224",
404            description: "Keccak-224 hash function",
405            enabled: true,
406        });
407
408        self.register(AlgorithmMetadata {
409            algorithm: Algorithm::Keccak256,
410            category: AlgorithmCategory::Hash,
411            security_level: 0,
412            name: "Keccak-256",
413            description: "Keccak-256 hash function",
414            enabled: true,
415        });
416
417        self.register(AlgorithmMetadata {
418            algorithm: Algorithm::Keccak384,
419            category: AlgorithmCategory::Hash,
420            security_level: 0,
421            name: "Keccak-384",
422            description: "Keccak-384 hash function",
423            enabled: true,
424        });
425
426        self.register(AlgorithmMetadata {
427            algorithm: Algorithm::Keccak512,
428            category: AlgorithmCategory::Hash,
429            security_level: 0,
430            name: "Keccak-512",
431            description: "Keccak-512 hash function",
432            enabled: true,
433        });
434
435        // RFC 9861 KangarooTwelve instances
436        self.register(AlgorithmMetadata {
437            algorithm: Algorithm::Kt128,
438            category: AlgorithmCategory::Hash,
439            security_level: 0,
440            name: "KT128",
441            description: "KangarooTwelve with TurboSHAKE128 (RFC 9861)",
442            enabled: true,
443        });
444
445        self.register(AlgorithmMetadata {
446            algorithm: Algorithm::Kt256,
447            category: AlgorithmCategory::Hash,
448            security_level: 0,
449            name: "KT256",
450            description: "KangarooTwelve with TurboSHAKE256 (RFC 9861)",
451            enabled: true,
452        });
453
454        // SHA-2 algorithms
455        self.register(AlgorithmMetadata {
456            algorithm: Algorithm::Sha224,
457            category: AlgorithmCategory::Hash,
458            security_level: 0,
459            name: "SHA-224",
460            description: "SHA-224 hash function",
461            enabled: true,
462        });
463
464        self.register(AlgorithmMetadata {
465            algorithm: Algorithm::Sha256,
466            category: AlgorithmCategory::Hash,
467            security_level: 0,
468            name: "SHA-256",
469            description: "SHA-256 hash function",
470            enabled: true,
471        });
472
473        self.register(AlgorithmMetadata {
474            algorithm: Algorithm::Sha384,
475            category: AlgorithmCategory::Hash,
476            security_level: 0,
477            name: "SHA-384",
478            description: "SHA-384 hash function",
479            enabled: true,
480        });
481
482        self.register(AlgorithmMetadata {
483            algorithm: Algorithm::Sha512,
484            category: AlgorithmCategory::Hash,
485            security_level: 0,
486            name: "SHA-512",
487            description: "SHA-512 hash function",
488            enabled: true,
489        });
490
491        self.register(AlgorithmMetadata {
492            algorithm: Algorithm::Sha512_224,
493            category: AlgorithmCategory::Hash,
494            security_level: 0,
495            name: "SHA-512/224",
496            description: "SHA-512/224 hash function (truncated)",
497            enabled: true,
498        });
499
500        self.register(AlgorithmMetadata {
501            algorithm: Algorithm::Sha512_256,
502            category: AlgorithmCategory::Hash,
503            security_level: 0,
504            name: "SHA-512/256",
505            description: "SHA-512/256 hash function (truncated)",
506            enabled: true,
507        });
508
509        // TurboSHAKE algorithms
510        self.register(AlgorithmMetadata {
511            algorithm: Algorithm::TurboShake128,
512            category: AlgorithmCategory::Hash,
513            security_level: 0,
514            name: "TurboSHAKE128",
515            description: "TurboSHAKE128 extendable-output function",
516            enabled: true,
517        });
518
519        self.register(AlgorithmMetadata {
520            algorithm: Algorithm::TurboShake256,
521            category: AlgorithmCategory::Hash,
522            security_level: 0,
523            name: "TurboSHAKE256",
524            description: "TurboSHAKE256 extendable-output function",
525            enabled: true,
526        });
527
528        // AEAD algorithms
529        self.register(AlgorithmMetadata {
530            algorithm: Algorithm::Saturnin,
531            category: AlgorithmCategory::Aead,
532            security_level: 1,
533            name: "Saturnin",
534            description: "Saturnin - Lightweight post-quantum symmetric algorithm suite for IoT and constrained devices",
535            enabled: true,
536        });
537
538        self.register(AlgorithmMetadata {
539            algorithm: Algorithm::Shake256Aead,
540            category: AlgorithmCategory::Aead,
541            security_level: 1,
542            name: "SHAKE256-AEAD",
543            description: "SHAKE256-based AEAD construction using post-quantum hash function",
544            enabled: true,
545        });
546
547        self.register(AlgorithmMetadata {
548            algorithm: Algorithm::DuplexSpongeAead,
549            category: AlgorithmCategory::Aead,
550            security_level: 4,
551            name: "Duplex-Sponge-AEAD",
552            description: "Keccak-f[1600] duplex-sponge authenticated encryption (SHA-3 family permutation)",
553            enabled: true,
554        });
555
556        self.register(AlgorithmMetadata {
557            algorithm: Algorithm::TweakAead,
558            category: AlgorithmCategory::Aead,
559            security_level: 4,
560            name: "Tweak-AEAD",
561            description: "Parallel tweakable-block CTR AEAD over Keccak-f[1600] with independent 32-byte blocks",
562            enabled: true,
563        });
564
565        self.register(AlgorithmMetadata {
566            algorithm: Algorithm::RomulusN,
567            category: AlgorithmCategory::Aead,
568            security_level: 1,
569            name: "Romulus-N",
570            description: "Romulus-N nonce-based AEAD (SKINNY-128-384+), LWC v1.3",
571            enabled: true,
572        });
573
574        self.register(AlgorithmMetadata {
575            algorithm: Algorithm::RomulusM,
576            category: AlgorithmCategory::Aead,
577            security_level: 1,
578            name: "Romulus-M",
579            description: "Romulus-M misuse-resistant AEAD (SKINNY-128-384+), LWC v1.3",
580            enabled: true,
581        });
582
583        // Privacy-oriented protocol identifiers (implementations: lib-q-lattice-zkp, lib-q-ring-sig)
584        self.register(AlgorithmMetadata {
585            algorithm: Algorithm::LatticeRingSignature,
586            category: AlgorithmCategory::PrivacyProtocol,
587            security_level: 3,
588            name: "Lattice federation ring signature",
589            description: "Federation ring-style opening proofs over Ajtai commitments (lib-q-ring-sig)",
590            enabled: true,
591        });
592        self.register(AlgorithmMetadata {
593            algorithm: Algorithm::LatticeBlindIssuance,
594            category: AlgorithmCategory::PrivacyProtocol,
595            security_level: 3,
596            name: "Lattice blind issuance",
597            description: "CRS blind issuance plumbing and issuer attestation (lib-q-lattice-zkp/blind)",
598            enabled: true,
599        });
600        self.register(AlgorithmMetadata {
601            algorithm: Algorithm::LatticeAnonymousToken,
602            category: AlgorithmCategory::PrivacyProtocol,
603            security_level: 3,
604            name: "Lattice anonymous token",
605            description: "Commitment-backed anonymous token and spending proof (lib-q-lattice-zkp/token)",
606            enabled: true,
607        });
608        self.register(AlgorithmMetadata {
609            algorithm: Algorithm::LatticeNullifierRegistry,
610            category: AlgorithmCategory::PrivacyProtocol,
611            security_level: 3,
612            name: "Lattice nullifier registry",
613            description: "SHAKE256 nullifier binding for Sybil-evidence style proofs (lib-q-lattice-zkp/sigma/uniqueness)",
614            enabled: true,
615        });
616        self.register(AlgorithmMetadata {
617            algorithm: Algorithm::LatticeWitnessNullifier,
618            category: AlgorithmCategory::PrivacyProtocol,
619            security_level: 3,
620            name: "Lattice witness nullifier",
621            description: "Witness-derived SHAKE256 nullifier and opening binding (lib-q-lattice-zkp/sigma/uniqueness)",
622            enabled: true,
623        });
624        self.register(AlgorithmMetadata {
625            algorithm: Algorithm::LatticeDualRingLb,
626            category: AlgorithmCategory::PrivacyProtocol,
627            security_level: 3,
628            name: "Lattice DualRing-LB pilot",
629            description: "DualRing-LB (CCS 2021 Alg. 3) aggregated opening verify over Ajtai ring (lib-q-ring-sig/dualring_lb)",
630            enabled: true,
631        });
632        self.register(AlgorithmMetadata {
633            algorithm: Algorithm::MixOnionRouting,
634            category: AlgorithmCategory::PrivacyProtocol,
635            security_level: 3,
636            name: "Mix-layer onion routing",
637            description: "ML-KEM-768 layered encapsulation with Saturnin AEAD per hop",
638            enabled: true,
639        });
640        self.register(AlgorithmMetadata {
641            algorithm: Algorithm::SessionResumptionBinding,
642            category: AlgorithmCategory::PrivacyProtocol,
643            security_level: 3,
644            name: "Session resumption binding",
645            description: "SHAKE256 session token and stateless retry-cookie derivation",
646            enabled: true,
647        });
648    }
649
650    /// Register an algorithm
651    fn register(&mut self, metadata: AlgorithmMetadata) {
652        self.algorithms.insert(metadata.algorithm, metadata);
653    }
654
655    /// Get all supported algorithms
656    #[cfg(feature = "alloc")]
657    pub fn supported_algorithms(&self) -> Vec<Algorithm> {
658        self.algorithms
659            .values()
660            .filter(|meta| meta.enabled)
661            .map(|meta| meta.algorithm)
662            .collect()
663    }
664
665    #[cfg(not(feature = "alloc"))]
666    pub fn supported_algorithms(&self) -> &'static [Algorithm] {
667        // In no_std mode, return a static slice of enabled algorithms
668        static ALGORITHMS: &[Algorithm] = &[
669            Algorithm::MlKem512,
670            Algorithm::MlKem768,
671            Algorithm::MlKem1024,
672            Algorithm::MlDsa44,
673            Algorithm::MlDsa65,
674            Algorithm::MlDsa87,
675            Algorithm::FnDsa,
676            Algorithm::FnDsa512,
677            Algorithm::FnDsa1024,
678        ];
679        ALGORITHMS
680    }
681
682    /// Get algorithms by category
683    #[cfg(feature = "alloc")]
684    pub fn algorithms_by_category(&self, category: AlgorithmCategory) -> Vec<Algorithm> {
685        self.algorithms
686            .values()
687            .filter(|meta| meta.enabled && meta.category == category)
688            .map(|meta| meta.algorithm)
689            .collect()
690    }
691
692    #[cfg(not(feature = "alloc"))]
693    pub fn algorithms_by_category(&self, category: AlgorithmCategory) -> &'static [Algorithm] {
694        // In no_std mode, return a static slice based on category
695        match category {
696            AlgorithmCategory::Kem => &[
697                Algorithm::MlKem512,
698                Algorithm::MlKem768,
699                Algorithm::MlKem1024,
700            ],
701            AlgorithmCategory::Signature => &[
702                Algorithm::MlDsa44,
703                Algorithm::MlDsa65,
704                Algorithm::MlDsa87,
705                Algorithm::FnDsa,
706                Algorithm::FnDsa512,
707                Algorithm::FnDsa1024,
708            ],
709            AlgorithmCategory::Hash => &[
710                Algorithm::Sha224,
711                Algorithm::Sha256,
712                Algorithm::Sha384,
713                Algorithm::Sha512,
714                Algorithm::Sha512_224,
715                Algorithm::Sha512_256,
716            ],
717            AlgorithmCategory::Aead => &[
718                Algorithm::Saturnin,
719                Algorithm::Shake256Aead,
720                Algorithm::DuplexSpongeAead,
721                Algorithm::TweakAead,
722                Algorithm::RomulusN,
723                Algorithm::RomulusM,
724            ],
725            AlgorithmCategory::PrivacyProtocol => &[
726                Algorithm::LatticeRingSignature,
727                Algorithm::LatticeBlindIssuance,
728                Algorithm::LatticeAnonymousToken,
729                Algorithm::LatticeNullifierRegistry,
730                Algorithm::LatticeWitnessNullifier,
731                Algorithm::LatticeDualRingLb,
732                Algorithm::MixOnionRouting,
733                Algorithm::SessionResumptionBinding,
734            ],
735        }
736    }
737
738    /// Get algorithms by security level
739    #[cfg(feature = "alloc")]
740    pub fn algorithms_by_security_level(&self, level: u32) -> Vec<Algorithm> {
741        self.algorithms
742            .values()
743            .filter(|meta| meta.enabled && meta.security_level == level)
744            .map(|meta| meta.algorithm)
745            .collect()
746    }
747
748    #[cfg(not(feature = "alloc"))]
749    pub fn algorithms_by_security_level(&self, level: u32) -> &'static [Algorithm] {
750        // In no_std mode, return a static slice based on security level
751        match level {
752            1 => &[
753                Algorithm::MlKem512,
754                Algorithm::MlDsa44,
755                Algorithm::FnDsa,
756                Algorithm::FnDsa512,
757                Algorithm::Saturnin,
758                Algorithm::Shake256Aead,
759                Algorithm::RomulusN,
760                Algorithm::RomulusM,
761            ],
762            3 => &[
763                Algorithm::MlKem768,
764                Algorithm::MlDsa65,
765                Algorithm::LatticeRingSignature,
766                Algorithm::LatticeBlindIssuance,
767                Algorithm::LatticeAnonymousToken,
768                Algorithm::LatticeNullifierRegistry,
769                Algorithm::LatticeWitnessNullifier,
770                Algorithm::LatticeDualRingLb,
771                Algorithm::MixOnionRouting,
772                Algorithm::SessionResumptionBinding,
773            ],
774            4 => &[
775                Algorithm::MlKem1024,
776                Algorithm::MlDsa87,
777                Algorithm::DuplexSpongeAead,
778                Algorithm::TweakAead,
779            ],
780            5 => &[Algorithm::FnDsa1024],
781            _ => &[],
782        }
783    }
784
785    /// Get algorithm metadata
786    pub fn get_metadata(&self, algorithm: &Algorithm) -> Option<&AlgorithmMetadata> {
787        self.algorithms.get(algorithm)
788    }
789
790    /// Check if algorithm is enabled
791    pub fn is_enabled(&self, algorithm: &Algorithm) -> bool {
792        self.algorithms
793            .get(algorithm)
794            .map(|meta| meta.enabled)
795            .unwrap_or(false)
796    }
797
798    /// Enable/disable an algorithm
799    pub fn set_enabled(&mut self, algorithm: Algorithm, enabled: bool) -> Result<()> {
800        if let Some(metadata) = self.algorithms.get_mut(&algorithm) {
801            metadata.enabled = enabled;
802            Ok(())
803        } else {
804            #[cfg(feature = "alloc")]
805            {
806                Err(crate::Error::UnsupportedAlgorithm {
807                    algorithm: "unsupported algorithm".to_string(),
808                })
809            }
810            #[cfg(not(feature = "alloc"))]
811            {
812                Err(crate::Error::UnsupportedAlgorithm {
813                    algorithm: "unsupported algorithm",
814                })
815            }
816        }
817    }
818}
819
820#[cfg(any(feature = "std", feature = "alloc"))]
821impl Default for AlgorithmRegistry {
822    fn default() -> Self {
823        Self::new()
824    }
825}
826
827// Global algorithm registry instance
828// Note: AlgorithmRegistry requires alloc (uses HashMap/BTreeMap)
829#[cfg(all(feature = "alloc", feature = "std"))]
830static REGISTRY: once_cell::sync::Lazy<AlgorithmRegistry> =
831    once_cell::sync::Lazy::new(AlgorithmRegistry::new);
832
833#[cfg(all(feature = "alloc", not(feature = "std"), feature = "spin"))]
834static REGISTRY: spin::Once<AlgorithmRegistry> = spin::Once::new();
835
836/// Get the global algorithm registry
837/// Requires alloc feature (registry uses HashMap/BTreeMap internally)
838#[cfg(all(feature = "alloc", feature = "std"))]
839pub fn registry() -> &'static AlgorithmRegistry {
840    &REGISTRY
841}
842
843#[cfg(all(feature = "alloc", not(feature = "std"), feature = "spin"))]
844pub fn registry() -> &'static AlgorithmRegistry {
845    REGISTRY.call_once(AlgorithmRegistry::new)
846}
847
848// registry() is not available in no_alloc mode
849// Use supported_algorithms() etc. which return static slices directly
850
851/// Get all supported algorithms
852#[cfg(all(feature = "alloc", any(feature = "std", feature = "spin")))]
853pub fn supported_algorithms() -> Vec<Algorithm> {
854    registry().supported_algorithms()
855}
856
857#[cfg(all(feature = "alloc", not(any(feature = "std", feature = "spin"))))]
858pub fn supported_algorithms() -> Vec<Algorithm> {
859    AlgorithmRegistry::new().supported_algorithms()
860}
861
862#[cfg(not(feature = "alloc"))]
863pub fn supported_algorithms() -> &'static [Algorithm] {
864    // In no_alloc mode, return static slice directly without using registry
865    static ALGORITHMS: &[Algorithm] = &[
866        Algorithm::MlKem512,
867        Algorithm::MlKem768,
868        Algorithm::MlKem1024,
869        Algorithm::MlDsa44,
870        Algorithm::MlDsa65,
871        Algorithm::MlDsa87,
872        Algorithm::FnDsa,
873        Algorithm::FnDsa512,
874        Algorithm::FnDsa1024,
875    ];
876    ALGORITHMS
877}
878
879/// Get algorithms by category
880#[cfg(all(feature = "alloc", any(feature = "std", feature = "spin")))]
881pub fn algorithms_by_category(category: AlgorithmCategory) -> Vec<Algorithm> {
882    registry().algorithms_by_category(category)
883}
884
885#[cfg(all(feature = "alloc", not(any(feature = "std", feature = "spin"))))]
886pub fn algorithms_by_category(category: AlgorithmCategory) -> Vec<Algorithm> {
887    AlgorithmRegistry::new().algorithms_by_category(category)
888}
889
890#[cfg(not(feature = "alloc"))]
891pub fn algorithms_by_category(category: AlgorithmCategory) -> &'static [Algorithm] {
892    // In no_alloc mode, return static slice directly without using registry
893    match category {
894        AlgorithmCategory::Kem => &[
895            Algorithm::MlKem512,
896            Algorithm::MlKem768,
897            Algorithm::MlKem1024,
898        ],
899        AlgorithmCategory::Signature => &[
900            Algorithm::MlDsa44,
901            Algorithm::MlDsa65,
902            Algorithm::MlDsa87,
903            Algorithm::FnDsa,
904            Algorithm::FnDsa512,
905            Algorithm::FnDsa1024,
906        ],
907        AlgorithmCategory::Hash => &[
908            Algorithm::Sha224,
909            Algorithm::Sha256,
910            Algorithm::Sha384,
911            Algorithm::Sha512,
912        ],
913        AlgorithmCategory::Aead => &[
914            Algorithm::Saturnin,
915            Algorithm::Shake256Aead,
916            Algorithm::DuplexSpongeAead,
917            Algorithm::TweakAead,
918            Algorithm::RomulusN,
919            Algorithm::RomulusM,
920        ],
921        AlgorithmCategory::PrivacyProtocol => &[
922            Algorithm::LatticeRingSignature,
923            Algorithm::LatticeBlindIssuance,
924            Algorithm::LatticeAnonymousToken,
925            Algorithm::LatticeNullifierRegistry,
926            Algorithm::LatticeWitnessNullifier,
927            Algorithm::LatticeDualRingLb,
928            Algorithm::MixOnionRouting,
929            Algorithm::SessionResumptionBinding,
930        ],
931    }
932}
933
934/// Get algorithms by security level
935#[cfg(all(feature = "alloc", any(feature = "std", feature = "spin")))]
936pub fn algorithms_by_security_level(level: u32) -> Vec<Algorithm> {
937    registry().algorithms_by_security_level(level)
938}
939
940#[cfg(all(feature = "alloc", not(any(feature = "std", feature = "spin"))))]
941pub fn algorithms_by_security_level(level: u32) -> Vec<Algorithm> {
942    AlgorithmRegistry::new().algorithms_by_security_level(level)
943}
944
945#[cfg(not(feature = "alloc"))]
946pub fn algorithms_by_security_level(level: u32) -> &'static [Algorithm] {
947    // In no_alloc mode, return static slice directly without using registry
948    match level {
949        1 => &[
950            Algorithm::MlKem512,
951            Algorithm::MlDsa44,
952            Algorithm::FnDsa,
953            Algorithm::FnDsa512,
954            Algorithm::Saturnin,
955            Algorithm::Shake256Aead,
956            Algorithm::RomulusN,
957            Algorithm::RomulusM,
958        ],
959        3 => &[
960            Algorithm::MlKem768,
961            Algorithm::MlDsa65,
962            Algorithm::LatticeRingSignature,
963            Algorithm::LatticeBlindIssuance,
964            Algorithm::LatticeAnonymousToken,
965            Algorithm::LatticeNullifierRegistry,
966            Algorithm::LatticeWitnessNullifier,
967            Algorithm::LatticeDualRingLb,
968            Algorithm::MixOnionRouting,
969            Algorithm::SessionResumptionBinding,
970        ],
971        4 => &[
972            Algorithm::MlKem1024,
973            Algorithm::MlDsa87,
974            Algorithm::DuplexSpongeAead,
975            Algorithm::TweakAead,
976        ],
977        5 => &[Algorithm::FnDsa1024],
978        _ => &[],
979    }
980}
981
982#[cfg(test)]
983mod tests {
984    use super::*;
985
986    #[test]
987    fn test_algorithm_registry() {
988        let registry = AlgorithmRegistry::new();
989
990        // Test that we have algorithms
991        let algorithms = registry.supported_algorithms();
992        assert!(!algorithms.is_empty());
993
994        // Test category filtering
995        let kem_algorithms = registry.algorithms_by_category(AlgorithmCategory::Kem);
996        assert!(!kem_algorithms.is_empty());
997
998        // Test security level filtering
999        let level1_algorithms = registry.algorithms_by_security_level(1);
1000        assert!(!level1_algorithms.is_empty());
1001
1002        // Test metadata retrieval
1003        let metadata = registry.get_metadata(&Algorithm::MlKem512);
1004        assert!(metadata.is_some());
1005        assert_eq!(metadata.unwrap().name, "ML-KEM-512");
1006    }
1007
1008    #[test]
1009    fn test_global_registry() {
1010        let algorithms = supported_algorithms();
1011        assert!(!algorithms.is_empty());
1012
1013        let kem_algorithms = algorithms_by_category(AlgorithmCategory::Kem);
1014        assert!(!kem_algorithms.is_empty());
1015    }
1016}