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 #[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 fn extract_at(&self, index: usize) -> <Mat as Matrix>::R {
215 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 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 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;