bc_components/
encrypter.rs

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