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 SampleExtractor<<Mat as Matrix>::R> for Mat {
209        /// Sample extract coefficient at `index` as a LWE ciphertext from RLWE
210        /// ciphertext `Self`
211        fn extract_at(&self, index: usize) -> <Mat as Matrix>::R {
212            // input is RLWE ciphertext
213            assert!(self.dimension().0 == 2);
214
215            let ring_size = self.dimension().1;
216            assert!(index < ring_size);
217
218            BoolEvaluator::with_local(|e| {
219                let mut lwe_out = <Mat as Matrix>::R::zeros(ring_size + 1);
220                sample_extract(&mut lwe_out, self, e.pbs_info().modop_rlweq(), index);
221                lwe_out
222            })
223        }
224
225        /// Extract first `how_many` coefficients of `Self` as LWE ciphertexts
226        fn extract_many(&self, how_many: usize) -> Vec<<Mat as Matrix>::R> {
227            assert!(self.dimension().0 == 2);
228
229            let ring_size = self.dimension().1;
230            assert!(how_many <= ring_size);
231
232            (0..how_many)
233                .map(|index| {
234                    BoolEvaluator::with_local(|e| {
235                        let mut lwe_out = <Mat as Matrix>::R::zeros(ring_size + 1);
236                        sample_extract(&mut lwe_out, self, e.pbs_info().modop_rlweq(), index);
237                        lwe_out
238                    })
239                })
240                .collect_vec()
241        }
242
243        /// Extracts all coefficients of `Self` as LWE ciphertexts
244        fn extract_all(&self) -> Vec<<Mat as Matrix>::R> {
245            assert!(self.dimension().0 == 2);
246
247            let ring_size = self.dimension().1;
248
249            (0..ring_size)
250                .map(|index| {
251                    BoolEvaluator::with_local(|e| {
252                        let mut lwe_out = <Mat as Matrix>::R::zeros(ring_size + 1);
253                        sample_extract(&mut lwe_out, self, e.pbs_info().modop_rlweq(), index);
254                        lwe_out
255                    })
256                })
257                .collect_vec()
258        }
259    }
260}
261
262#[cfg(test)]
263mod print_noise;