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}