concrete_core/backends/core/implementation/engines/glwe_ciphertext_vector_decryption.rs
1use concrete_commons::parameters::PlaintextCount;
2
3use crate::backends::core::implementation::engines::CoreEngine;
4use crate::backends::core::implementation::entities::{
5    GlweCiphertextVector32, GlweCiphertextVector64, GlweSecretKey32, GlweSecretKey64,
6    PlaintextVector32, PlaintextVector64,
7};
8use crate::backends::core::private::crypto::encoding::PlaintextList as ImplPlaintextList;
9use crate::specification::engines::{
10    GlweCiphertextVectorDecryptionEngine, GlweCiphertextVectorDecryptionError,
11};
12use crate::specification::entities::{GlweCiphertextVectorEntity, GlweSecretKeyEntity};
13
14/// # Description:
15/// Implementation of [`GlweCiphertextVectorDecryptionEngine`] for [`CoreEngine`] that operates on
16/// 32 bits integers.
17impl
18    GlweCiphertextVectorDecryptionEngine<GlweSecretKey32, GlweCiphertextVector32, PlaintextVector32>
19    for CoreEngine
20{
21    /// # Example:
22    /// ```
23    /// use concrete_commons::dispersion::Variance;
24    /// use concrete_commons::parameters::{GlweDimension, PlaintextCount, PolynomialSize};
25    /// use concrete_core::prelude::*;
26    /// # use std::error::Error;
27    ///
28    /// # fn main() -> Result<(), Box<dyn Error>> {
29    /// // DISCLAIMER: the parameters used here are only for test purpose, and are not secure.
30    /// let glwe_dimension = GlweDimension(2);
31    /// let polynomial_size = PolynomialSize(4);
32    /// // Here a hard-set encoding is applied (shift by 20 bits)
33    /// let input = vec![3_u32 << 20; 8];
34    /// let noise = Variance(2_f64.powf(-25.));
35    ///
36    /// let mut engine = CoreEngine::new(())?;
37    /// let key: GlweSecretKey32 = engine.create_glwe_secret_key(glwe_dimension, polynomial_size)?;
38    /// let plaintext_vector = engine.create_plaintext_vector(&input)?;
39    /// let ciphertext_vector =
40    ///     engine.encrypt_glwe_ciphertext_vector(&key, &plaintext_vector, noise)?;
41    ///
42    /// let decrypted_plaintext_vector =
43    ///     engine.decrypt_glwe_ciphertext_vector(&key, &ciphertext_vector)?;
44    /// #
45    /// assert_eq!(
46    /// #     decrypted_plaintext_vector.plaintext_count(),
47    /// #     PlaintextCount(8)
48    /// # );
49    ///
50    /// engine.destroy(ciphertext_vector)?;
51    /// engine.destroy(plaintext_vector)?;
52    /// engine.destroy(decrypted_plaintext_vector)?;
53    /// engine.destroy(key)?;
54    /// #
55    /// # Ok(())
56    /// # }
57    /// ```
58    fn decrypt_glwe_ciphertext_vector(
59        &mut self,
60        key: &GlweSecretKey32,
61        input: &GlweCiphertextVector32,
62    ) -> Result<PlaintextVector32, GlweCiphertextVectorDecryptionError<Self::EngineError>> {
63        GlweCiphertextVectorDecryptionError::perform_generic_checks(key, input)?;
64        Ok(unsafe { self.decrypt_glwe_ciphertext_vector_unchecked(key, input) })
65    }
66
67    unsafe fn decrypt_glwe_ciphertext_vector_unchecked(
68        &mut self,
69        key: &GlweSecretKey32,
70        input: &GlweCiphertextVector32,
71    ) -> PlaintextVector32 {
72        let mut plaintext_list = ImplPlaintextList::allocate(
73            0u32,
74            PlaintextCount(key.polynomial_size().0 * input.glwe_ciphertext_count().0),
75        );
76        key.0.decrypt_glwe_list(&mut plaintext_list, &input.0);
77        PlaintextVector32(plaintext_list)
78    }
79}
80
81/// # Description:
82/// Implementation of [`GlweCiphertextVectorDecryptionEngine`] for [`CoreEngine`] that operates on
83/// 64 bits integers.
84impl
85    GlweCiphertextVectorDecryptionEngine<GlweSecretKey64, GlweCiphertextVector64, PlaintextVector64>
86    for CoreEngine
87{
88    /// # Example:
89    /// ```
90    /// use concrete_commons::dispersion::Variance;
91    /// use concrete_commons::parameters::{GlweDimension, PlaintextCount, PolynomialSize};
92    /// use concrete_core::prelude::*;
93    /// # use std::error::Error;
94    ///
95    /// # fn main() -> Result<(), Box<dyn Error>> {
96    /// // DISCLAIMER: the parameters used here are only for test purpose, and are not secure.
97    /// let glwe_dimension = GlweDimension(2);
98    /// let polynomial_size = PolynomialSize(4);
99    /// // Here a hard-set encoding is applied (shift by 50 bits)
100    /// let input = vec![3_u64 << 50; 8];
101    /// let noise = Variance(2_f64.powf(-25.));
102    ///
103    /// let mut engine = CoreEngine::new(())?;
104    /// let key: GlweSecretKey64 = engine.create_glwe_secret_key(glwe_dimension, polynomial_size)?;
105    /// let plaintext_vector = engine.create_plaintext_vector(&input)?;
106    /// let ciphertext_vector =
107    ///     engine.encrypt_glwe_ciphertext_vector(&key, &plaintext_vector, noise)?;
108    ///
109    /// let decrypted_plaintext_vector =
110    ///     engine.decrypt_glwe_ciphertext_vector(&key, &ciphertext_vector)?;
111    /// #
112    /// assert_eq!(
113    /// #     decrypted_plaintext_vector.plaintext_count(),
114    /// #     PlaintextCount(8)
115    /// # );
116    ///
117    /// engine.destroy(ciphertext_vector)?;
118    /// engine.destroy(plaintext_vector)?;
119    /// engine.destroy(decrypted_plaintext_vector)?;
120    /// engine.destroy(key)?;
121    /// #
122    /// # Ok(())
123    /// # }
124    /// ```
125    fn decrypt_glwe_ciphertext_vector(
126        &mut self,
127        key: &GlweSecretKey64,
128        input: &GlweCiphertextVector64,
129    ) -> Result<PlaintextVector64, GlweCiphertextVectorDecryptionError<Self::EngineError>> {
130        GlweCiphertextVectorDecryptionError::perform_generic_checks(key, input)?;
131        Ok(unsafe { self.decrypt_glwe_ciphertext_vector_unchecked(key, input) })
132    }
133
134    unsafe fn decrypt_glwe_ciphertext_vector_unchecked(
135        &mut self,
136        key: &GlweSecretKey64,
137        input: &GlweCiphertextVector64,
138    ) -> PlaintextVector64 {
139        let mut plaintext_list = ImplPlaintextList::allocate(
140            0u64,
141            PlaintextCount(key.polynomial_size().0 * input.glwe_ciphertext_count().0),
142        );
143        key.0.decrypt_glwe_list(&mut plaintext_list, &input.0);
144        PlaintextVector64(plaintext_list)
145    }
146}