bc_components/encapsulation/
encapsulation_scheme.rs

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