concrete_integer/server_key/crt/
neg_crt.rs

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