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