concrete_integer/server_key/radix_parallel/mod.rs
1mod add;
2mod bitwise_op;
3mod mul;
4mod neg;
5mod scalar_add;
6mod scalar_mul;
7mod scalar_sub;
8mod shift;
9mod sub;
10
11#[cfg(test)]
12mod tests;
13
14use super::ServerKey;
15use crate::RadixCiphertext;
16
17// parallelized versions
18impl ServerKey {
19 /// Propagate the carry of the 'index' block to the next one.
20 ///
21 /// # Example
22 ///
23 ///```rust
24 /// use concrete_integer::gen_keys_radix;
25 /// use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
26 ///
27 /// // Generate the client key and the server key:
28 /// let num_blocks = 4;
29 /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
30 ///
31 /// let msg = 7;
32 ///
33 /// let ct1 = cks.encrypt(msg);
34 /// let ct2 = cks.encrypt(msg);
35 ///
36 /// // Compute homomorphically an addition:
37 /// let mut ct_res = sks.unchecked_add(&ct1, &ct2);
38 /// sks.propagate_parallelized(&mut ct_res, 0);
39 ///
40 /// // Decrypt one block:
41 /// let res = cks.decrypt_one_block(&ct_res.blocks()[1]);
42 /// assert_eq!(3, res);
43 /// ```
44 pub fn propagate_parallelized(&self, ctxt: &mut RadixCiphertext, index: usize) {
45 let (carry, message) = rayon::join(
46 || self.key.carry_extract(&ctxt.blocks[index]),
47 || self.key.message_extract(&ctxt.blocks[index]),
48 );
49 ctxt.blocks[index] = message;
50
51 //add the carry to the next block
52 if index < ctxt.blocks.len() - 1 {
53 self.key
54 .unchecked_add_assign(&mut ctxt.blocks[index + 1], &carry);
55 }
56 }
57
58 /// Propagate all the carries.
59 ///
60 /// # Example
61 ///
62 ///```rust
63 /// use concrete_integer::gen_keys_radix;
64 /// use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
65 ///
66 /// // Generate the client key and the server key:
67 /// let num_blocks = 4;
68 /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
69 ///
70 /// let msg = 10;
71 ///
72 /// let mut ct1 = cks.encrypt(msg);
73 /// let mut ct2 = cks.encrypt(msg);
74 ///
75 /// // Compute homomorphically an addition:
76 /// let mut ct_res = sks.unchecked_add(&mut ct1, &mut ct2);
77 /// sks.full_propagate_parallelized(&mut ct_res);
78 ///
79 /// // Decrypt:
80 /// let res = cks.decrypt(&ct_res);
81 /// assert_eq!(msg + msg, res);
82 /// ```
83 pub fn full_propagate_parallelized(&self, ctxt: &mut RadixCiphertext) {
84 let len = ctxt.blocks.len();
85 for i in 0..len {
86 self.propagate_parallelized(ctxt, i);
87 }
88 }
89}