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}