pqc_binary_format/
algorithm.rs

1//! Algorithm identifiers for supported post-quantum cryptographic algorithms.
2
3use serde::{Deserialize, Serialize};
4
5/// Algorithm identifier type
6pub type AlgorithmId = u16;
7
8/// Supported cryptographic algorithms with unique identifiers
9///
10/// Each algorithm has a unique 16-bit identifier used in the binary format.
11/// Identifiers are grouped by algorithm family for easy categorization.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13#[repr(u16)]
14pub enum Algorithm {
15    // Classical algorithms (0x0050-0x00FF)
16    /// Classical cryptography: X25519 + Ed25519 + AES-256-GCM
17    Classical = 0x0050,
18    /// Password-based classical encryption
19    PasswordClassical = 0x0051,
20
21    // Hybrid algorithms (0x0100-0x01FF)
22    /// Hybrid: ML-KEM-1024 + X25519 + ML-DSA-87 + Ed25519 + AES-256-GCM
23    Hybrid = 0x0100,
24
25    // Pure post-quantum algorithms (0x0200-0x02FF)
26    /// Post-quantum: ML-KEM-1024 + ML-DSA-87 + AES-256-GCM
27    PostQuantum = 0x0200,
28    /// Multi-algorithm runtime selection
29    MultiAlgorithm = 0x0201,
30    /// ML-KEM-1024 with AES-256-GCM
31    MlKem1024 = 0x0202,
32    /// Multi-KEM dual layer
33    MultiKem = 0x0203,
34    /// Multi-KEM triple layer
35    MultiKemTriple = 0x0204,
36    /// Quad-layer redundant security
37    QuadLayer = 0x0205,
38    /// Lattice-Code hybrid stack
39    LatticeCodeHybrid = 0x0206,
40    /// PQ3-Stack with forward secrecy
41    Pq3Stack = 0x0207,
42
43    // Max Secure series (0x0300-0x03FF)
44    /// Max Secure: PQ Lightweight
45    MaxSecureLightweight = 0x0300,
46    /// Max Secure: Pure PQ
47    MaxSecurePurePq = 0x0301,
48    /// Max Secure: Hybrid Transition
49    MaxSecureHybrid = 0x0302,
50    /// Max Secure: Stateless
51    MaxSecureStateless = 0x0303,
52    /// Max Secure: Crypto-Agile
53    MaxSecureCryptoAgile = 0x0304,
54    /// Max Secure: PQC + Zero-Knowledge
55    MaxSecurePqcZk = 0x0305,
56    /// Max Secure: Hybrid Transition
57    MaxSecureHybridTransition = 0x0306,
58
59    // FN-DSA series (Falcon-based signatures) (0x0400-0x04FF)
60    /// FN-DSA 512: Compact
61    FnDsa512Compact = 0x0400,
62    /// FN-DSA 1024: High-Security
63    FnDsa1024Security = 0x0401,
64    /// FN-DSA: Floating-Point Hardened
65    FnDsaFpHardened = 0x0402,
66    /// FN-DSA: Dual Signature
67    FnDsaDualSignature = 0x0403,
68    /// FN-DSA: Transition Stack
69    FnDsaTransition = 0x0404,
70    /// FN-DSA + Zero-Knowledge Stack
71    FnDsaZk = 0x0405,
72    /// FN-DSA + ZK Stack Enhanced
73    FnDsaZkStack = 0x0406,
74    /// FN-DSA: Transition Stack Enhanced
75    FnDsaTransitionStack = 0x0407,
76
77    // Experimental algorithms (0x0500-0x05FF)
78    /// Quantum-Inspired Lattice Fusion
79    QuantumLatticeFusion = 0x0500,
80    /// Post-ZK Homomorphic with LFHE 2023
81    PostZkHomomorphic = 0x0501,
82    /// Quantum-Resistant Consensus
83    QuantumResistantConsensus = 0x0502,
84    /// Entropy-Orchestrated PQ Stack
85    EntropyOrchestrated = 0x0503,
86    /// Lattice-Code Hybrid FN
87    LatticeCodeHybridFn = 0x0504,
88    /// AI-Synthesized Crypto-Agile
89    AiSynthesizedCryptoAgile = 0x0505,
90    /// Experimental Engine (generic)
91    Experimental = 0x0506,
92
93    // HQC Code-Based series (NIST 2025 Backup KEM) (0x0600-0x06FF)
94    /// HQC-128 (NIST Level 1, 128-bit security)
95    Hqc128 = 0x0600,
96    /// HQC-192 (NIST Level 3, 192-bit security)
97    Hqc192 = 0x0601,
98    /// HQC-256 (NIST Level 5, 256-bit security)
99    Hqc256 = 0x0602,
100}
101
102impl Algorithm {
103    /// Convert u16 identifier to Algorithm enum
104    ///
105    /// # Example
106    ///
107    /// ```
108    /// use pqc_binary_format::Algorithm;
109    ///
110    /// let algo = Algorithm::from_id(0x0100).unwrap();
111    /// assert_eq!(algo, Algorithm::Hybrid);
112    /// ```
113    #[must_use]
114    pub fn from_id(id: u16) -> Option<Self> {
115        match id {
116            0x0050 => Some(Self::Classical),
117            0x0051 => Some(Self::PasswordClassical),
118            0x0100 => Some(Self::Hybrid),
119            0x0200 => Some(Self::PostQuantum),
120            0x0201 => Some(Self::MultiAlgorithm),
121            0x0202 => Some(Self::MlKem1024),
122            0x0203 => Some(Self::MultiKem),
123            0x0204 => Some(Self::MultiKemTriple),
124            0x0205 => Some(Self::QuadLayer),
125            0x0206 => Some(Self::LatticeCodeHybrid),
126            0x0207 => Some(Self::Pq3Stack),
127            0x0300 => Some(Self::MaxSecureLightweight),
128            0x0301 => Some(Self::MaxSecurePurePq),
129            0x0302 => Some(Self::MaxSecureHybrid),
130            0x0303 => Some(Self::MaxSecureStateless),
131            0x0304 => Some(Self::MaxSecureCryptoAgile),
132            0x0305 => Some(Self::MaxSecurePqcZk),
133            0x0306 => Some(Self::MaxSecureHybridTransition),
134            0x0400 => Some(Self::FnDsa512Compact),
135            0x0401 => Some(Self::FnDsa1024Security),
136            0x0402 => Some(Self::FnDsaFpHardened),
137            0x0403 => Some(Self::FnDsaDualSignature),
138            0x0404 => Some(Self::FnDsaTransition),
139            0x0405 => Some(Self::FnDsaZk),
140            0x0406 => Some(Self::FnDsaZkStack),
141            0x0407 => Some(Self::FnDsaTransitionStack),
142            0x0500 => Some(Self::QuantumLatticeFusion),
143            0x0501 => Some(Self::PostZkHomomorphic),
144            0x0502 => Some(Self::QuantumResistantConsensus),
145            0x0503 => Some(Self::EntropyOrchestrated),
146            0x0504 => Some(Self::LatticeCodeHybridFn),
147            0x0505 => Some(Self::AiSynthesizedCryptoAgile),
148            0x0506 => Some(Self::Experimental),
149            0x0600 => Some(Self::Hqc128),
150            0x0601 => Some(Self::Hqc192),
151            0x0602 => Some(Self::Hqc256),
152            _ => None,
153        }
154    }
155
156    /// Get u16 identifier for this algorithm
157    ///
158    /// # Example
159    ///
160    /// ```
161    /// use pqc_binary_format::Algorithm;
162    ///
163    /// assert_eq!(Algorithm::Hybrid.as_id(), 0x0100);
164    /// ```
165    #[must_use]
166    pub const fn as_id(self) -> u16 {
167        self as u16
168    }
169
170    /// Get human-readable name for this algorithm
171    ///
172    /// # Example
173    ///
174    /// ```
175    /// use pqc_binary_format::Algorithm;
176    ///
177    /// assert_eq!(Algorithm::Hybrid.name(), "Hybrid");
178    /// ```
179    #[must_use]
180    pub const fn name(self) -> &'static str {
181        match self {
182            Self::Classical => "Classical",
183            Self::PasswordClassical => "Password Classical",
184            Self::Hybrid => "Hybrid",
185            Self::PostQuantum => "Post-Quantum",
186            Self::MultiAlgorithm => "Multi-Algorithm",
187            Self::MlKem1024 => "ML-KEM-1024",
188            Self::MultiKem => "Multi-KEM Dual Layer",
189            Self::MultiKemTriple => "Multi-KEM Triple Layer",
190            Self::QuadLayer => "Quad-Layer",
191            Self::LatticeCodeHybrid => "Lattice-Code Hybrid",
192            Self::Pq3Stack => "PQ3-Stack",
193            Self::MaxSecureLightweight => "Max Secure: PQ Lightweight",
194            Self::MaxSecurePurePq => "Max Secure: Pure PQ",
195            Self::MaxSecureHybrid => "Max Secure: Hybrid",
196            Self::MaxSecureStateless => "Max Secure: Stateless",
197            Self::MaxSecureCryptoAgile => "Max Secure: Crypto-Agile",
198            Self::MaxSecurePqcZk => "Max Secure: PQC + ZK",
199            Self::FnDsa512Compact => "FN-DSA 512: Compact",
200            Self::FnDsa1024Security => "FN-DSA 1024: High-Security",
201            Self::FnDsaFpHardened => "FN-DSA: Floating-Point Hardened",
202            Self::FnDsaDualSignature => "FN-DSA: Dual Signature",
203            Self::FnDsaTransition => "FN-DSA: Transition Stack",
204            Self::FnDsaZk => "FN-DSA + ZK Stack",
205            Self::FnDsaZkStack => "FN-DSA + ZK Stack Enhanced",
206            Self::FnDsaTransitionStack => "FN-DSA: Transition Stack Enhanced",
207            Self::MaxSecureHybridTransition => "Max Secure: Hybrid Transition",
208            Self::QuantumLatticeFusion => "Quantum-Inspired Lattice Fusion",
209            Self::PostZkHomomorphic => "Post-ZK Homomorphic",
210            Self::QuantumResistantConsensus => "Quantum-Resistant Consensus",
211            Self::EntropyOrchestrated => "Entropy-Orchestrated",
212            Self::LatticeCodeHybridFn => "Lattice-Code Hybrid FN",
213            Self::AiSynthesizedCryptoAgile => "AI-Synthesized Crypto-Agile",
214            Self::Experimental => "Experimental Engine",
215            Self::Hqc128 => "HQC-128",
216            Self::Hqc192 => "HQC-192",
217            Self::Hqc256 => "HQC-256",
218        }
219    }
220
221    /// Check if this algorithm is marked as experimental
222    ///
223    /// Experimental algorithms may have reduced security guarantees
224    /// and are intended for research purposes.
225    #[must_use]
226    pub const fn is_experimental(self) -> bool {
227        matches!(
228            self,
229            Self::QuantumLatticeFusion
230                | Self::PostZkHomomorphic
231                | Self::QuantumResistantConsensus
232                | Self::EntropyOrchestrated
233                | Self::LatticeCodeHybridFn
234                | Self::AiSynthesizedCryptoAgile
235                | Self::Experimental
236        )
237    }
238
239    /// Get all defined algorithm identifiers
240    ///
241    /// Useful for iteration and testing.
242    #[must_use]
243    pub fn all() -> Vec<Self> {
244        vec![
245            Self::Classical,
246            Self::PasswordClassical,
247            Self::Hybrid,
248            Self::PostQuantum,
249            Self::MultiAlgorithm,
250            Self::MlKem1024,
251            Self::MultiKem,
252            Self::MultiKemTriple,
253            Self::QuadLayer,
254            Self::LatticeCodeHybrid,
255            Self::Pq3Stack,
256            Self::MaxSecureLightweight,
257            Self::MaxSecurePurePq,
258            Self::MaxSecureHybrid,
259            Self::MaxSecureStateless,
260            Self::MaxSecureCryptoAgile,
261            Self::MaxSecurePqcZk,
262            Self::MaxSecureHybridTransition,
263            Self::FnDsa512Compact,
264            Self::FnDsa1024Security,
265            Self::FnDsaFpHardened,
266            Self::FnDsaDualSignature,
267            Self::FnDsaTransition,
268            Self::FnDsaZk,
269            Self::FnDsaZkStack,
270            Self::FnDsaTransitionStack,
271            Self::QuantumLatticeFusion,
272            Self::PostZkHomomorphic,
273            Self::QuantumResistantConsensus,
274            Self::EntropyOrchestrated,
275            Self::LatticeCodeHybridFn,
276            Self::AiSynthesizedCryptoAgile,
277            Self::Experimental,
278            Self::Hqc128,
279            Self::Hqc192,
280            Self::Hqc256,
281        ]
282    }
283}
284
285#[cfg(test)]
286mod tests {
287    use super::*;
288
289    #[test]
290    fn test_algorithm_roundtrip() {
291        for algo in Algorithm::all() {
292            let id = algo.as_id();
293            let recovered = Algorithm::from_id(id).unwrap();
294            assert_eq!(algo, recovered);
295        }
296    }
297
298    #[test]
299    fn test_invalid_algorithm_id() {
300        assert!(Algorithm::from_id(0xFFFF).is_none());
301    }
302
303    #[test]
304    fn test_experimental_detection() {
305        assert!(Algorithm::QuantumLatticeFusion.is_experimental());
306        assert!(!Algorithm::Hybrid.is_experimental());
307    }
308}