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}