bc_components/
encrypter.rs

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