bc_components/encapsulation/
encapsulation_scheme.rs

1use bc_rand::RandomNumberGenerator;
2
3#[cfg(feature = "pqcrypto")]
4use crate::MLKEM;
5#[cfg_attr(not(feature = "pqcrypto"), allow(unused_imports))]
6use crate::{
7    EncapsulationPrivateKey, EncapsulationPublicKey, Error, Result,
8    X25519PrivateKey,
9};
10
11/// Supported key encapsulation mechanisms.
12///
13/// Key Encapsulation Mechanisms (KEMs) are cryptographic algorithms designed to
14/// securely establish a shared secret between parties in public-key
15/// cryptography. They are often used to encapsulate (wrap) symmetric keys for
16/// secure key exchange.
17///
18/// This enum represents the various KEM schemes supported in this crate:
19/// - X25519: A Diffie-Hellman key exchange mechanism using the Curve25519
20///   elliptic curve
21/// - ML-KEM (Module Lattice-based Key Encapsulation Mechanism): Post-quantum
22///   secure KEM at different security levels (512, 768, 1024)
23#[derive(Debug, Copy, Clone, PartialEq, Default)]
24pub enum EncapsulationScheme {
25    /// X25519 key agreement (default)
26    #[default]
27    X25519,
28    /// ML-KEM512 post-quantum key encapsulation (NIST level 1)
29    #[cfg(feature = "pqcrypto")]
30    MLKEM512,
31    /// ML-KEM768 post-quantum key encapsulation (NIST level 3)
32    #[cfg(feature = "pqcrypto")]
33    MLKEM768,
34    /// ML-KEM1024 post-quantum key encapsulation (NIST level 5)
35    #[cfg(feature = "pqcrypto")]
36    MLKEM1024,
37}
38
39impl EncapsulationScheme {
40    /// Generates a new random key pair for the specified encapsulation scheme.
41    ///
42    /// # Returns
43    ///
44    /// A tuple containing the private key and public key for the selected
45    /// encapsulation scheme.
46    ///
47    /// # Example
48    ///
49    /// ```
50    /// use bc_components::EncapsulationScheme;
51    ///
52    /// // Generate a key pair using X25519 (default)
53    /// let (private_key, public_key) = EncapsulationScheme::default().keypair();
54    /// ```
55    ///
56    /// ```ignore
57    /// # use bc_components::EncapsulationScheme;
58    /// // Generate a key pair using ML-KEM768
59    /// let (private_key, public_key) = EncapsulationScheme::MLKEM768.keypair();
60    /// ```
61    pub fn keypair(self) -> (EncapsulationPrivateKey, EncapsulationPublicKey) {
62        match self {
63            EncapsulationScheme::X25519 => {
64                let (private_key, public_key) = X25519PrivateKey::keypair();
65                (
66                    EncapsulationPrivateKey::X25519(private_key),
67                    EncapsulationPublicKey::X25519(public_key),
68                )
69            }
70            #[cfg(feature = "pqcrypto")]
71            EncapsulationScheme::MLKEM512 => {
72                let (private_key, public_key) = MLKEM::MLKEM512.keypair();
73                (
74                    EncapsulationPrivateKey::MLKEM(private_key),
75                    EncapsulationPublicKey::MLKEM(public_key),
76                )
77            }
78            #[cfg(feature = "pqcrypto")]
79            EncapsulationScheme::MLKEM768 => {
80                let (private_key, public_key) = MLKEM::MLKEM768.keypair();
81                (
82                    EncapsulationPrivateKey::MLKEM(private_key),
83                    EncapsulationPublicKey::MLKEM(public_key),
84                )
85            }
86            #[cfg(feature = "pqcrypto")]
87            EncapsulationScheme::MLKEM1024 => {
88                let (private_key, public_key) = MLKEM::MLKEM1024.keypair();
89                (
90                    EncapsulationPrivateKey::MLKEM(private_key),
91                    EncapsulationPublicKey::MLKEM(public_key),
92                )
93            }
94        }
95    }
96
97    /// Generates a deterministic key pair using the provided random number
98    /// generator.
99    ///
100    /// # Parameters
101    ///
102    /// * `rng` - A mutable reference to a random number generator
103    ///
104    /// # Returns
105    ///
106    /// A Result containing a tuple with the private key and public key if
107    /// successful, or an error if deterministic key generation is not
108    /// supported for the selected scheme.
109    ///
110    /// # Errors
111    ///
112    /// Returns an error if deterministic key generation is not supported for
113    /// the selected encapsulation scheme (currently only X25519 supports
114    /// this).
115    ///
116    /// # Example
117    ///
118    /// ```
119    /// use bc_components::EncapsulationScheme;
120    /// use bc_rand::SecureRandomNumberGenerator;
121    ///
122    /// let mut rng = SecureRandomNumberGenerator;
123    /// let result = EncapsulationScheme::X25519.keypair_using(&mut rng);
124    /// assert!(result.is_ok());
125    /// ```
126    ///
127    /// ```ignore
128    /// # use bc_components::EncapsulationScheme;
129    /// # use bc_rand::SecureRandomNumberGenerator;
130    /// # let mut rng = SecureRandomNumberGenerator;
131    /// // ML-KEM schemes don't support deterministic key generation
132    /// let result = EncapsulationScheme::MLKEM512.keypair_using(&mut rng);
133    /// assert!(result.is_err());
134    /// ```
135    pub fn keypair_using(
136        self,
137        rng: &mut impl RandomNumberGenerator,
138    ) -> Result<(EncapsulationPrivateKey, EncapsulationPublicKey)> {
139        match self {
140            EncapsulationScheme::X25519 => {
141                let (private_key, public_key) =
142                    X25519PrivateKey::keypair_using(rng);
143                Ok((
144                    EncapsulationPrivateKey::X25519(private_key),
145                    EncapsulationPublicKey::X25519(public_key),
146                ))
147            }
148            #[cfg(feature = "pqcrypto")]
149            _ => Err(Error::general(
150                "Deterministic keypair generation not supported for this encapsulation scheme",
151            )),
152        }
153    }
154}