concrete_integer/server_key/radix_parallel/bitwise_op.rs
1use crate::ciphertext::RadixCiphertext;
2use crate::ServerKey;
3
4impl ServerKey {
5 /// Computes homomorphically a bitand between two ciphertexts encrypting integer values.
6 ///
7 /// # Warning
8 ///
9 /// - Multithreaded
10 ///
11 /// # Example
12 ///
13 /// ```rust
14 /// use concrete_integer::gen_keys_radix;
15 /// use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
16 ///
17 /// // Generate the client key and the server key:
18 /// let num_blocks = 4;
19 /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
20 ///
21 /// let msg1 = 14;
22 /// let msg2 = 97;
23 ///
24 /// let mut ct1 = cks.encrypt(msg1);
25 /// let mut ct2 = cks.encrypt(msg2);
26 ///
27 /// let ct_res = sks.smart_bitand_parallelized(&mut ct1, &mut ct2);
28 ///
29 /// // Decrypt:
30 /// let dec_result = cks.decrypt(&ct_res);
31 /// assert_eq!(dec_result, msg1 & msg2);
32 /// ```
33 pub fn smart_bitand_parallelized(
34 &self,
35 ct_left: &mut RadixCiphertext,
36 ct_right: &mut RadixCiphertext,
37 ) -> RadixCiphertext {
38 if !self.is_functional_bivariate_pbs_possible(ct_left, ct_right) {
39 rayon::join(
40 || self.full_propagate_parallelized(ct_left),
41 || self.full_propagate_parallelized(ct_right),
42 );
43 }
44 self.unchecked_bitand(ct_left, ct_right)
45 }
46
47 pub fn smart_bitand_assign_parallelized(
48 &self,
49 ct_left: &mut RadixCiphertext,
50 ct_right: &mut RadixCiphertext,
51 ) {
52 if !self.is_functional_bivariate_pbs_possible(ct_left, ct_right) {
53 rayon::join(
54 || self.full_propagate_parallelized(ct_left),
55 || self.full_propagate_parallelized(ct_right),
56 );
57 }
58 self.unchecked_bitand_assign(ct_left, ct_right);
59 }
60
61 /// Computes homomorphically a bitor between two ciphertexts encrypting integer values.
62 ///
63 /// # Warning
64 ///
65 /// - Multithreaded
66 ///
67 /// # Example
68 ///
69 /// ```rust
70 /// use concrete_integer::gen_keys_radix;
71 /// use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
72 ///
73 /// // Generate the client key and the server key:
74 /// let num_blocks = 4;
75 /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
76 ///
77 /// let msg1 = 14;
78 /// let msg2 = 97;
79 ///
80 /// let mut ct1 = cks.encrypt(msg1);
81 /// let mut ct2 = cks.encrypt(msg2);
82 ///
83 /// let ct_res = sks.smart_bitor(&mut ct1, &mut ct2);
84 ///
85 /// // Decrypt:
86 /// let dec_result = cks.decrypt(&ct_res);
87 /// assert_eq!(dec_result, msg1 | msg2);
88 /// ```
89 pub fn smart_bitor_parallelized(
90 &self,
91 ct_left: &mut RadixCiphertext,
92 ct_right: &mut RadixCiphertext,
93 ) -> RadixCiphertext {
94 if !self.is_functional_bivariate_pbs_possible(ct_left, ct_right) {
95 rayon::join(
96 || self.full_propagate_parallelized(ct_left),
97 || self.full_propagate_parallelized(ct_right),
98 );
99 }
100 self.unchecked_bitor(ct_left, ct_right)
101 }
102
103 pub fn smart_bitor_assign_parallelized(
104 &self,
105 ct_left: &mut RadixCiphertext,
106 ct_right: &mut RadixCiphertext,
107 ) {
108 if !self.is_functional_bivariate_pbs_possible(ct_left, ct_right) {
109 rayon::join(
110 || self.full_propagate_parallelized(ct_left),
111 || self.full_propagate_parallelized(ct_right),
112 );
113 }
114 self.unchecked_bitor_assign(ct_left, ct_right);
115 }
116
117 /// Computes homomorphically a bitxor between two ciphertexts encrypting integer values.
118 ///
119 /// # Warning
120 ///
121 /// - Multithreaded
122 ///
123 /// # Example
124 ///
125 /// ```rust
126 /// use concrete_integer::gen_keys_radix;
127 /// use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
128 ///
129 /// // Generate the client key and the server key:
130 /// let num_blocks = 4;
131 /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
132 ///
133 /// let msg1 = 14;
134 /// let msg2 = 97;
135 ///
136 /// let mut ct1 = cks.encrypt(msg1);
137 /// let mut ct2 = cks.encrypt(msg2);
138 ///
139 /// let ct_res = sks.smart_bitxor_parallelized(&mut ct1, &mut ct2);
140 ///
141 /// // Decrypt:
142 /// let dec_result = cks.decrypt(&ct_res);
143 /// assert_eq!(dec_result, msg1 ^ msg2);
144 /// ```
145 pub fn smart_bitxor_parallelized(
146 &self,
147 ct_left: &mut RadixCiphertext,
148 ct_right: &mut RadixCiphertext,
149 ) -> RadixCiphertext {
150 if !self.is_functional_bivariate_pbs_possible(ct_left, ct_right) {
151 rayon::join(
152 || self.full_propagate_parallelized(ct_left),
153 || self.full_propagate_parallelized(ct_right),
154 );
155 }
156 self.unchecked_bitxor(ct_left, ct_right)
157 }
158
159 pub fn smart_bitxor_assign_parallelized(
160 &self,
161 ct_left: &mut RadixCiphertext,
162 ct_right: &mut RadixCiphertext,
163 ) {
164 if !self.is_functional_bivariate_pbs_possible(ct_left, ct_right) {
165 rayon::join(
166 || self.full_propagate_parallelized(ct_left),
167 || self.full_propagate_parallelized(ct_right),
168 );
169 }
170 self.unchecked_bitxor_assign(ct_left, ct_right);
171 }
172}