tfhe/boolean/client_key/mod.rs
1//! The secret key of the client.
2//!
3//! This module implements the generation of the client' secret keys, together with the
4//! encryption and decryption methods.
5
6use crate::boolean::ciphertext::{Ciphertext, CompressedCiphertext};
7use crate::boolean::engine::{BooleanEngine, WithThreadLocalEngine};
8use crate::boolean::parameters::{BooleanParameters, DynamicDistribution, EncryptionKeyChoice};
9use crate::core_crypto::entities::*;
10use serde::{Deserialize, Serialize};
11use std::fmt::{Debug, Formatter};
12use tfhe_versionable::Versionize;
13
14use super::backward_compatibility::client_key::ClientKeyVersions;
15
16/// A structure containing the client key, which must be kept secret.
17///
18/// In more details, it contains:
19/// * `lwe_secret_key` - an LWE secret key, used to encrypt the inputs and decrypt the outputs. This
20/// secret key is also used in the generation of bootstrapping and key switching keys.
21/// * `glwe_secret_key` - a GLWE secret key, used to generate the bootstrapping keys and key
22/// switching keys.
23/// * `parameters` - the cryptographic parameter set.
24#[derive(Clone, Serialize, Deserialize, Versionize)]
25#[versionize(ClientKeyVersions)]
26pub struct ClientKey {
27 pub(crate) lwe_secret_key: LweSecretKeyOwned<u32>,
28 pub(crate) glwe_secret_key: GlweSecretKeyOwned<u32>,
29 pub(crate) parameters: BooleanParameters,
30}
31
32impl PartialEq for ClientKey {
33 fn eq(&self, other: &Self) -> bool {
34 self.parameters == other.parameters
35 && self.lwe_secret_key == other.lwe_secret_key
36 && self.glwe_secret_key == other.glwe_secret_key
37 }
38}
39
40impl Debug for ClientKey {
41 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42 write!(f, "ClientKey {{ ")?;
43 write!(f, "lwe_secret_key: {:?}, ", self.lwe_secret_key)?;
44 write!(f, "glwe_secret_key: {:?}, ", self.glwe_secret_key)?;
45 write!(f, "parameters: {:?}, ", self.parameters)?;
46 write!(f, "engine: CoreEngine, ")?;
47 write!(f, "}}")?;
48 Ok(())
49 }
50}
51
52impl ClientKey {
53 /// Returns a view to the encryption key and the corresponding noise distribution.
54 pub fn encryption_key_and_noise(
55 &self,
56 ) -> (LweSecretKeyView<'_, u32>, DynamicDistribution<u32>) {
57 match self.parameters.encryption_key_choice {
58 EncryptionKeyChoice::Big => (
59 self.glwe_secret_key.as_lwe_secret_key(),
60 self.parameters.glwe_noise_distribution,
61 ),
62 EncryptionKeyChoice::Small => (
63 self.lwe_secret_key.as_view(),
64 self.parameters.lwe_noise_distribution,
65 ),
66 }
67 }
68
69 /// Encrypt a Boolean message using the client key.
70 ///
71 /// # Example
72 ///
73 /// ```rust
74 /// use tfhe::boolean::prelude::*;
75 ///
76 /// // Generate the client key and the server key:
77 /// let (cks, sks) = gen_keys();
78 ///
79 /// // Encryption of one message:
80 /// let ct = cks.encrypt(true);
81 ///
82 /// // Decryption:
83 /// let dec = cks.decrypt(&ct);
84 /// assert!(dec);
85 /// ```
86 pub fn encrypt(&self, message: bool) -> Ciphertext {
87 BooleanEngine::with_thread_local_mut(|engine| engine.encrypt(message, self))
88 }
89
90 /// Encrypt a Boolean message using the client key returning a compressed ciphertext.
91 ///
92 /// # Example
93 ///
94 /// ```rust
95 /// use tfhe::boolean::prelude::*;
96 ///
97 /// // Generate the client key and the server key:
98 /// let (cks, sks) = gen_keys();
99 ///
100 /// // Encryption of one message:
101 /// let ct = cks.encrypt_compressed(true);
102 ///
103 /// let ct = ct.decompress();
104 ///
105 /// // Decryption:
106 /// let dec = cks.decrypt(&ct);
107 /// assert!(dec);
108 /// ```
109 pub fn encrypt_compressed(&self, message: bool) -> CompressedCiphertext {
110 BooleanEngine::with_thread_local_mut(|engine| engine.encrypt_compressed(message, self))
111 }
112
113 /// Decrypt a ciphertext encrypting a Boolean message using the client key.
114 ///
115 /// # Example
116 ///
117 /// ```rust
118 /// use tfhe::boolean::prelude::*;
119 ///
120 /// // Generate the client key and the server key:
121 /// let (cks, sks) = gen_keys();
122 ///
123 /// // Encryption of one message:
124 /// let ct = cks.encrypt(true);
125 ///
126 /// // Decryption:
127 /// let dec = cks.decrypt(&ct);
128 /// assert!(dec);
129 /// ```
130 pub fn decrypt(&self, ct: &Ciphertext) -> bool {
131 BooleanEngine::with_thread_local_mut(|engine| engine.decrypt(ct, self))
132 }
133
134 /// Allocate and generate a client key.
135 ///
136 /// # Example
137 ///
138 /// ```rust
139 /// use tfhe::boolean::client_key::ClientKey;
140 /// use tfhe::boolean::parameters::PARAMETERS_ERROR_PROB_2_POW_MINUS_165;
141 ///
142 /// // Generate the client key:
143 /// let cks = ClientKey::new(&PARAMETERS_ERROR_PROB_2_POW_MINUS_165);
144 /// ```
145 pub fn new(parameter_set: &BooleanParameters) -> Self {
146 BooleanEngine::with_thread_local_mut(|engine| engine.create_client_key(*parameter_set))
147 }
148
149 /// Deconstruct a [`ClientKey`] into its constituents.
150 ///
151 /// # Example
152 ///
153 /// ```rust
154 /// use tfhe::boolean::client_key::ClientKey;
155 /// use tfhe::boolean::parameters::PARAMETERS_ERROR_PROB_2_POW_MINUS_165;
156 ///
157 /// // Generate the client key:
158 /// let cks = ClientKey::new(&PARAMETERS_ERROR_PROB_2_POW_MINUS_165);
159 /// let raw_parts = cks.into_raw_parts();
160 /// ```
161 pub fn into_raw_parts(
162 self,
163 ) -> (
164 LweSecretKeyOwned<u32>,
165 GlweSecretKeyOwned<u32>,
166 BooleanParameters,
167 ) {
168 let Self {
169 lwe_secret_key,
170 glwe_secret_key,
171 parameters,
172 } = self;
173
174 (lwe_secret_key, glwe_secret_key, parameters)
175 }
176
177 /// Construct a [`ClientKey`] from its constituents.
178 ///
179 /// # Panics
180 ///
181 /// Panics if the provided raw parts are not compatible with the provided parameters.
182 ///
183 /// # Example
184 ///
185 /// ```rust
186 /// use tfhe::boolean::client_key::ClientKey;
187 /// use tfhe::boolean::parameters::PARAMETERS_ERROR_PROB_2_POW_MINUS_165;
188 ///
189 /// // Generate the client key:
190 /// let cks = ClientKey::new(&PARAMETERS_ERROR_PROB_2_POW_MINUS_165);
191 /// let (lwe_secret_key, glwe_secret_key, parameters) = cks.into_raw_parts();
192 /// let reconstructed_cks =
193 /// ClientKey::new_from_raw_parts(lwe_secret_key, glwe_secret_key, parameters);
194 /// ```
195 pub fn new_from_raw_parts(
196 lwe_secret_key: LweSecretKeyOwned<u32>,
197 glwe_secret_key: GlweSecretKeyOwned<u32>,
198 parameters: BooleanParameters,
199 ) -> Self {
200 assert_eq!(
201 lwe_secret_key.lwe_dimension(),
202 parameters.lwe_dimension,
203 "Mismatch between the LweSecretKey LweDimension ({:?}) \
204 and the parameters LweDimension ({:?})",
205 lwe_secret_key.lwe_dimension(),
206 parameters.lwe_dimension
207 );
208 assert_eq!(
209 glwe_secret_key.glwe_dimension(),
210 parameters.glwe_dimension,
211 "Mismatch between the GlweSecretKey GlweDimension ({:?}) \
212 and the parameters GlweDimension ({:?})",
213 glwe_secret_key.glwe_dimension(),
214 parameters.glwe_dimension
215 );
216
217 assert_eq!(
218 glwe_secret_key.polynomial_size(),
219 parameters.polynomial_size,
220 "Mismatch between the GlweSecretKey PolynomialSize ({:?}) \
221 and the parameters PolynomialSize ({:?})",
222 glwe_secret_key.polynomial_size(),
223 parameters.polynomial_size
224 );
225
226 Self {
227 lwe_secret_key,
228 glwe_secret_key,
229 parameters,
230 }
231 }
232}