quantcrypt/dsa/api/
algorithm.rs

1use crate::dsa::common::{config::oids::Oid, dsa_type::DsaType};
2
3use strum::IntoEnumIterator;
4use strum_macros::{Display, EnumIter};
5
6#[derive(Clone, Debug, PartialEq, EnumIter, Display, Copy)]
7/// The permissible algorithms for the `AlgorithmIdentifier` type.
8pub enum DsaAlgorithm {
9    // ML DSA
10    MlDsa44,
11    MlDsa65,
12    MlDsa87,
13
14    // Composite DSAs
15    MlDsa44Rsa2048PssSha256,
16    MlDsa44Rsa2048Pkcs15Sha256,
17    MlDsa44Ed25519SHA512,
18    MlDsa44EcdsaP256SHA256,
19    MlDsa44EcdsaBrainpoolP256r1SHA256,
20    MlDsa65Rsa3072PssSHA512,
21    MlDsa65Rsa3072Pkcs15SHA512,
22    MlDsa65EcdsaP256SHA512,
23    MlDsa65EcdsaBrainpoolP256r1SHA512,
24    MlDsa65Ed25519SHA512,
25    MlDsa87EcdsaP384SHA512,
26    MlDsa87EcdsaBrainpoolP384r1SHA512,
27    MlDsa87Ed448SHA512,
28
29    #[cfg(not(feature = "ipd"))]
30    SlhDsaSha2_128s,
31    #[cfg(not(feature = "ipd"))]
32    SlhDsaSha2_128f,
33    #[cfg(not(feature = "ipd"))]
34    SlhDsaSha2_192s,
35    #[cfg(not(feature = "ipd"))]
36    SlhDsaSha2_192f,
37    #[cfg(not(feature = "ipd"))]
38    SlhDsaSha2_256s,
39    #[cfg(not(feature = "ipd"))]
40    SlhDsaSha2_256f,
41    #[cfg(not(feature = "ipd"))]
42    SlhDsaShake128s,
43    #[cfg(not(feature = "ipd"))]
44    SlhDsaShake128f,
45    #[cfg(not(feature = "ipd"))]
46    SlhDsaShake192s,
47    #[cfg(not(feature = "ipd"))]
48    SlhDsaShake192f,
49    #[cfg(not(feature = "ipd"))]
50    SlhDsaShake256s,
51    #[cfg(not(feature = "ipd"))]
52    SlhDsaShake256f,
53}
54
55impl DsaAlgorithm {
56    /// Get all DSA algorithms
57    pub(crate) fn all() -> Vec<DsaAlgorithm> {
58        DsaAlgorithm::iter().collect()
59    }
60
61    /// Get the corresponding `DsaType` for the algorithm
62    pub(crate) fn get_dsa_type(&self) -> DsaType {
63        match self {
64            // Pure DSAs
65            DsaAlgorithm::MlDsa44 => DsaType::MlDsa44,
66            DsaAlgorithm::MlDsa65 => DsaType::MlDsa65,
67            DsaAlgorithm::MlDsa87 => DsaType::MlDsa87,
68
69            // Composite DSAs
70            DsaAlgorithm::MlDsa44Rsa2048PssSha256 => DsaType::MlDsa44Rsa2048PssSha256,
71            DsaAlgorithm::MlDsa44Rsa2048Pkcs15Sha256 => DsaType::MlDsa44Rsa2048Pkcs15Sha256,
72            DsaAlgorithm::MlDsa44Ed25519SHA512 => DsaType::MlDsa44Ed25519SHA512,
73            DsaAlgorithm::MlDsa44EcdsaP256SHA256 => DsaType::MlDsa44EcdsaP256SHA256,
74            DsaAlgorithm::MlDsa44EcdsaBrainpoolP256r1SHA256 => {
75                DsaType::MlDsa44EcdsaBrainpoolP256r1SHA256
76            }
77            DsaAlgorithm::MlDsa65Rsa3072PssSHA512 => DsaType::MlDsa65Rsa3072PssSHA512,
78            DsaAlgorithm::MlDsa65Rsa3072Pkcs15SHA512 => DsaType::MlDsa65Rsa3072Pkcs15SHA512,
79            DsaAlgorithm::MlDsa65EcdsaP256SHA512 => DsaType::MlDsa65EcdsaP256SHA512,
80            DsaAlgorithm::MlDsa65EcdsaBrainpoolP256r1SHA512 => {
81                DsaType::MlDsa65EcdsaBrainpoolP256r1SHA512
82            }
83            DsaAlgorithm::MlDsa65Ed25519SHA512 => DsaType::MlDsa65Ed25519SHA512,
84            DsaAlgorithm::MlDsa87EcdsaP384SHA512 => DsaType::MlDsa87EcdsaP384SHA512,
85            DsaAlgorithm::MlDsa87EcdsaBrainpoolP384r1SHA512 => {
86                DsaType::MlDsa87EcdsaBrainpoolP384r1SHA512
87            }
88            DsaAlgorithm::MlDsa87Ed448SHA512 => DsaType::MlDsa87Ed448SHA512,
89
90            #[cfg(not(feature = "ipd"))]
91            DsaAlgorithm::SlhDsaSha2_128s => DsaType::SlhDsaSha2_128s,
92            #[cfg(not(feature = "ipd"))]
93            DsaAlgorithm::SlhDsaSha2_128f => DsaType::SlhDsaSha2_128f,
94            #[cfg(not(feature = "ipd"))]
95            DsaAlgorithm::SlhDsaSha2_192s => DsaType::SlhDsaSha2_192s,
96            #[cfg(not(feature = "ipd"))]
97            DsaAlgorithm::SlhDsaSha2_192f => DsaType::SlhDsaSha2_192f,
98            #[cfg(not(feature = "ipd"))]
99            DsaAlgorithm::SlhDsaSha2_256s => DsaType::SlhDsaSha2_256s,
100            #[cfg(not(feature = "ipd"))]
101            DsaAlgorithm::SlhDsaSha2_256f => DsaType::SlhDsaSha2_256f,
102            #[cfg(not(feature = "ipd"))]
103            DsaAlgorithm::SlhDsaShake128s => DsaType::SlhDsaShake128s,
104            #[cfg(not(feature = "ipd"))]
105            DsaAlgorithm::SlhDsaShake128f => DsaType::SlhDsaShake128f,
106            #[cfg(not(feature = "ipd"))]
107            DsaAlgorithm::SlhDsaShake192s => DsaType::SlhDsaShake192s,
108            #[cfg(not(feature = "ipd"))]
109            DsaAlgorithm::SlhDsaShake192f => DsaType::SlhDsaShake192f,
110            #[cfg(not(feature = "ipd"))]
111            DsaAlgorithm::SlhDsaShake256s => DsaType::SlhDsaShake256s,
112            #[cfg(not(feature = "ipd"))]
113            DsaAlgorithm::SlhDsaShake256f => DsaType::SlhDsaShake256f,
114        }
115    }
116
117    /// Check if the algorithm is a composite or pure algorithm
118    ///
119    /// # Returns
120    ///
121    /// True if the algorithm is a composite algorithm, false otherwise
122    pub fn is_composite(&self) -> bool {
123        !matches!(
124            self,
125            DsaAlgorithm::MlDsa44 | DsaAlgorithm::MlDsa65 | DsaAlgorithm::MlDsa87
126        )
127    }
128
129    /// Get the OID for the algorithm
130    ///
131    /// # Returns
132    ///
133    /// The OID for the algorithm
134    pub fn get_oid(&self) -> String {
135        self.get_dsa_type().get_oid()
136    }
137
138    /// Get the DSA algorithm from an OID
139    ///
140    /// # Arguments
141    ///
142    /// * `oid` - The OID of the DSA algorithm
143    ///
144    /// # Returns
145    ///
146    /// The DSA algorithm or None if the OID is not found
147    pub fn from_oid(oid: &str) -> Option<DsaAlgorithm> {
148        DsaAlgorithm::all()
149            .iter()
150            .find(|x| x.get_oid() == oid)
151            .cloned()
152    }
153}