concrete_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::ciphertext::Ciphertext;
7use crate::engine::{CpuBooleanEngine, WithThreadLocalEngine};
8use crate::parameters::BooleanParameters;
9use concrete_core::prelude::*;
10use serde::{Deserialize, Deserializer, Serialize, Serializer};
11use std::fmt::{Debug, Formatter};
12
13/// A structure containing the client key, which must be kept secret.
14///
15/// In more details, it contains:
16/// * `lwe_secret_key` - an LWE secret key, used to encrypt the inputs and decrypt the outputs.
17/// This secret key is also used in the generation of bootstrapping and key switching keys.
18/// * `glwe_secret_key` - a GLWE secret key, used to generate the bootstrapping keys and key
19/// switching keys.
20/// * `parameters` - the cryptographic parameter set.
21#[derive(Clone)]
22pub struct ClientKey {
23    pub(crate) lwe_secret_key: LweSecretKey32,
24    pub(crate) glwe_secret_key: GlweSecretKey32,
25    pub(crate) parameters: BooleanParameters,
26}
27
28impl PartialEq for ClientKey {
29    fn eq(&self, other: &Self) -> bool {
30        self.parameters == other.parameters
31            && self.lwe_secret_key == other.lwe_secret_key
32            && self.glwe_secret_key == other.glwe_secret_key
33    }
34}
35
36impl Debug for ClientKey {
37    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
38        write!(f, "ClientKey {{ ")?;
39        write!(f, "lwe_secret_key: {:?}, ", self.lwe_secret_key)?;
40        write!(f, "glwe_secret_key: {:?}, ", self.glwe_secret_key)?;
41        write!(f, "parameters: {:?}, ", self.parameters)?;
42        write!(f, "engine: CoreEngine, ")?;
43        write!(f, "}}")?;
44        Ok(())
45    }
46}
47
48impl ClientKey {
49    /// Encrypts a Boolean message using the client key.
50    ///
51    /// # Example
52    ///
53    /// ```rust
54    /// # #[cfg(not(feature = "cuda"))]
55    /// # fn main() {
56    /// use concrete_boolean::prelude::*;
57    ///
58    /// // Generate the client key and the server key:
59    /// let (cks, mut sks) = gen_keys();
60    ///
61    /// // Encryption of one message:
62    /// let ct = cks.encrypt(true);
63    ///
64    /// // Decryption:
65    /// let dec = cks.decrypt(&ct);
66    /// assert_eq!(true, dec);
67    /// # }
68    /// # #[cfg(feature = "cuda")]
69    /// # fn main() {}
70    /// ```
71    pub fn encrypt(&self, message: bool) -> Ciphertext {
72        CpuBooleanEngine::with_thread_local_mut(|engine| engine.encrypt(message, self))
73    }
74
75    /// Decrypts a ciphertext encrypting a Boolean message using the client key.
76    ///
77    /// # Example
78    ///
79    /// ```rust
80    /// # #[cfg(not(feature = "cuda"))]
81    /// # fn main() {
82    /// use concrete_boolean::prelude::*;
83    ///
84    /// // Generate the client key and the server key:
85    /// let (cks, mut sks) = gen_keys();
86    ///
87    /// // Encryption of one message:
88    /// let ct = cks.encrypt(true);
89    ///
90    /// // Decryption:
91    /// let dec = cks.decrypt(&ct);
92    /// assert_eq!(true, dec);
93    /// # }
94    /// # #[cfg(feature = "cuda")]
95    /// # fn main() {}
96    /// ```
97    pub fn decrypt(&self, ct: &Ciphertext) -> bool {
98        CpuBooleanEngine::with_thread_local_mut(|engine| engine.decrypt(ct, self))
99    }
100
101    /// Allocates and generates a client key.
102    ///
103    /// # Panic
104    ///
105    /// This will panic when the "cuda" feature is enabled and the parameters
106    /// uses a GlweDimension > 1 (as it is not yet supported by the cuda backend).
107    ///
108    /// # Example
109    ///
110    /// ```rust
111    /// use concrete_boolean::client_key::ClientKey;
112    /// use concrete_boolean::parameters::TFHE_LIB_PARAMETERS;
113    /// use concrete_boolean::prelude::*;
114    ///
115    /// // Generate the client key:
116    /// let cks = ClientKey::new(&TFHE_LIB_PARAMETERS);
117    /// ```
118    pub fn new(parameter_set: &BooleanParameters) -> ClientKey {
119        #[cfg(feature = "cuda")]
120        {
121            if parameter_set.glwe_dimension.0 > 1 {
122                panic!("the cuda backend does not support support GlweSize greater than one");
123            }
124        }
125        CpuBooleanEngine::with_thread_local_mut(|engine| engine.create_client_key(*parameter_set))
126    }
127}
128
129#[derive(Serialize, Deserialize)]
130struct SerializableClientKey {
131    lwe_secret_key: Vec<u8>,
132    glwe_secret_key: Vec<u8>,
133    parameters: BooleanParameters,
134}
135
136impl Serialize for ClientKey {
137    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
138    where
139        S: Serializer,
140    {
141        let mut ser_eng = DefaultSerializationEngine::new(()).map_err(serde::ser::Error::custom)?;
142
143        let lwe_secret_key = ser_eng
144            .serialize(&self.lwe_secret_key)
145            .map_err(serde::ser::Error::custom)?;
146        let glwe_secret_key = ser_eng
147            .serialize(&self.glwe_secret_key)
148            .map_err(serde::ser::Error::custom)?;
149
150        SerializableClientKey {
151            lwe_secret_key,
152            glwe_secret_key,
153            parameters: self.parameters,
154        }
155        .serialize(serializer)
156    }
157}
158
159impl<'de> Deserialize<'de> for ClientKey {
160    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
161    where
162        D: Deserializer<'de>,
163    {
164        let thing =
165            SerializableClientKey::deserialize(deserializer).map_err(serde::de::Error::custom)?;
166        let mut de_eng = DefaultSerializationEngine::new(()).map_err(serde::de::Error::custom)?;
167
168        Ok(Self {
169            lwe_secret_key: de_eng
170                .deserialize(thing.lwe_secret_key.as_slice())
171                .map_err(serde::de::Error::custom)?,
172            glwe_secret_key: de_eng
173                .deserialize(thing.glwe_secret_key.as_slice())
174                .map_err(serde::de::Error::custom)?,
175            parameters: thing.parameters,
176        })
177    }
178}