bc_components/encrypter.rs
1use crate::{
2 EncapsulationCiphertext, EncapsulationPrivateKey, EncapsulationPublicKey,
3 Result, SymmetricKey,
4};
5
6/// A trait for types that can encapsulate shared secrets for public key
7/// encryption.
8///
9/// The `Encrypter` trait defines an interface for encapsulating a shared secret
10/// using a public key. This is a key part of hybrid encryption schemes, where a
11/// shared symmetric key is encapsulated with a public key, and the recipient
12/// uses their private key to recover the symmetric key.
13///
14/// Types implementing this trait provide the ability to:
15/// 1. Access their encapsulation public key
16/// 2. Generate and encapsulate new shared secrets
17///
18/// This trait is typically implemented by:
19/// - Encapsulation public keys
20/// - Higher-level types that contain or can generate encapsulation public keys
21pub trait Encrypter {
22 /// Returns the encapsulation public key for this encrypter.
23 ///
24 /// # Returns
25 ///
26 /// The encapsulation public key that should be used for encapsulation.
27 fn encapsulation_public_key(&self) -> EncapsulationPublicKey;
28
29 /// Encapsulates a new shared secret for the recipient.
30 ///
31 /// This method generates a new shared secret and encapsulates it using
32 /// the encapsulation public key from this encrypter.
33 ///
34 /// # Returns
35 ///
36 /// A tuple containing:
37 /// - The generated shared secret as a `SymmetricKey`
38 /// - The encapsulation ciphertext that can be sent to the recipient
39 ///
40 /// # Example
41 ///
42 /// ```
43 /// use bc_components::{EncapsulationScheme, Encrypter};
44 ///
45 /// // Generate a recipient keypair
46 /// let (recipient_private_key, recipient_public_key) =
47 /// EncapsulationScheme::default().keypair();
48 ///
49 /// // Encapsulate a new shared secret
50 /// let (shared_secret, ciphertext) =
51 /// recipient_public_key.encapsulate_new_shared_secret();
52 /// ```
53 fn encapsulate_new_shared_secret(
54 &self,
55 ) -> (SymmetricKey, EncapsulationCiphertext) {
56 self.encapsulation_public_key()
57 .encapsulate_new_shared_secret()
58 }
59}
60
61/// A trait for types that can decapsulate shared secrets for public key
62/// decryption.
63///
64/// The `Decrypter` trait defines an interface for decapsulating (recovering) a
65/// shared secret using a private key. This is the counterpart to the
66/// `Encrypter` trait and is used by the recipient of encapsulated messages.
67///
68/// Types implementing this trait provide the ability to:
69/// 1. Access their encapsulation private key
70/// 2. Decapsulate shared secrets from ciphertexts
71///
72/// This trait is typically implemented by:
73/// - Encapsulation private keys
74/// - Higher-level types that contain or can access encapsulation private keys
75pub trait Decrypter {
76 /// Returns the encapsulation private key for this decrypter.
77 ///
78 /// # Returns
79 ///
80 /// The encapsulation private key that should be used for decapsulation.
81 fn encapsulation_private_key(&self) -> EncapsulationPrivateKey;
82
83 /// Decapsulates a shared secret from a ciphertext.
84 ///
85 /// This method recovers the shared secret that was encapsulated in the
86 /// given ciphertext, using the private key from this decrypter.
87 ///
88 /// # Parameters
89 ///
90 /// * `ciphertext` - The encapsulation ciphertext containing the
91 /// encapsulated shared secret
92 ///
93 /// # Returns
94 ///
95 /// A `Result` containing the decapsulated `SymmetricKey` if successful,
96 /// or an error if the decapsulation fails.
97 ///
98 /// # Errors
99 ///
100 /// Returns an error if:
101 /// - The ciphertext type doesn't match the private key type
102 /// - The decapsulation operation fails
103 ///
104 /// # Example
105 ///
106 /// ```
107 /// use bc_components::{Decrypter, EncapsulationScheme, Encrypter};
108 ///
109 /// // Generate a keypair
110 /// let (private_key, public_key) = EncapsulationScheme::default().keypair();
111 ///
112 /// // Encapsulate a new shared secret
113 /// let (original_secret, ciphertext) =
114 /// public_key.encapsulate_new_shared_secret();
115 ///
116 /// // Decapsulate the shared secret
117 /// let recovered_secret =
118 /// private_key.decapsulate_shared_secret(&ciphertext).unwrap();
119 ///
120 /// // The original and recovered secrets should match
121 /// assert_eq!(original_secret, recovered_secret);
122 /// ```
123 fn decapsulate_shared_secret(
124 &self,
125 ciphertext: &EncapsulationCiphertext,
126 ) -> Result<SymmetricKey> {
127 self.encapsulation_private_key()
128 .decapsulate_shared_secret(ciphertext)
129 }
130}