bc_components/encapsulation/
encapsulation_scheme.rs

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