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        self.register(AlgorithmMetadata {
584            algorithm: Algorithm::RoccaS,
585            category: AlgorithmCategory::Aead,
586            security_level: 1,
587            name: "Rocca-S",
588            description: "Rocca-S high-throughput AES-round AEAD (IETF draft-nakano-rocca-s); 256-bit key/tag, 128-bit nonce",
589            enabled: true,
590        });
591
592        // Privacy-oriented protocol identifiers (implementations: lib-q-lattice-zkp, lib-q-ring-sig)
593        self.register(AlgorithmMetadata {
594            algorithm: Algorithm::LatticeRingSignature,
595            category: AlgorithmCategory::PrivacyProtocol,
596            security_level: 3,
597            name: "Lattice federation ring signature",
598            description: "Federation ring-style opening proofs over Ajtai commitments (lib-q-ring-sig)",
599            enabled: true,
600        });
601        self.register(AlgorithmMetadata {
602            algorithm: Algorithm::LatticeBlindIssuance,
603            category: AlgorithmCategory::PrivacyProtocol,
604            security_level: 3,
605            name: "Lattice blind issuance",
606            description: "CRS blind issuance plumbing and issuer attestation (lib-q-lattice-zkp/blind)",
607            enabled: true,
608        });
609        self.register(AlgorithmMetadata {
610            algorithm: Algorithm::LatticeAnonymousToken,
611            category: AlgorithmCategory::PrivacyProtocol,
612            security_level: 3,
613            name: "Lattice anonymous token",
614            description: "Commitment-backed anonymous token and spending proof (lib-q-lattice-zkp/token)",
615            enabled: true,
616        });
617        self.register(AlgorithmMetadata {
618            algorithm: Algorithm::LatticeNullifierRegistry,
619            category: AlgorithmCategory::PrivacyProtocol,
620            security_level: 3,
621            name: "Lattice nullifier registry",
622            description: "SHAKE256 nullifier binding for Sybil-evidence style proofs (lib-q-lattice-zkp/sigma/uniqueness)",
623            enabled: true,
624        });
625        self.register(AlgorithmMetadata {
626            algorithm: Algorithm::LatticeWitnessNullifier,
627            category: AlgorithmCategory::PrivacyProtocol,
628            security_level: 3,
629            name: "Lattice witness nullifier",
630            description: "Witness-derived SHAKE256 nullifier and opening binding (lib-q-lattice-zkp/sigma/uniqueness)",
631            enabled: true,
632        });
633        self.register(AlgorithmMetadata {
634            algorithm: Algorithm::LatticeDualRingLb,
635            category: AlgorithmCategory::PrivacyProtocol,
636            security_level: 3,
637            name: "Lattice DualRing-LB pilot",
638            description: "DualRing-LB (CCS 2021 Alg. 3) aggregated opening verify over Ajtai ring (lib-q-ring-sig/dualring_lb)",
639            enabled: true,
640        });
641        self.register(AlgorithmMetadata {
642            algorithm: Algorithm::MixOnionRouting,
643            category: AlgorithmCategory::PrivacyProtocol,
644            security_level: 3,
645            name: "Mix-layer onion routing",
646            description: "ML-KEM-768 layered encapsulation with Saturnin AEAD per hop",
647            enabled: true,
648        });
649        self.register(AlgorithmMetadata {
650            algorithm: Algorithm::SessionResumptionBinding,
651            category: AlgorithmCategory::PrivacyProtocol,
652            security_level: 3,
653            name: "Session resumption binding",
654            description: "SHAKE256 session token and stateless retry-cookie derivation",
655            enabled: true,
656        });
657    }
658
659    /// Register an algorithm
660    fn register(&mut self, metadata: AlgorithmMetadata) {
661        self.algorithms.insert(metadata.algorithm, metadata);
662    }
663
664    /// Get all supported algorithms
665    #[cfg(feature = "alloc")]
666    pub fn supported_algorithms(&self) -> Vec<Algorithm> {
667        self.algorithms
668            .values()
669            .filter(|meta| meta.enabled)
670            .map(|meta| meta.algorithm)
671            .collect()
672    }
673
674    #[cfg(not(feature = "alloc"))]
675    pub fn supported_algorithms(&self) -> &'static [Algorithm] {
676        // In no_std mode, return a static slice of enabled algorithms
677        static ALGORITHMS: &[Algorithm] = &[
678            Algorithm::MlKem512,
679            Algorithm::MlKem768,
680            Algorithm::MlKem1024,
681            Algorithm::MlDsa44,
682            Algorithm::MlDsa65,
683            Algorithm::MlDsa87,
684            Algorithm::FnDsa,
685            Algorithm::FnDsa512,
686            Algorithm::FnDsa1024,
687        ];
688        ALGORITHMS
689    }
690
691    /// Get algorithms by category
692    #[cfg(feature = "alloc")]
693    pub fn algorithms_by_category(&self, category: AlgorithmCategory) -> Vec<Algorithm> {
694        self.algorithms
695            .values()
696            .filter(|meta| meta.enabled && meta.category == category)
697            .map(|meta| meta.algorithm)
698            .collect()
699    }
700
701    #[cfg(not(feature = "alloc"))]
702    pub fn algorithms_by_category(&self, category: AlgorithmCategory) -> &'static [Algorithm] {
703        // In no_std mode, return a static slice based on category
704        match category {
705            AlgorithmCategory::Kem => &[
706                Algorithm::MlKem512,
707                Algorithm::MlKem768,
708                Algorithm::MlKem1024,
709            ],
710            AlgorithmCategory::Signature => &[
711                Algorithm::MlDsa44,
712                Algorithm::MlDsa65,
713                Algorithm::MlDsa87,
714                Algorithm::FnDsa,
715                Algorithm::FnDsa512,
716                Algorithm::FnDsa1024,
717            ],
718            AlgorithmCategory::Hash => &[
719                Algorithm::Sha224,
720                Algorithm::Sha256,
721                Algorithm::Sha384,
722                Algorithm::Sha512,
723                Algorithm::Sha512_224,
724                Algorithm::Sha512_256,
725            ],
726            AlgorithmCategory::Aead => &[
727                Algorithm::Saturnin,
728                Algorithm::Shake256Aead,
729                Algorithm::DuplexSpongeAead,
730                Algorithm::TweakAead,
731                Algorithm::RomulusN,
732                Algorithm::RomulusM,
733            ],
734            AlgorithmCategory::PrivacyProtocol => &[
735                Algorithm::LatticeRingSignature,
736                Algorithm::LatticeBlindIssuance,
737                Algorithm::LatticeAnonymousToken,
738                Algorithm::LatticeNullifierRegistry,
739                Algorithm::LatticeWitnessNullifier,
740                Algorithm::LatticeDualRingLb,
741                Algorithm::MixOnionRouting,
742                Algorithm::SessionResumptionBinding,
743            ],
744        }
745    }
746
747    /// Get algorithms by security level
748    #[cfg(feature = "alloc")]
749    pub fn algorithms_by_security_level(&self, level: u32) -> Vec<Algorithm> {
750        self.algorithms
751            .values()
752            .filter(|meta| meta.enabled && meta.security_level == level)
753            .map(|meta| meta.algorithm)
754            .collect()
755    }
756
757    #[cfg(not(feature = "alloc"))]
758    pub fn algorithms_by_security_level(&self, level: u32) -> &'static [Algorithm] {
759        // In no_std mode, return a static slice based on security level
760        match level {
761            1 => &[
762                Algorithm::MlKem512,
763                Algorithm::MlDsa44,
764                Algorithm::FnDsa,
765                Algorithm::FnDsa512,
766                Algorithm::Saturnin,
767                Algorithm::Shake256Aead,
768                Algorithm::RomulusN,
769                Algorithm::RomulusM,
770            ],
771            3 => &[
772                Algorithm::MlKem768,
773                Algorithm::MlDsa65,
774                Algorithm::LatticeRingSignature,
775                Algorithm::LatticeBlindIssuance,
776                Algorithm::LatticeAnonymousToken,
777                Algorithm::LatticeNullifierRegistry,
778                Algorithm::LatticeWitnessNullifier,
779                Algorithm::LatticeDualRingLb,
780                Algorithm::MixOnionRouting,
781                Algorithm::SessionResumptionBinding,
782            ],
783            4 => &[
784                Algorithm::MlKem1024,
785                Algorithm::MlDsa87,
786                Algorithm::DuplexSpongeAead,
787                Algorithm::TweakAead,
788            ],
789            5 => &[Algorithm::FnDsa1024],
790            _ => &[],
791        }
792    }
793
794    /// Get algorithm metadata
795    pub fn get_metadata(&self, algorithm: &Algorithm) -> Option<&AlgorithmMetadata> {
796        self.algorithms.get(algorithm)
797    }
798
799    /// Check if algorithm is enabled
800    pub fn is_enabled(&self, algorithm: &Algorithm) -> bool {
801        self.algorithms
802            .get(algorithm)
803            .map(|meta| meta.enabled)
804            .unwrap_or(false)
805    }
806
807    /// Enable/disable an algorithm
808    pub fn set_enabled(&mut self, algorithm: Algorithm, enabled: bool) -> Result<()> {
809        if let Some(metadata) = self.algorithms.get_mut(&algorithm) {
810            metadata.enabled = enabled;
811            Ok(())
812        } else {
813            #[cfg(feature = "alloc")]
814            {
815                Err(crate::Error::UnsupportedAlgorithm {
816                    algorithm: "unsupported algorithm".to_string(),
817                })
818            }
819            #[cfg(not(feature = "alloc"))]
820            {
821                Err(crate::Error::UnsupportedAlgorithm {
822                    algorithm: "unsupported algorithm",
823                })
824            }
825        }
826    }
827}
828
829#[cfg(any(feature = "std", feature = "alloc"))]
830impl Default for AlgorithmRegistry {
831    fn default() -> Self {
832        Self::new()
833    }
834}
835
836// Global algorithm registry instance
837// Note: AlgorithmRegistry requires alloc (uses HashMap/BTreeMap)
838#[cfg(all(feature = "alloc", feature = "std"))]
839static REGISTRY: once_cell::sync::Lazy<AlgorithmRegistry> =
840    once_cell::sync::Lazy::new(AlgorithmRegistry::new);
841
842#[cfg(all(feature = "alloc", not(feature = "std"), feature = "spin"))]
843static REGISTRY: spin::Once<AlgorithmRegistry> = spin::Once::new();
844
845/// Get the global algorithm registry
846/// Requires alloc feature (registry uses HashMap/BTreeMap internally)
847#[cfg(all(feature = "alloc", feature = "std"))]
848pub fn registry() -> &'static AlgorithmRegistry {
849    &REGISTRY
850}
851
852#[cfg(all(feature = "alloc", not(feature = "std"), feature = "spin"))]
853pub fn registry() -> &'static AlgorithmRegistry {
854    REGISTRY.call_once(AlgorithmRegistry::new)
855}
856
857// registry() is not available in no_alloc mode
858// Use supported_algorithms() etc. which return static slices directly
859
860/// Get all supported algorithms
861#[cfg(all(feature = "alloc", any(feature = "std", feature = "spin")))]
862pub fn supported_algorithms() -> Vec<Algorithm> {
863    registry().supported_algorithms()
864}
865
866#[cfg(all(feature = "alloc", not(any(feature = "std", feature = "spin"))))]
867pub fn supported_algorithms() -> Vec<Algorithm> {
868    AlgorithmRegistry::new().supported_algorithms()
869}
870
871#[cfg(not(feature = "alloc"))]
872pub fn supported_algorithms() -> &'static [Algorithm] {
873    // In no_alloc mode, return static slice directly without using registry
874    static ALGORITHMS: &[Algorithm] = &[
875        Algorithm::MlKem512,
876        Algorithm::MlKem768,
877        Algorithm::MlKem1024,
878        Algorithm::MlDsa44,
879        Algorithm::MlDsa65,
880        Algorithm::MlDsa87,
881        Algorithm::FnDsa,
882        Algorithm::FnDsa512,
883        Algorithm::FnDsa1024,
884    ];
885    ALGORITHMS
886}
887
888/// Get algorithms by category
889#[cfg(all(feature = "alloc", any(feature = "std", feature = "spin")))]
890pub fn algorithms_by_category(category: AlgorithmCategory) -> Vec<Algorithm> {
891    registry().algorithms_by_category(category)
892}
893
894#[cfg(all(feature = "alloc", not(any(feature = "std", feature = "spin"))))]
895pub fn algorithms_by_category(category: AlgorithmCategory) -> Vec<Algorithm> {
896    AlgorithmRegistry::new().algorithms_by_category(category)
897}
898
899#[cfg(not(feature = "alloc"))]
900pub fn algorithms_by_category(category: AlgorithmCategory) -> &'static [Algorithm] {
901    // In no_alloc mode, return static slice directly without using registry
902    match category {
903        AlgorithmCategory::Kem => &[
904            Algorithm::MlKem512,
905            Algorithm::MlKem768,
906            Algorithm::MlKem1024,
907        ],
908        AlgorithmCategory::Signature => &[
909            Algorithm::MlDsa44,
910            Algorithm::MlDsa65,
911            Algorithm::MlDsa87,
912            Algorithm::FnDsa,
913            Algorithm::FnDsa512,
914            Algorithm::FnDsa1024,
915        ],
916        AlgorithmCategory::Hash => &[
917            Algorithm::Sha224,
918            Algorithm::Sha256,
919            Algorithm::Sha384,
920            Algorithm::Sha512,
921        ],
922        AlgorithmCategory::Aead => &[
923            Algorithm::Saturnin,
924            Algorithm::Shake256Aead,
925            Algorithm::DuplexSpongeAead,
926            Algorithm::TweakAead,
927            Algorithm::RomulusN,
928            Algorithm::RomulusM,
929        ],
930        AlgorithmCategory::PrivacyProtocol => &[
931            Algorithm::LatticeRingSignature,
932            Algorithm::LatticeBlindIssuance,
933            Algorithm::LatticeAnonymousToken,
934            Algorithm::LatticeNullifierRegistry,
935            Algorithm::LatticeWitnessNullifier,
936            Algorithm::LatticeDualRingLb,
937            Algorithm::MixOnionRouting,
938            Algorithm::SessionResumptionBinding,
939        ],
940    }
941}
942
943/// Get algorithms by security level
944#[cfg(all(feature = "alloc", any(feature = "std", feature = "spin")))]
945pub fn algorithms_by_security_level(level: u32) -> Vec<Algorithm> {
946    registry().algorithms_by_security_level(level)
947}
948
949#[cfg(all(feature = "alloc", not(any(feature = "std", feature = "spin"))))]
950pub fn algorithms_by_security_level(level: u32) -> Vec<Algorithm> {
951    AlgorithmRegistry::new().algorithms_by_security_level(level)
952}
953
954#[cfg(not(feature = "alloc"))]
955pub fn algorithms_by_security_level(level: u32) -> &'static [Algorithm] {
956    // In no_alloc mode, return static slice directly without using registry
957    match level {
958        1 => &[
959            Algorithm::MlKem512,
960            Algorithm::MlDsa44,
961            Algorithm::FnDsa,
962            Algorithm::FnDsa512,
963            Algorithm::Saturnin,
964            Algorithm::Shake256Aead,
965            Algorithm::RomulusN,
966            Algorithm::RomulusM,
967        ],
968        3 => &[
969            Algorithm::MlKem768,
970            Algorithm::MlDsa65,
971            Algorithm::LatticeRingSignature,
972            Algorithm::LatticeBlindIssuance,
973            Algorithm::LatticeAnonymousToken,
974            Algorithm::LatticeNullifierRegistry,
975            Algorithm::LatticeWitnessNullifier,
976            Algorithm::LatticeDualRingLb,
977            Algorithm::MixOnionRouting,
978            Algorithm::SessionResumptionBinding,
979        ],
980        4 => &[
981            Algorithm::MlKem1024,
982            Algorithm::MlDsa87,
983            Algorithm::DuplexSpongeAead,
984            Algorithm::TweakAead,
985        ],
986        5 => &[Algorithm::FnDsa1024],
987        _ => &[],
988    }
989}
990
991#[cfg(test)]
992mod tests {
993    use super::*;
994
995    #[test]
996    fn test_algorithm_registry() {
997        let registry = AlgorithmRegistry::new();
998
999        // Test that we have algorithms
1000        let algorithms = registry.supported_algorithms();
1001        assert!(!algorithms.is_empty());
1002
1003        // Test category filtering
1004        let kem_algorithms = registry.algorithms_by_category(AlgorithmCategory::Kem);
1005        assert!(!kem_algorithms.is_empty());
1006
1007        // Test security level filtering
1008        let level1_algorithms = registry.algorithms_by_security_level(1);
1009        assert!(!level1_algorithms.is_empty());
1010
1011        // Test metadata retrieval
1012        let metadata = registry.get_metadata(&Algorithm::MlKem512);
1013        assert!(metadata.is_some());
1014        assert_eq!(metadata.unwrap().name, "ML-KEM-512");
1015    }
1016
1017    #[test]
1018    fn test_global_registry() {
1019        let algorithms = supported_algorithms();
1020        assert!(!algorithms.is_empty());
1021
1022        let kem_algorithms = algorithms_by_category(AlgorithmCategory::Kem);
1023        assert!(!kem_algorithms.is_empty());
1024    }
1025}