phantom_zone/bool/
mod.rs

1mod evaluator;
2mod keys;
3pub(crate) mod parameters;
4
5#[cfg(feature = "interactive_mp")]
6mod mp_api;
7#[cfg(feature = "non_interactive_mp")]
8mod ni_mp_api;
9
10#[cfg(feature = "non_interactive_mp")]
11pub use ni_mp_api::*;
12
13#[cfg(feature = "interactive_mp")]
14pub use mp_api::*;
15
16use crate::RowEntity;
17
18pub type ClientKey = keys::ClientKey<[u8; 32], u64>;
19#[cfg(any(feature = "interactive_mp", feature = "non_interactive_mp"))]
20pub type FheBool = impl_bool_frontend::FheBool<Vec<u64>>;
21
22pub(crate) trait BooleanGates {
23    type Ciphertext: RowEntity;
24    type Key;
25
26    fn and_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
27    fn nand_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
28    fn or_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
29    fn nor_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
30    fn xor_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
31    fn xnor_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
32    fn not_inplace(&self, c: &mut Self::Ciphertext);
33
34    fn and(
35        &mut self,
36        c0: &Self::Ciphertext,
37        c1: &Self::Ciphertext,
38        key: &Self::Key,
39    ) -> Self::Ciphertext;
40    fn nand(
41        &mut self,
42        c0: &Self::Ciphertext,
43        c1: &Self::Ciphertext,
44        key: &Self::Key,
45    ) -> Self::Ciphertext;
46    fn or(
47        &mut self,
48        c0: &Self::Ciphertext,
49        c1: &Self::Ciphertext,
50        key: &Self::Key,
51    ) -> Self::Ciphertext;
52    fn nor(
53        &mut self,
54        c0: &Self::Ciphertext,
55        c1: &Self::Ciphertext,
56        key: &Self::Key,
57    ) -> Self::Ciphertext;
58    fn xor(
59        &mut self,
60        c0: &Self::Ciphertext,
61        c1: &Self::Ciphertext,
62        key: &Self::Key,
63    ) -> Self::Ciphertext;
64    fn xnor(
65        &mut self,
66        c0: &Self::Ciphertext,
67        c1: &Self::Ciphertext,
68        key: &Self::Key,
69    ) -> Self::Ciphertext;
70    fn not(&self, c: &Self::Ciphertext) -> Self::Ciphertext;
71}
72
73#[cfg(any(feature = "interactive_mp", feature = "non_interactive_mp"))]
74mod impl_bool_frontend {
75    use crate::MultiPartyDecryptor;
76
77    /// Fhe Bool ciphertext
78    #[derive(Clone)]
79    pub struct FheBool<C> {
80        pub(crate) data: C,
81    }
82
83    impl<C> FheBool<C> {
84        pub(crate) fn data(&self) -> &C {
85            &self.data
86        }
87
88        pub(crate) fn data_mut(&mut self) -> &mut C {
89            &mut self.data
90        }
91    }
92
93    impl<C, K> MultiPartyDecryptor<bool, FheBool<C>> for K
94    where
95        K: MultiPartyDecryptor<bool, C>,
96    {
97        type DecryptionShare = <K as MultiPartyDecryptor<bool, C>>::DecryptionShare;
98
99        fn aggregate_decryption_shares(
100            &self,
101            c: &FheBool<C>,
102            shares: &[Self::DecryptionShare],
103        ) -> bool {
104            self.aggregate_decryption_shares(&c.data, shares)
105        }
106
107        fn gen_decryption_share(&self, c: &FheBool<C>) -> Self::DecryptionShare {
108            self.gen_decryption_share(&c.data)
109        }
110    }
111
112    mod ops {
113        use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
114
115        use crate::{
116            utils::{Global, WithLocal},
117            BooleanGates,
118        };
119
120        use super::super::{BoolEvaluator, RuntimeServerKey};
121
122        type FheBool = super::super::FheBool;
123
124        impl BitAnd for &FheBool {
125            type Output = FheBool;
126            fn bitand(self, rhs: Self) -> Self::Output {
127                BoolEvaluator::with_local_mut(|e| {
128                    let key = RuntimeServerKey::global();
129                    FheBool {
130                        data: e.and(self.data(), rhs.data(), key),
131                    }
132                })
133            }
134        }
135
136        impl BitAndAssign for FheBool {
137            fn bitand_assign(&mut self, rhs: Self) {
138                BoolEvaluator::with_local_mut_mut(&mut |e| {
139                    let key = RuntimeServerKey::global();
140                    e.and_inplace(&mut self.data_mut(), rhs.data(), key);
141                });
142            }
143        }
144
145        impl BitOr for &FheBool {
146            type Output = FheBool;
147            fn bitor(self, rhs: Self) -> Self::Output {
148                BoolEvaluator::with_local_mut(|e| {
149                    let key = RuntimeServerKey::global();
150                    FheBool {
151                        data: e.or(self.data(), rhs.data(), key),
152                    }
153                })
154            }
155        }
156
157        impl BitOrAssign for FheBool {
158            fn bitor_assign(&mut self, rhs: Self) {
159                BoolEvaluator::with_local_mut_mut(&mut |e| {
160                    let key = RuntimeServerKey::global();
161                    e.or_inplace(&mut self.data_mut(), rhs.data(), key);
162                });
163            }
164        }
165
166        impl BitXor for &FheBool {
167            type Output = FheBool;
168            fn bitxor(self, rhs: Self) -> Self::Output {
169                BoolEvaluator::with_local_mut(|e| {
170                    let key = RuntimeServerKey::global();
171                    FheBool {
172                        data: e.xor(self.data(), rhs.data(), key),
173                    }
174                })
175            }
176        }
177
178        impl BitXorAssign for FheBool {
179            fn bitxor_assign(&mut self, rhs: Self) {
180                BoolEvaluator::with_local_mut_mut(&mut |e| {
181                    let key = RuntimeServerKey::global();
182                    e.xor_inplace(&mut self.data_mut(), rhs.data(), key);
183                });
184            }
185        }
186
187        impl Not for &FheBool {
188            type Output = FheBool;
189            fn not(self) -> Self::Output {
190                BoolEvaluator::with_local(|e| FheBool {
191                    data: e.not(self.data()),
192                })
193            }
194        }
195    }
196}
197
198#[cfg(any(feature = "interactive_mp", feature = "non_interactive_mp"))]
199mod common_mp_enc_dec {
200    use itertools::Itertools;
201
202    use super::BoolEvaluator;
203    use crate::{
204        pbs::{sample_extract, PbsInfo},
205        utils::WithLocal,
206        Matrix, RowEntity, SampleExtractor,
207    };
208
209    type Mat = Vec<Vec<u64>>;
210
211    impl SampleExtractor<<Mat as Matrix>::R> for Mat {
212        /// Sample extract coefficient at `index` as a LWE ciphertext from RLWE
213        /// ciphertext `Self`
214        fn extract_at(&self, index: usize) -> <Mat as Matrix>::R {
215            // input is RLWE ciphertext
216            assert!(self.dimension().0 == 2);
217
218            let ring_size = self.dimension().1;
219            assert!(index < ring_size);
220
221            BoolEvaluator::with_local(|e| {
222                let mut lwe_out = <Mat as Matrix>::R::zeros(ring_size + 1);
223                sample_extract(&mut lwe_out, self, e.pbs_info().modop_rlweq(), index);
224                lwe_out
225            })
226        }
227
228        /// Extract first `how_many` coefficients of `Self` as LWE ciphertexts
229        fn extract_many(&self, how_many: usize) -> Vec<<Mat as Matrix>::R> {
230            assert!(self.dimension().0 == 2);
231
232            let ring_size = self.dimension().1;
233            assert!(how_many <= ring_size);
234
235            (0..how_many)
236                .map(|index| {
237                    BoolEvaluator::with_local(|e| {
238                        let mut lwe_out = <Mat as Matrix>::R::zeros(ring_size + 1);
239                        sample_extract(&mut lwe_out, self, e.pbs_info().modop_rlweq(), index);
240                        lwe_out
241                    })
242                })
243                .collect_vec()
244        }
245
246        /// Extracts all coefficients of `Self` as LWE ciphertexts
247        fn extract_all(&self) -> Vec<<Mat as Matrix>::R> {
248            assert!(self.dimension().0 == 2);
249
250            let ring_size = self.dimension().1;
251
252            (0..ring_size)
253                .map(|index| {
254                    BoolEvaluator::with_local(|e| {
255                        let mut lwe_out = <Mat as Matrix>::R::zeros(ring_size + 1);
256                        sample_extract(&mut lwe_out, self, e.pbs_info().modop_rlweq(), index);
257                        lwe_out
258                    })
259                })
260                .collect_vec()
261        }
262    }
263}
264
265#[cfg(test)]
266mod print_noise;