1use core::fmt::Display;
5use core::fmt::Formatter;
6use core::fmt::Result;
7use std::str::FromStr;
8
9#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize, serde::Serialize)]
13#[cfg_attr(not(feature = "custom_alg"), derive(Copy))]
14#[allow(non_camel_case_types)]
15pub enum JwsAlgorithm {
16 HS256,
18 HS384,
20 HS512,
22 RS256,
24 RS384,
26 RS512,
28 PS256,
30 PS384,
32 PS512,
34 ES256,
36 ES384,
38 ES512,
40 ES256K,
42 #[serde(rename = "none")]
44 NONE,
45 EdDSA,
47 #[serde(rename = "ML-DSA-44")]
50 ML_DSA_44,
51 #[serde(rename = "ML-DSA-65")]
54 ML_DSA_65,
55 #[serde(rename = "ML-DSA-87")]
58 ML_DSA_87,
59 #[serde(rename = "SLH-DSA-SHA2-128s")]
62 SLH_DSA_SHA2_128s,
63 #[serde(rename = "SLH-DSA-SHAKE-128s")]
66 SLH_DSA_SHAKE_128s,
67 #[serde(rename = "SLH-DSA-SHA2-128f")]
70 SLH_DSA_SHA2_128f,
71 #[serde(rename = "SLH-DSA-SHAKE-128f")]
73 SLH_DSA_SHAKE_128f,
74 #[serde(rename = "SLH-DSA-SHA2-192s")]
76 SLH_DSA_SHA2_192s,
77 #[serde(rename = "SLH-DSA-SHAKE-192s")]
79 SLH_DSA_SHAKE_192s,
80 #[serde(rename = "SLH-DSA-SHA2-192f")]
82 SLH_DSA_SHA2_192f,
83 #[serde(rename = "SLH-DSA-SHAKE-192f")]
85 SLH_DSA_SHAKE_192f,
86 #[serde(rename = "SLH-DSA-SHA2-256s")]
88 SLH_DSA_SHA2_256s,
89 #[serde(rename = "SLH-DSA-SHAKE-256s")]
91 SLH_DSA_SHAKE_256s,
92 #[serde(rename = "SLH-DSA-SHA2-256f")]
94 SLH_DSA_SHA2_256f,
95 #[serde(rename = "SLH-DSA-SHAKE-256f")]
97 SLH_DSA_SHAKE_256f,
98 FALCON512,
100 FALCON1024,
102 #[serde(rename = "id-MLDSA44-Ed25519")]
104 IdMldsa44Ed25519,
105 #[serde(rename = "id-MLDSA65-Ed25519")]
107 IdMldsa65Ed25519,
108 #[cfg(feature = "custom_alg")]
110 #[serde(untagged)]
111 Custom(String),
112}
113
114impl JwsAlgorithm {
115 #[cfg(not(feature = "custom_alg"))]
121 pub const ALL: &'static [Self] = &[
122 Self::HS256,
123 Self::HS384,
124 Self::HS512,
125 Self::RS256,
126 Self::RS384,
127 Self::RS512,
128 Self::PS256,
129 Self::PS384,
130 Self::PS512,
131 Self::ES256,
132 Self::ES384,
133 Self::ES512,
134 Self::ES256K,
135 Self::NONE,
136 Self::EdDSA,
137 Self::ML_DSA_44,
138 Self::ML_DSA_65,
139 Self::ML_DSA_87,
140 Self::SLH_DSA_SHA2_128s,
141 Self::SLH_DSA_SHAKE_128s,
142 Self::SLH_DSA_SHA2_128f,
143 Self::SLH_DSA_SHAKE_128f,
144 Self::SLH_DSA_SHA2_192s,
145 Self::SLH_DSA_SHAKE_192s,
146 Self::SLH_DSA_SHA2_192f,
147 Self::SLH_DSA_SHAKE_192f,
148 Self::SLH_DSA_SHA2_256s,
149 Self::SLH_DSA_SHAKE_256s,
150 Self::SLH_DSA_SHA2_256f,
151 Self::SLH_DSA_SHAKE_256f,
152 Self::FALCON512,
153 Self::FALCON1024,
154 Self::IdMldsa44Ed25519,
155 Self::IdMldsa65Ed25519,
156 ];
157
158 #[cfg(not(feature = "custom_alg"))]
160 pub const fn name(self) -> &'static str {
161 match self {
162 Self::HS256 => "HS256",
163 Self::HS384 => "HS384",
164 Self::HS512 => "HS512",
165 Self::RS256 => "RS256",
166 Self::RS384 => "RS384",
167 Self::RS512 => "RS512",
168 Self::PS256 => "PS256",
169 Self::PS384 => "PS384",
170 Self::PS512 => "PS512",
171 Self::ES256 => "ES256",
172 Self::ES384 => "ES384",
173 Self::ES512 => "ES512",
174 Self::ES256K => "ES256K",
175 Self::NONE => "none",
176 Self::EdDSA => "EdDSA",
177 Self::ML_DSA_44 => "ML-DSA-44",
178 Self::ML_DSA_65 => "ML-DSA-65",
179 Self::ML_DSA_87 => "ML-DSA-87",
180 Self::SLH_DSA_SHA2_128s => "SLH-DSA-SHA2-128s",
181 Self::SLH_DSA_SHAKE_128s => "SLH-DSA-SHAKE-128s",
182 Self::SLH_DSA_SHA2_128f => "SLH-DSA-SHA2-128f",
183 Self::SLH_DSA_SHAKE_128f => "SLH-DSA-SHAKE-128f",
184 Self::SLH_DSA_SHA2_192s => "SLH-DSA-SHA2-192s",
185 Self::SLH_DSA_SHAKE_192s => "SLH-DSA-SHAKE-192s",
186 Self::SLH_DSA_SHA2_192f => "SLH-DSA-SHA2-192f",
187 Self::SLH_DSA_SHAKE_192f => "SLH-DSA-SHAKE-192f",
188 Self::SLH_DSA_SHA2_256s => "SLH-DSA-SHA2-256s",
189 Self::SLH_DSA_SHAKE_256s => "SLH-DSA-SHAKE-256s",
190 Self::SLH_DSA_SHA2_256f => "SLH-DSA-SHA2-256f",
191 Self::SLH_DSA_SHAKE_256f => "SLH-DSA-SHAKE-256f",
192 Self::FALCON512 => "FALCON512",
193 Self::FALCON1024 => "FALCON1024",
194 Self::IdMldsa44Ed25519 => "id-MLDSA44-Ed25519",
195 Self::IdMldsa65Ed25519 => "id-MLDSA65-Ed25519",
196 }
197 }
198
199 #[cfg(feature = "custom_alg")]
201 pub fn name(&self) -> String {
202 match self {
203 Self::HS256 => "HS256".to_string(),
204 Self::HS384 => "HS384".to_string(),
205 Self::HS512 => "HS512".to_string(),
206 Self::RS256 => "RS256".to_string(),
207 Self::RS384 => "RS384".to_string(),
208 Self::RS512 => "RS512".to_string(),
209 Self::PS256 => "PS256".to_string(),
210 Self::PS384 => "PS384".to_string(),
211 Self::PS512 => "PS512".to_string(),
212 Self::ES256 => "ES256".to_string(),
213 Self::ES384 => "ES384".to_string(),
214 Self::ES512 => "ES512".to_string(),
215 Self::ES256K => "ES256K".to_string(),
216 Self::NONE => "none".to_string(),
217 Self::EdDSA => "EdDSA".to_string(),
218 Self::ML_DSA_44 => "ML-DSA-44".to_string(),
219 Self::ML_DSA_65 => "ML-DSA-65".to_string(),
220 Self::ML_DSA_87 => "ML-DSA-87".to_string(),
221 Self::SLH_DSA_SHA2_128s => "SLH-DSA-SHA2-128s".to_string(),
222 Self::SLH_DSA_SHAKE_128s => "SLH-DSA-SHAKE-128s".to_string(),
223 Self::SLH_DSA_SHA2_128f => "SLH-DSA-SHA2-128f".to_string(),
224 Self::SLH_DSA_SHAKE_128f => "SLH-DSA-SHAKE-128f".to_string(),
225 Self::SLH_DSA_SHA2_192s => "SLH-DSA-SHA2-192s".to_string(),
226 Self::SLH_DSA_SHAKE_192s => "SLH-DSA-SHAKE-192s".to_string(),
227 Self::SLH_DSA_SHA2_192f => "SLH-DSA-SHA2-192f".to_string(),
228 Self::SLH_DSA_SHAKE_192f => "SLH-DSA-SHAKE-192f".to_string(),
229 Self::SLH_DSA_SHA2_256s => "SLH-DSA-SHA2-256s".to_string(),
230 Self::SLH_DSA_SHAKE_256s => "SLH-DSA-SHAKE-256s".to_string(),
231 Self::SLH_DSA_SHA2_256f => "SLH-DSA-SHA2-256f".to_string(),
232 Self::SLH_DSA_SHAKE_256f => "SLH-DSA-SHAKE-256f".to_string(),
233 Self::FALCON512 => "FALCON512".to_string(),
234 Self::FALCON1024 => "FALCON1024".to_string(),
235 Self::IdMldsa44Ed25519 => "id-MLDSA44-Ed25519".to_string(),
236 Self::IdMldsa65Ed25519 => "id-MLDSA65-Ed25519".to_string(),
237 Self::Custom(name) => name.clone(),
238 }
239 }
240}
241
242impl FromStr for JwsAlgorithm {
243 type Err = crate::error::Error;
244
245 fn from_str(string: &str) -> std::result::Result<Self, Self::Err> {
246 match string {
247 "HS256" => Ok(Self::HS256),
248 "HS384" => Ok(Self::HS384),
249 "HS512" => Ok(Self::HS512),
250 "RS256" => Ok(Self::RS256),
251 "RS384" => Ok(Self::RS384),
252 "RS512" => Ok(Self::RS512),
253 "PS256" => Ok(Self::PS256),
254 "PS384" => Ok(Self::PS384),
255 "PS512" => Ok(Self::PS512),
256 "ES256" => Ok(Self::ES256),
257 "ES384" => Ok(Self::ES384),
258 "ES512" => Ok(Self::ES512),
259 "ES256K" => Ok(Self::ES256K),
260 "none" => Ok(Self::NONE),
261 "EdDSA" => Ok(Self::EdDSA),
262 "ML-DSA-44" => Ok(Self::ML_DSA_44),
263 "ML-DSA-65" => Ok(Self::ML_DSA_65),
264 "ML-DSA-87" => Ok(Self::ML_DSA_87),
265 "SLH-DSA-SHA2-128s" => Ok(Self::SLH_DSA_SHA2_128s),
266 "SLH-DSA-SHAKE-128s" => Ok(Self::SLH_DSA_SHAKE_128s),
267 "SLH-DSA-SHA2-128f" => Ok(Self::SLH_DSA_SHA2_128f),
268 "SLH-DSA-SHAKE-128f" => Ok(Self::SLH_DSA_SHAKE_128f),
269 "SLH-DSA-SHA2-192s" => Ok(Self::SLH_DSA_SHA2_192s),
270 "SLH-DSA-SHAKE-192s" => Ok(Self::SLH_DSA_SHAKE_192s),
271 "SLH-DSA-SHA2-192f" => Ok(Self::SLH_DSA_SHA2_192f),
272 "SLH-DSA-SHAKE-192f" => Ok(Self::SLH_DSA_SHAKE_192f),
273 "SLH-DSA-SHA2-256s" => Ok(Self::SLH_DSA_SHA2_256s),
274 "SLH-DSA-SHAKE-256s" => Ok(Self::SLH_DSA_SHAKE_256s),
275 "SLH-DSA-SHA2-256f" => Ok(Self::SLH_DSA_SHA2_256f),
276 "SLH-DSA-SHAKE-256f" => Ok(Self::SLH_DSA_SHAKE_256f),
277 "FALCON512" => Ok(Self::FALCON512),
278 "FALCON1024" => Ok(Self::FALCON1024),
279 "id-MLDSA44-Ed25519" => Ok(Self::IdMldsa44Ed25519),
280 "id-MLDSA65-Ed25519" => Ok(Self::IdMldsa65Ed25519),
281 #[cfg(feature = "custom_alg")]
282 value => Ok(Self::Custom(value.to_string())),
283 #[cfg(not(feature = "custom_alg"))]
284 _ => Err(crate::error::Error::JwsAlgorithmParsingError),
285 }
286 }
287}
288
289#[cfg(not(feature = "custom_alg"))]
290impl Display for JwsAlgorithm {
291 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
292 f.write_str(self.name())
293 }
294}
295
296#[cfg(feature = "custom_alg")]
297impl Display for JwsAlgorithm {
298 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
299 f.write_str(&(*self).name())
300 }
301}