concrete_core/backends/fft/implementation/engines/fft_serialization_engine/deserialization.rs
1#![allow(clippy::missing_safety_doc)]
2
3use super::{FftSerializationEngine, FftSerializationError};
4use crate::backends::fft::private::crypto::bootstrap::FourierLweBootstrapKey;
5use crate::backends::fft::private::crypto::ggsw::FourierGgswCiphertext;
6use crate::prelude::{
7 EntityDeserializationEngine, EntityDeserializationError, FftFourierGgswCiphertext32,
8 FftFourierGgswCiphertext32Version, FftFourierGgswCiphertext64,
9 FftFourierGgswCiphertext64Version, FftFourierLweBootstrapKey32,
10 FftFourierLweBootstrapKey32Version, FftFourierLweBootstrapKey64,
11 FftFourierLweBootstrapKey64Version,
12};
13use aligned_vec::ABox;
14use concrete_fft::c64;
15use serde::Deserialize;
16
17/// # Description:
18/// Implementation of [`EntityDeserializationEngine`] for [`FftSerializationEngine`] that operates
19/// on 32 bits integers. It deserializes a GGSW ciphertext in the Fourier domain.
20impl EntityDeserializationEngine<&[u8], FftFourierGgswCiphertext32> for FftSerializationEngine {
21 /// # Example
22 /// ```
23 /// use concrete_core::prelude::{
24 /// DecompositionBaseLog, DecompositionLevelCount, GlweDimension, LweDimension, PolynomialSize,
25 /// Variance, *,
26 /// };
27 /// # use std::error::Error;
28 ///
29 /// # fn main() -> Result<(), Box<dyn Error>> {
30 /// // DISCLAIMER: the parameters used here are only for test purpose, and are not secure.
31 /// let glwe_dimension = GlweDimension(2);
32 /// let polynomial_size = PolynomialSize(256);
33 /// let level = DecompositionLevelCount(1);
34 /// let base_log = DecompositionBaseLog(4);
35 /// // Here a hard-set encoding is applied (shift by 20 bits)
36 /// let input = 3_u32 << 20;
37 /// let noise = Variance(2_f64.powf(-25.));
38 ///
39 /// // Unix seeder must be given a secret input.
40 /// // Here we just give it 0, which is totally unsafe.
41 /// const UNSAFE_SECRET: u128 = 0;
42 /// let mut default_engine = DefaultEngine::new(Box::new(UnixSeeder::new(UNSAFE_SECRET)))?;
43 /// let mut fft_engine = FftEngine::new(())?;
44 /// let key: GlweSecretKey32 =
45 /// default_engine.generate_new_glwe_secret_key(glwe_dimension, polynomial_size)?;
46 /// let plaintext = default_engine.create_plaintext_from(&input)?;
47 ///
48 /// // We encrypt a GGSW ciphertext in the standard domain
49 /// let ciphertext =
50 /// default_engine.encrypt_scalar_ggsw_ciphertext(&key, &plaintext, noise, level, base_log)?;
51 ///
52 /// // Then we convert it to the Fourier domain.
53 /// let fourier_ciphertext: FftFourierGgswCiphertext32 =
54 /// fft_engine.convert_ggsw_ciphertext(&ciphertext)?;
55 ///
56 /// let mut serialization_engine = FftSerializationEngine::new(())?;
57 /// let serialized = serialization_engine.serialize(&fourier_ciphertext)?;
58 /// let recovered = serialization_engine.deserialize(serialized.as_slice())?;
59 /// assert_eq!(fourier_ciphertext, recovered);
60 /// #
61 /// # Ok(())
62 /// # }
63 /// ```
64 fn deserialize(
65 &mut self,
66 serialized: &[u8],
67 ) -> Result<FftFourierGgswCiphertext32, EntityDeserializationError<Self::EngineError>> {
68 #[derive(Deserialize)]
69 struct SerializableFftFourierGgswCiphertext32 {
70 version: FftFourierGgswCiphertext32Version,
71 inner: FourierGgswCiphertext<ABox<[c64]>>,
72 }
73 let deserialized: SerializableFftFourierGgswCiphertext32 = bincode::deserialize(serialized)
74 .map_err(FftSerializationError::Deserialization)
75 .map_err(EntityDeserializationError::Engine)?;
76 match deserialized {
77 SerializableFftFourierGgswCiphertext32 {
78 version: FftFourierGgswCiphertext32Version::Unsupported,
79 ..
80 } => Err(EntityDeserializationError::Engine(
81 FftSerializationError::UnsupportedVersion,
82 )),
83 SerializableFftFourierGgswCiphertext32 {
84 version: FftFourierGgswCiphertext32Version::V0,
85 inner,
86 } => Ok(FftFourierGgswCiphertext32(inner)),
87 }
88 }
89
90 unsafe fn deserialize_unchecked(&mut self, serialized: &[u8]) -> FftFourierGgswCiphertext32 {
91 self.deserialize(serialized).unwrap()
92 }
93}
94
95/// # Description:
96/// Implementation of [`EntityDeserializationEngine`] for [`FftSerializationEngine`] that operates
97/// on 64 bits integers. It deserializes a GGSW ciphertext in the Fourier domain.
98impl EntityDeserializationEngine<&[u8], FftFourierGgswCiphertext64> for FftSerializationEngine {
99 /// # Example
100 /// ```
101 /// use concrete_core::prelude::{
102 /// DecompositionBaseLog, DecompositionLevelCount, GlweDimension, LweDimension, PolynomialSize,
103 /// Variance, *,
104 /// };
105 /// # use std::error::Error;
106 ///
107 /// # fn main() -> Result<(), Box<dyn Error>> {
108 /// // DISCLAIMER: the parameters used here are only for test purpose, and are not secure.
109 /// let glwe_dimension = GlweDimension(2);
110 /// let polynomial_size = PolynomialSize(256);
111 /// let level = DecompositionLevelCount(1);
112 /// let base_log = DecompositionBaseLog(4);
113 /// // Here a hard-set encoding is applied (shift by 50 bits)
114 /// let input = 3_u64 << 50;
115 /// let noise = Variance(2_f64.powf(-25.));
116 ///
117 /// // Unix seeder must be given a secret input.
118 /// // Here we just give it 0, which is totally unsafe.
119 /// const UNSAFE_SECRET: u128 = 0;
120 /// let mut default_engine = DefaultEngine::new(Box::new(UnixSeeder::new(UNSAFE_SECRET)))?;
121 /// let mut fft_engine = FftEngine::new(())?;
122 /// let key: GlweSecretKey64 =
123 /// default_engine.generate_new_glwe_secret_key(glwe_dimension, polynomial_size)?;
124 /// let plaintext = default_engine.create_plaintext_from(&input)?;
125 ///
126 /// // We encrypt a GGSW ciphertext in the standard domain
127 /// let ciphertext =
128 /// default_engine.encrypt_scalar_ggsw_ciphertext(&key, &plaintext, noise, level, base_log)?;
129 ///
130 /// // Then we convert it to the Fourier domain.
131 /// let fourier_ciphertext: FftFourierGgswCiphertext64 =
132 /// fft_engine.convert_ggsw_ciphertext(&ciphertext)?;
133 ///
134 /// let mut serialization_engine = FftSerializationEngine::new(())?;
135 /// let serialized = serialization_engine.serialize(&fourier_ciphertext)?;
136 /// let recovered = serialization_engine.deserialize(serialized.as_slice())?;
137 /// assert_eq!(fourier_ciphertext, recovered);
138 ///
139 /// #
140 /// # Ok(())
141 /// # }
142 /// ```
143 fn deserialize(
144 &mut self,
145 serialized: &[u8],
146 ) -> Result<FftFourierGgswCiphertext64, EntityDeserializationError<Self::EngineError>> {
147 #[derive(Deserialize)]
148 struct SerializableFftFourierGgswCiphertext64 {
149 version: FftFourierGgswCiphertext64Version,
150 inner: FourierGgswCiphertext<ABox<[c64]>>,
151 }
152 let deserialized: SerializableFftFourierGgswCiphertext64 = bincode::deserialize(serialized)
153 .map_err(FftSerializationError::Deserialization)
154 .map_err(EntityDeserializationError::Engine)?;
155 match deserialized {
156 SerializableFftFourierGgswCiphertext64 {
157 version: FftFourierGgswCiphertext64Version::Unsupported,
158 ..
159 } => Err(EntityDeserializationError::Engine(
160 FftSerializationError::UnsupportedVersion,
161 )),
162 SerializableFftFourierGgswCiphertext64 {
163 version: FftFourierGgswCiphertext64Version::V0,
164 inner,
165 } => Ok(FftFourierGgswCiphertext64(inner)),
166 }
167 }
168
169 unsafe fn deserialize_unchecked(&mut self, serialized: &[u8]) -> FftFourierGgswCiphertext64 {
170 self.deserialize(serialized).unwrap()
171 }
172}
173
174/// # Description:
175/// Implementation of [`EntityDeserializationEngine`] for [`FftSerializationEngine`] that operates
176/// on 32 bits integers. It deserializes an LWE bootstrap key in the Fourier domain.
177impl EntityDeserializationEngine<&[u8], FftFourierLweBootstrapKey32> for FftSerializationEngine {
178 /// # Example
179 /// ```
180 /// use concrete_core::prelude::{
181 /// DecompositionBaseLog, DecompositionLevelCount, GlweDimension, LweDimension, PolynomialSize,
182 /// Variance, *,
183 /// };
184 /// # use std::error::Error;
185 ///
186 /// # fn main() -> Result<(), Box<dyn Error>> {
187 /// // DISCLAIMER: the parameters used here are only for test purpose, and are not secure.
188 /// let (lwe_dim, glwe_dim, poly_size) = (LweDimension(4), GlweDimension(6), PolynomialSize(256));
189 /// let (dec_lc, dec_bl) = (DecompositionLevelCount(3), DecompositionBaseLog(5));
190 /// let noise = Variance(2_f64.powf(-25.));
191 ///
192 /// // Unix seeder must be given a secret input.
193 /// // Here we just give it 0, which is totally unsafe.
194 /// const UNSAFE_SECRET: u128 = 0;
195 /// let mut default_engine = DefaultEngine::new(Box::new(UnixSeeder::new(UNSAFE_SECRET)))?;
196 /// let mut fft_engine = FftEngine::new(())?;
197 /// let lwe_sk: LweSecretKey32 = default_engine.generate_new_lwe_secret_key(lwe_dim)?;
198 /// let glwe_sk: GlweSecretKey32 =
199 /// default_engine.generate_new_glwe_secret_key(glwe_dim, poly_size)?;
200 /// let bsk: LweBootstrapKey32 =
201 /// default_engine.generate_new_lwe_bootstrap_key(&lwe_sk, &glwe_sk, dec_bl, dec_lc, noise)?;
202 ///
203 /// let fourier_bsk: FftFourierLweBootstrapKey32 = fft_engine.convert_lwe_bootstrap_key(&bsk)?;
204 ///
205 /// let mut serialization_engine = FftSerializationEngine::new(())?;
206 /// let serialized = serialization_engine.serialize(&fourier_bsk)?;
207 /// let recovered = serialization_engine.deserialize(serialized.as_slice())?;
208 /// assert_eq!(fourier_bsk, recovered);
209 ///
210 /// #
211 /// # Ok(())
212 /// # }
213 /// ```
214 fn deserialize(
215 &mut self,
216 serialized: &[u8],
217 ) -> Result<FftFourierLweBootstrapKey32, EntityDeserializationError<Self::EngineError>> {
218 #[derive(Deserialize)]
219 struct SerializableFftFourierLweBootstrapKey32 {
220 version: FftFourierLweBootstrapKey32Version,
221 inner: FourierLweBootstrapKey<ABox<[c64]>>,
222 }
223 let deserialized: SerializableFftFourierLweBootstrapKey32 =
224 bincode::deserialize(serialized)
225 .map_err(FftSerializationError::Deserialization)
226 .map_err(EntityDeserializationError::Engine)?;
227 match deserialized {
228 SerializableFftFourierLweBootstrapKey32 {
229 version: FftFourierLweBootstrapKey32Version::Unsupported,
230 ..
231 } => Err(EntityDeserializationError::Engine(
232 FftSerializationError::UnsupportedVersion,
233 )),
234 SerializableFftFourierLweBootstrapKey32 {
235 version: FftFourierLweBootstrapKey32Version::V0,
236 inner,
237 } => Ok(FftFourierLweBootstrapKey32(inner)),
238 }
239 }
240
241 unsafe fn deserialize_unchecked(&mut self, serialized: &[u8]) -> FftFourierLweBootstrapKey32 {
242 self.deserialize(serialized).unwrap()
243 }
244}
245
246/// # Description:
247/// Implementation of [`EntityDeserializationEngine`] for [`FftSerializationEngine`] that operates
248/// on 64 bits integers. It deserializes an LWE bootstrap key in the Fourier domain.
249impl EntityDeserializationEngine<&[u8], FftFourierLweBootstrapKey64> for FftSerializationEngine {
250 /// # Example
251 /// ```
252 /// use concrete_core::prelude::{
253 /// DecompositionBaseLog, DecompositionLevelCount, GlweDimension, LweDimension, PolynomialSize,
254 /// Variance, *,
255 /// };
256 /// # use std::error::Error;
257 ///
258 /// # fn main() -> Result<(), Box<dyn Error>> {
259 /// // DISCLAIMER: the parameters used here are only for test purpose, and are not secure.
260 /// let (lwe_dim, glwe_dim, poly_size) = (LweDimension(4), GlweDimension(6), PolynomialSize(256));
261 /// let (dec_lc, dec_bl) = (DecompositionLevelCount(3), DecompositionBaseLog(5));
262 /// let noise = Variance(2_f64.powf(-25.));
263 ///
264 /// // Unix seeder must be given a secret input.
265 /// // Here we just give it 0, which is totally unsafe.
266 /// const UNSAFE_SECRET: u128 = 0;
267 /// let mut default_engine = DefaultEngine::new(Box::new(UnixSeeder::new(UNSAFE_SECRET)))?;
268 /// let mut fft_engine = FftEngine::new(())?;
269 /// let lwe_sk: LweSecretKey64 = default_engine.generate_new_lwe_secret_key(lwe_dim)?;
270 /// let glwe_sk: GlweSecretKey64 =
271 /// default_engine.generate_new_glwe_secret_key(glwe_dim, poly_size)?;
272 /// let bsk: LweBootstrapKey64 =
273 /// default_engine.generate_new_lwe_bootstrap_key(&lwe_sk, &glwe_sk, dec_bl, dec_lc, noise)?;
274 ///
275 /// let fourier_bsk: FftFourierLweBootstrapKey64 = fft_engine.convert_lwe_bootstrap_key(&bsk)?;
276 ///
277 /// let mut serialization_engine = FftSerializationEngine::new(())?;
278 /// let serialized = serialization_engine.serialize(&fourier_bsk)?;
279 /// let recovered = serialization_engine.deserialize(serialized.as_slice())?;
280 /// assert_eq!(fourier_bsk, recovered);
281 ///
282 /// #
283 /// # Ok(())
284 /// # }
285 /// ```
286 fn deserialize(
287 &mut self,
288 serialized: &[u8],
289 ) -> Result<FftFourierLweBootstrapKey64, EntityDeserializationError<Self::EngineError>> {
290 #[derive(Deserialize)]
291 struct SerializableFftFourierLweBootstrapKey64 {
292 version: FftFourierLweBootstrapKey64Version,
293 inner: FourierLweBootstrapKey<ABox<[c64]>>,
294 }
295 let deserialized: SerializableFftFourierLweBootstrapKey64 =
296 bincode::deserialize(serialized)
297 .map_err(FftSerializationError::Deserialization)
298 .map_err(EntityDeserializationError::Engine)?;
299 match deserialized {
300 SerializableFftFourierLweBootstrapKey64 {
301 version: FftFourierLweBootstrapKey64Version::Unsupported,
302 ..
303 } => Err(EntityDeserializationError::Engine(
304 FftSerializationError::UnsupportedVersion,
305 )),
306 SerializableFftFourierLweBootstrapKey64 {
307 version: FftFourierLweBootstrapKey64Version::V0,
308 inner,
309 } => Ok(FftFourierLweBootstrapKey64(inner)),
310 }
311 }
312
313 unsafe fn deserialize_unchecked(&mut self, serialized: &[u8]) -> FftFourierLweBootstrapKey64 {
314 self.deserialize(serialized).unwrap()
315 }
316}