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}