1#[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#[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#[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 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 fn register_all(&mut self) {
55 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 {
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 fn register(&mut self, metadata: AlgorithmMetadata) {
652 self.algorithms.insert(metadata.algorithm, metadata);
653 }
654
655 #[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 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 #[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 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 #[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 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 pub fn get_metadata(&self, algorithm: &Algorithm) -> Option<&AlgorithmMetadata> {
787 self.algorithms.get(algorithm)
788 }
789
790 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 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#[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#[cfg(all(feature = "alloc", feature = "std"))]
839pub fn registry() -> &'static AlgorithmRegistry {
840 ®ISTRY
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#[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 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#[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 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#[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 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 let algorithms = registry.supported_algorithms();
992 assert!(!algorithms.is_empty());
993
994 let kem_algorithms = registry.algorithms_by_category(AlgorithmCategory::Kem);
996 assert!(!kem_algorithms.is_empty());
997
998 let level1_algorithms = registry.algorithms_by_security_level(1);
1000 assert!(!level1_algorithms.is_empty());
1001
1002 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}