Skip to main content

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}