concrete_integer/server_key/crt_parallel/
neg_crt.rs

1use crate::{CrtCiphertext, ServerKey};
2use rayon::prelude::*;
3
4impl ServerKey {
5    /// Homomorphically computes the opposite of a ciphertext encrypting an integer message.
6    ///
7    /// This function computes the opposite of a message without checking if it exceeds the
8    /// capacity of the ciphertext.
9    ///
10    /// The result is returned as a new ciphertext.
11    /// # Example
12    ///
13    ///```rust
14    /// use concrete_integer::gen_keys;
15    /// use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
16    ///
17    /// // Generate the client key and the server key:
18    /// let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
19    ///
20    /// let clear = 14_u64;
21    /// let basis = vec![2, 3, 5];
22    ///
23    /// let mut ctxt = cks.encrypt_crt(clear, basis.clone());
24    ///
25    /// sks.unchecked_crt_neg_assign_parallelized(&mut ctxt);
26    ///
27    /// // Decrypt
28    /// let res = cks.decrypt_crt(&ctxt);
29    /// assert_eq!(16, res);
30    /// ```
31    pub fn unchecked_crt_neg_parallelized(&self, ctxt: &CrtCiphertext) -> CrtCiphertext {
32        let mut result = ctxt.clone();
33        self.unchecked_crt_neg_assign_parallelized(&mut result);
34        result
35    }
36
37    /// Homomorphically computes the opposite of a ciphertext encrypting an integer message.
38    ///
39    /// This function computes the opposite of a message without checking if it exceeds the
40    /// capacity of the ciphertext.
41    ///
42    /// The result is assigned to the `ct_left` ciphertext.
43    pub fn unchecked_crt_neg_assign_parallelized(&self, ctxt: &mut CrtCiphertext) {
44        ctxt.blocks.par_iter_mut().for_each(|ct_i| {
45            self.key.unchecked_neg_assign(ct_i);
46        });
47    }
48
49    /// Homomorphically computes the opposite of a ciphertext encrypting an integer message.
50    ///
51    /// # Example
52    ///
53    ///```rust
54    /// use concrete_integer::gen_keys;
55    /// use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
56    ///
57    /// // Generate the client key and the server key:
58    /// let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
59    ///
60    /// let clear = 14_u64;
61    /// let basis = vec![2, 3, 5];
62    ///
63    /// let mut ctxt = cks.encrypt_crt(clear, basis.clone());
64    ///
65    /// sks.smart_crt_neg_assign_parallelized(&mut ctxt);
66    ///
67    /// // Decrypt
68    /// let res = cks.decrypt_crt(&ctxt);
69    /// assert_eq!(16, res);
70    /// ```
71    pub fn smart_crt_neg_assign_parallelized(&self, ctxt: &mut CrtCiphertext) {
72        if !self.is_crt_neg_possible(ctxt) {
73            self.full_extract_parallelized(ctxt);
74        }
75        self.unchecked_crt_neg_assign_parallelized(ctxt);
76    }
77
78    pub fn smart_crt_neg_parallelized(&self, ctxt: &mut CrtCiphertext) -> CrtCiphertext {
79        if !self.is_crt_neg_possible(ctxt) {
80            self.full_extract_parallelized(ctxt);
81        }
82        self.unchecked_crt_neg_parallelized(ctxt)
83    }
84}