Skip to main content

sequoia_openpgp/crypto/
key.rs

1//! Common secret key related operations.
2
3use std::time::SystemTime;
4
5use crate::{
6    Result,
7    crypto::{
8        PublicKeyAlgorithm,
9        backend::{Backend, interface::Asymmetric},
10        mpi,
11    },
12    packet::key::{self, Key4, Key6, SecretParts},
13    types::Curve,
14};
15
16impl<R> Key6<SecretParts, R>
17    where R: key::KeyRole,
18{
19    /// Generates a new X25519 key.
20    pub fn generate_x25519() -> Result<Self> {
21        Key4::generate_x25519().map(Key6::from_common)
22    }
23
24    /// Generates a new X448 key.
25    pub fn generate_x448() -> Result<Self> {
26        Key4::generate_x448().map(Key6::from_common)
27    }
28
29    /// Generates a new Ed25519 key.
30    pub fn generate_ed25519() -> Result<Self> {
31        Key4::generate_ed25519().map(Key6::from_common)
32    }
33
34    /// Generates a new Ed448 key.
35    pub fn generate_ed448() -> Result<Self> {
36        Key4::generate_ed448().map(Key6::from_common)
37    }
38
39    /// Generates a new MLDSA65+Ed25519 key.
40    pub fn generate_mldsa65_ed25519() -> Result<Self> {
41        let (eddsa_secret, eddsa_public) = Backend::ed25519_generate_key()?;
42        let (mldsa_secret, mldsa_public) = Backend::mldsa65_generate_key()?;
43
44        Self::with_secret(
45            crate::now(),
46            PublicKeyAlgorithm::MLDSA65_Ed25519,
47            mpi::PublicKey::MLDSA65_Ed25519 {
48                eddsa: Box::new(eddsa_public),
49                mldsa: mldsa_public,
50            },
51            mpi::SecretKeyMaterial::MLDSA65_Ed25519 {
52                eddsa: eddsa_secret,
53                mldsa: mldsa_secret,
54            }.into())
55    }
56
57    /// Generates a new MLDSA87+Ed448 key.
58    pub fn generate_mldsa87_ed448() -> Result<Self> {
59        let (eddsa_secret, eddsa_public) = Backend::ed448_generate_key()?;
60        let (mldsa_secret, mldsa_public) = Backend::mldsa87_generate_key()?;
61
62        Self::with_secret(
63            crate::now(),
64            PublicKeyAlgorithm::MLDSA87_Ed448,
65            mpi::PublicKey::MLDSA87_Ed448 {
66                eddsa: Box::new(eddsa_public),
67                mldsa: mldsa_public,
68            },
69            mpi::SecretKeyMaterial::MLDSA87_Ed448 {
70                eddsa: eddsa_secret,
71                mldsa: mldsa_secret,
72            }.into())
73    }
74
75    /// Generates a new SLHDSA128s key.
76    pub fn generate_slhdsa128s() -> Result<Self> {
77        let (secret, public) = Backend::slhdsa128s_generate_key()?;
78
79        Self::with_secret(
80            crate::now(),
81            PublicKeyAlgorithm::SLHDSA128s,
82            mpi::PublicKey::SLHDSA128s { public },
83            mpi::SecretKeyMaterial::SLHDSA128s { secret }.into())
84    }
85
86    /// Generates a new SLHDSA128f key.
87    pub fn generate_slhdsa128f() -> Result<Self> {
88        let (secret, public) = Backend::slhdsa128f_generate_key()?;
89
90        Self::with_secret(
91            crate::now(),
92            PublicKeyAlgorithm::SLHDSA128f,
93            mpi::PublicKey::SLHDSA128f { public },
94            mpi::SecretKeyMaterial::SLHDSA128f { secret }.into())
95    }
96
97    /// Generates a new SLHDSA256s key.
98    pub fn generate_slhdsa256s() -> Result<Self> {
99        let (secret, public) = Backend::slhdsa256s_generate_key()?;
100
101        Self::with_secret(
102            crate::now(),
103            PublicKeyAlgorithm::SLHDSA256s,
104            mpi::PublicKey::SLHDSA256s { public },
105            mpi::SecretKeyMaterial::SLHDSA256s { secret }.into())
106    }
107
108    /// Generates a new MLKEM768+X25519 key.
109    pub fn generate_mlkem768_x25519() -> Result<Self> {
110        Key4::generate_mlkem768_x25519()
111            .map(Key6::from_common)
112    }
113
114    /// Generates a new MLKEM1024+X448 key.
115    pub fn generate_mlkem1024_x448() -> Result<Self> {
116        let (ecdh_secret, ecdh_public) = Backend::x448_generate_key()?;
117        let (mlkem_secret, mlkem_public) = Backend::mlkem1024_generate_key()?;
118
119        Self::with_secret(
120            crate::now(),
121            PublicKeyAlgorithm::MLKEM1024_X448,
122            mpi::PublicKey::MLKEM1024_X448 {
123                ecdh: Box::new(ecdh_public),
124                mlkem: mlkem_public,
125            },
126            mpi::SecretKeyMaterial::MLKEM1024_X448 {
127                ecdh: ecdh_secret,
128                mlkem: mlkem_secret,
129            }.into())
130    }
131
132    /// Generates a new RSA key with a public modulos of size `bits`.
133    pub fn generate_rsa(bits: usize) -> Result<Self> {
134        Key4::generate_rsa(bits)
135            .map(Key6::from_common)
136    }
137
138    /// Creates a new OpenPGP public key packet for an existing RSA key.
139    ///
140    /// The RSA key will use public exponent `e` and modulo `n`. The key will
141    /// have its creation date set to `ctime` or the current time if `None`
142    /// is given.
143    #[allow(clippy::many_single_char_names)]
144    pub fn import_secret_rsa<T>(d: &[u8], p: &[u8], q: &[u8], ctime: T)
145        -> Result<Self> where T: Into<Option<SystemTime>>
146    {
147        Key4::import_secret_rsa(d, p, q, ctime)
148            .map(Key6::from_common)
149    }
150
151    /// Generates a new ECC key over `curve`.
152    ///
153    /// If `for_signing` is false a ECDH key, if it's true either a
154    /// EdDSA or ECDSA key is generated.  Giving `for_signing == true` and
155    /// `curve == Cv25519` will produce an error. Likewise
156    /// `for_signing == false` and `curve == Ed25519` will produce an error.
157    pub fn generate_ecc(for_signing: bool, curve: Curve) -> Result<Self> {
158        match (for_signing, curve) {
159            (true, Curve::Ed25519) => Self::generate_ed25519(),
160            (false, Curve::Cv25519) => Self::generate_x25519(),
161            (s, c) => Key4::generate_ecc(s, c).map(Key6::from_common),
162        }
163    }
164}