concrete_integer/server_key/crt/
add_crt.rs

1use crate::{CrtCiphertext, ServerKey};
2
3impl ServerKey {
4    /// Computes homomorphically an addition between two ciphertexts encrypting integer values.
5    ///
6    /// # Example
7    ///
8    ///```rust
9    /// use concrete_integer::gen_keys;
10    /// use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
11    ///
12    /// // Generate the client key and the server key:
13    /// let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
14    ///
15    /// let clear_1 = 14;
16    /// let clear_2 = 14;
17    /// let basis = vec![2, 3, 5];
18    /// // Encrypt two messages
19    /// let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
20    /// let mut ctxt_2 = cks.encrypt_crt(clear_2, basis);
21    ///
22    /// sks.smart_crt_add_assign(&mut ctxt_1, &mut ctxt_2);
23    ///
24    /// // Decrypt
25    /// let res = cks.decrypt_crt(&ctxt_1);
26    /// assert_eq!((clear_1 + clear_2) % 30, res);
27    /// ```
28    pub fn smart_crt_add(
29        &self,
30        ct_left: &mut CrtCiphertext,
31        ct_right: &mut CrtCiphertext,
32    ) -> CrtCiphertext {
33        if !self.is_crt_add_possible(ct_left, ct_right) {
34            self.full_extract(ct_left);
35            self.full_extract(ct_right);
36        }
37        self.unchecked_crt_add(ct_left, ct_right)
38    }
39
40    pub fn smart_crt_add_assign(&self, ct_left: &mut CrtCiphertext, ct_right: &mut CrtCiphertext) {
41        //If the ciphertext cannot be added together without exceeding the capacity of a ciphertext
42        if !self.is_crt_add_possible(ct_left, ct_right) {
43            self.full_extract(ct_left);
44            self.full_extract(ct_right);
45        }
46        self.unchecked_crt_add_assign(ct_left, ct_right);
47    }
48
49    pub fn is_crt_add_possible(&self, ct_left: &CrtCiphertext, ct_right: &CrtCiphertext) -> bool {
50        for (ct_left_i, ct_right_i) in ct_left.blocks.iter().zip(ct_right.blocks.iter()) {
51            if !self.key.is_add_possible(ct_left_i, ct_right_i) {
52                return false;
53            }
54        }
55        true
56    }
57
58    pub fn unchecked_crt_add_assign(&self, ct_left: &mut CrtCiphertext, ct_right: &CrtCiphertext) {
59        for (ct_left_i, ct_right_i) in ct_left.blocks.iter_mut().zip(ct_right.blocks.iter()) {
60            self.key.unchecked_add_assign(ct_left_i, ct_right_i);
61        }
62    }
63
64    pub fn unchecked_crt_add(
65        &self,
66        ct_left: &CrtCiphertext,
67        ct_right: &CrtCiphertext,
68    ) -> CrtCiphertext {
69        let mut ct_res = ct_left.clone();
70        self.unchecked_crt_add_assign(&mut ct_res, ct_right);
71        ct_res
72    }
73}