Skip to main content

hpke_dispatch/
kem.rs

1use std::str::FromStr;
2
3use num_enum::TryFromPrimitive;
4
5use crate::{IdLookupError, Keypair};
6
7/// An asymmetric key encapsulation mechanism.
8///
9/// Codepoints are defined in [RFC9180ยง7.2][1] and [draft-ietf-hpke-pq][2].
10///
11/// [1]: https://www.rfc-editor.org/rfc/rfc9180.html#section-7.2
12/// [2]: https://www.ietf.org/archive/id/draft-ietf-hpke-pq-05.html#table-1
13#[non_exhaustive]
14#[repr(u16)]
15#[derive(Copy, Clone, Debug, PartialEq, Eq, TryFromPrimitive)]
16#[cfg_attr(
17    feature = "serde",
18    derive(serde_crate::Serialize, serde_crate::Deserialize)
19)]
20#[cfg_attr(feature = "serde", serde(crate = "serde_crate"))]
21pub enum Kem {
22    /// DHKEM(P-256, HKDF-SHA256) [NISTCurves](https://doi.org/10.6028/nist.fips.186-4)
23    #[cfg(feature = "nistp")]
24    DhP256HkdfSha256 = 0x0010,
25
26    /// DHKEM(P-384, HKDF-SHA384) [NISTCurves](https://doi.org/10.6028/nist.fips.186-4)
27    #[cfg(feature = "nistp")]
28    DhP384HkdfSha384 = 0x0011,
29
30    /// DHKEM(P-521, HKDF-SHA512) [NISTCurves](https://doi.org/10.6028/nist.fips.186-4)
31    #[cfg(feature = "nistp")]
32    DhP521HkdfSha512 = 0x0012,
33
34    /// DHKEM(X25519, HKDF-SHA256) [RFC7748](https://www.rfc-editor.org/info/rfc7748)
35    #[cfg(feature = "x25519")]
36    X25519HkdfSha256 = 0x0020,
37
38    /// MLKEM-768 [FIPS 203](https://csrc.nist.gov/pubs/fips/203/final)
39    #[cfg(feature = "mlkem")]
40    MlKem768 = 0x0041,
41
42    /// MLKEM-1024 [FIPS 203](https://csrc.nist.gov/pubs/fips/203/final)
43    #[cfg(feature = "mlkem")]
44    MlKem1024 = 0x0042,
45
46    /// X-Wing (MLKEM768-X25519) <https://www.ietf.org/archive/id/draft-irtf-cfrg-concrete-hybrid-kems-04.html>
47    #[cfg(all(feature = "mlkem", feature = "x25519"))]
48    XWing = 0x647a,
49
50    /// MLKEM768-P256 <https://www.ietf.org/archive/id/draft-irtf-cfrg-concrete-hybrid-kems-04.html>
51    #[cfg(all(feature = "mlkem", feature = "nistp"))]
52    MlKem768P256 = 0x0050,
53
54    /// MLKEM1024-P384 <https://www.ietf.org/archive/id/draft-irtf-cfrg-concrete-hybrid-kems-04.html>
55    #[cfg(all(feature = "mlkem", feature = "nistp"))]
56    MlKem1024P384 = 0x0051,
57}
58
59impl FromStr for Kem {
60    type Err = IdLookupError;
61
62    fn from_str(s: &str) -> Result<Self, Self::Err> {
63        match &*s.to_lowercase().replace('-', "") {
64            #[cfg(feature = "nistp")]
65            "p256sha256" | "dhkemp256hkdfsha256" | "p256hkdfsha256" | "dhkem(p256, hkdfsha256)" => {
66                Ok(Self::DhP256HkdfSha256)
67            }
68            #[cfg(feature = "nistp")]
69            "p384sha384" | "dhkemp384hkdfsha384" | "p384hkdfsha384" | "dhkem(p384, hkdfsha384)" => {
70                Ok(Self::DhP384HkdfSha384)
71            }
72            #[cfg(feature = "nistp")]
73            "p521sha512" | "dhkemp521hkdfsha512" | "p521hkdfsha512" | "dhkem(p521, hkdfsha512)" => {
74                Ok(Self::DhP521HkdfSha512)
75            }
76            #[cfg(feature = "x25519")]
77            "x25519sha256"
78            | "dhkemx25519hkdfsha256"
79            | "x25519hkdfsha256"
80            | "dhkem(x25519, hkdfsha256)" => Ok(Self::X25519HkdfSha256),
81            #[cfg(feature = "mlkem")]
82            "mlkem768" => Ok(Self::MlKem768),
83            #[cfg(feature = "mlkem")]
84            "mlkem1024" => Ok(Self::MlKem1024),
85            #[cfg(all(feature = "mlkem", feature = "x25519"))]
86            "xwing" | "mlkem768x25119" | "mlkem768-x25119" => Ok(Self::XWing),
87            #[cfg(all(feature = "mlkem", feature = "nistp"))]
88            "mlkem768p256" | "mlkem768-p256" => Ok(Self::MlKem768P256),
89            #[cfg(all(feature = "mlkem", feature = "nistp"))]
90            "mlkem1024p384" | "mlkem1024-p384" => Ok(Self::MlKem1024P384),
91            _ => Err(IdLookupError("kem not recognized")),
92        }
93    }
94}
95
96impl Kem {
97    /// generate a [`Keypair`] for this [`Kem`].
98    #[must_use]
99    pub fn gen_keypair(self) -> Keypair {
100        crate::gen_keypair(self)
101    }
102}
103
104/// An iterable slice of [`Kem`] variants
105pub const KEM_ALL: &[Kem] = &[
106    #[cfg(feature = "nistp")]
107    Kem::DhP256HkdfSha256,
108    #[cfg(feature = "nistp")]
109    Kem::DhP384HkdfSha384,
110    #[cfg(feature = "nistp")]
111    Kem::DhP521HkdfSha512,
112    #[cfg(feature = "x25519")]
113    Kem::X25519HkdfSha256,
114    #[cfg(feature = "mlkem")]
115    Kem::MlKem768,
116    #[cfg(feature = "mlkem")]
117    Kem::MlKem1024,
118    #[cfg(all(feature = "mlkem", feature = "x25519"))]
119    Kem::XWing,
120    #[cfg(all(feature = "mlkem", feature = "nistp"))]
121    Kem::MlKem768P256,
122    #[cfg(all(feature = "mlkem", feature = "nistp"))]
123    Kem::MlKem1024P384,
124];