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}