Skip to main content

affinidi_crypto/
key_type.rs

1//! Key type enumeration
2
3use std::fmt;
4
5use serde::{Deserialize, Serialize};
6use zeroize::Zeroize;
7
8use crate::CryptoError;
9
10/// Known cryptographic key types.
11///
12/// This enum is `#[non_exhaustive]`: new algorithms (hybrid schemes, future
13/// NIST standards, vendor-specific key types) will be added in minor
14/// releases without breaking match-all arms.
15///
16/// No `Default` impl is provided on purpose: a key without a known
17/// algorithm is a programming error in this crate, not a sensible
18/// default state. `KeyType::Unknown` exists for parsing paths that
19/// receive an unrecognised curve or codec identifier.
20#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Zeroize)]
21#[non_exhaustive]
22pub enum KeyType {
23    Ed25519,
24    X25519,
25    P256,
26    P384,
27    P521,
28    Secp256k1,
29    /// ML-DSA-44 (FIPS 204) — post-quantum signature scheme.
30    #[cfg(feature = "ml-dsa")]
31    MlDsa44,
32    /// ML-DSA-65 (FIPS 204) — post-quantum signature scheme.
33    #[cfg(feature = "ml-dsa")]
34    MlDsa65,
35    /// ML-DSA-87 (FIPS 204) — post-quantum signature scheme.
36    #[cfg(feature = "ml-dsa")]
37    MlDsa87,
38    /// SLH-DSA-SHA2-128s (FIPS 205) — stateless hash-based post-quantum signature.
39    #[cfg(feature = "slh-dsa")]
40    SlhDsaSha2_128s,
41    /// Unrecognised or unsupported key type. Produced by parsing paths
42    /// on unknown curve identifiers; should never be constructed directly.
43    Unknown,
44}
45
46impl TryFrom<&str> for KeyType {
47    type Error = CryptoError;
48
49    fn try_from(value: &str) -> Result<Self, Self::Error> {
50        match value {
51            "Ed25519" => Ok(KeyType::Ed25519),
52            "X25519" => Ok(KeyType::X25519),
53            "P-256" => Ok(KeyType::P256),
54            "P-384" => Ok(KeyType::P384),
55            "P-521" => Ok(KeyType::P521),
56            "secp256k1" => Ok(KeyType::Secp256k1),
57            #[cfg(feature = "ml-dsa")]
58            "ML-DSA-44" => Ok(KeyType::MlDsa44),
59            #[cfg(feature = "ml-dsa")]
60            "ML-DSA-65" => Ok(KeyType::MlDsa65),
61            #[cfg(feature = "ml-dsa")]
62            "ML-DSA-87" => Ok(KeyType::MlDsa87),
63            #[cfg(feature = "slh-dsa")]
64            "SLH-DSA-SHA2-128s" => Ok(KeyType::SlhDsaSha2_128s),
65            _ => Err(CryptoError::UnsupportedKeyType(value.to_string())),
66        }
67    }
68}
69
70impl fmt::Display for KeyType {
71    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72        match self {
73            KeyType::Ed25519 => write!(f, "Ed25519"),
74            KeyType::X25519 => write!(f, "X25519"),
75            KeyType::P256 => write!(f, "P-256"),
76            KeyType::P384 => write!(f, "P-384"),
77            KeyType::P521 => write!(f, "P-521"),
78            KeyType::Secp256k1 => write!(f, "secp256k1"),
79            #[cfg(feature = "ml-dsa")]
80            KeyType::MlDsa44 => write!(f, "ML-DSA-44"),
81            #[cfg(feature = "ml-dsa")]
82            KeyType::MlDsa65 => write!(f, "ML-DSA-65"),
83            #[cfg(feature = "ml-dsa")]
84            KeyType::MlDsa87 => write!(f, "ML-DSA-87"),
85            #[cfg(feature = "slh-dsa")]
86            KeyType::SlhDsaSha2_128s => write!(f, "SLH-DSA-SHA2-128s"),
87            KeyType::Unknown => write!(f, "Unknown"),
88        }
89    }
90}