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}