arnaucube
arnaucube/phantom-zonePublic Self-hosted repository
phantom-zone/src/shortint/mod.rs
src/shortint/mod.rsRaw
  1mod enc_dec;
  2mod ops;
  3
  4pub type FheUint8 = enc_dec::FheUint8<Vec<u64>>;
  5pub type FheBool = enc_dec::FheBool<Vec<u64>>;
  6
  7use std::cell::RefCell;
  8
  9use crate::bool::{evaluator::BooleanGates, BoolEvaluator, RuntimeServerKey};
 10
 11thread_local! {
 12     static DIV_ZERO_ERROR: RefCell<Option<FheBool>> = RefCell::new(None);
 13}
 14
 15/// Returns Boolean ciphertext indicating whether last division was attempeted
 16/// with decnomiantor set to 0.
 17pub fn div_zero_error_flag() -> Option<FheBool> {
 18    DIV_ZERO_ERROR.with_borrow(|c| c.clone())
 19}
 20
 21mod frontend {
 22    use super::ops::{
 23        arbitrary_bit_adder, arbitrary_bit_division_for_quotient_and_rem, arbitrary_bit_subtractor,
 24        eight_bit_mul,
 25    };
 26    use crate::utils::{Global, WithLocal};
 27
 28    use super::*;
 29
 30    mod arithetic {
 31
 32        use ops::is_zero;
 33
 34        use super::*;
 35        use std::ops::{Add, AddAssign, Div, Mul, Rem, Sub};
 36
 37        impl AddAssign<&FheUint8> for FheUint8 {
 38            fn add_assign(&mut self, rhs: &FheUint8) {
 39                BoolEvaluator::with_local_mut_mut(&mut |e| {
 40                    let key = RuntimeServerKey::global();
 41                    arbitrary_bit_adder(e, self.data_mut(), rhs.data(), false, key);
 42                });
 43            }
 44        }
 45
 46        impl Add<&FheUint8> for &FheUint8 {
 47            type Output = FheUint8;
 48            fn add(self, rhs: &FheUint8) -> Self::Output {
 49                let mut a = self.clone();
 50                a += rhs;
 51                a
 52            }
 53        }
 54
 55        impl Sub<&FheUint8> for &FheUint8 {
 56            type Output = FheUint8;
 57            fn sub(self, rhs: &FheUint8) -> Self::Output {
 58                BoolEvaluator::with_local_mut(|e| {
 59                    let key = RuntimeServerKey::global();
 60                    let (out, _, _) = arbitrary_bit_subtractor(e, self.data(), rhs.data(), key);
 61                    FheUint8 { data: out }
 62                })
 63            }
 64        }
 65
 66        impl Mul<&FheUint8> for &FheUint8 {
 67            type Output = FheUint8;
 68            fn mul(self, rhs: &FheUint8) -> Self::Output {
 69                BoolEvaluator::with_local_mut(|e| {
 70                    let key = RuntimeServerKey::global();
 71                    let out = eight_bit_mul(e, self.data(), rhs.data(), key);
 72                    FheUint8 { data: out }
 73                })
 74            }
 75        }
 76
 77        impl Div<&FheUint8> for &FheUint8 {
 78            type Output = FheUint8;
 79            fn div(self, rhs: &FheUint8) -> Self::Output {
 80                BoolEvaluator::with_local_mut(|e| {
 81                    let key = RuntimeServerKey::global();
 82
 83                    // set div by 0 error flag
 84                    let is_zero = is_zero(e, rhs.data(), key);
 85                    DIV_ZERO_ERROR.set(Some(FheBool { data: is_zero }));
 86
 87                    let (quotient, _) = arbitrary_bit_division_for_quotient_and_rem(
 88                        e,
 89                        self.data(),
 90                        rhs.data(),
 91                        key,
 92                    );
 93                    FheUint8 { data: quotient }
 94                })
 95            }
 96        }
 97
 98        impl Rem<&FheUint8> for &FheUint8 {
 99            type Output = FheUint8;
100            fn rem(self, rhs: &FheUint8) -> Self::Output {
101                BoolEvaluator::with_local_mut(|e| {
102                    let key = RuntimeServerKey::global();
103                    let (_, remainder) = arbitrary_bit_division_for_quotient_and_rem(
104                        e,
105                        self.data(),
106                        rhs.data(),
107                        key,
108                    );
109                    FheUint8 { data: remainder }
110                })
111            }
112        }
113
114        impl FheUint8 {
115            pub fn overflowing_add_assign(&mut self, rhs: &FheUint8) -> FheBool {
116                BoolEvaluator::with_local_mut_mut(&mut |e| {
117                    let key = RuntimeServerKey::global();
118                    let (overflow, _) =
119                        arbitrary_bit_adder(e, self.data_mut(), rhs.data(), false, key);
120                    FheBool { data: overflow }
121                })
122            }
123
124            pub fn overflowing_add(self, rhs: &FheUint8) -> (FheUint8, FheBool) {
125                BoolEvaluator::with_local_mut(|e| {
126                    let mut lhs = self.clone();
127                    let key = RuntimeServerKey::global();
128                    let (overflow, _) =
129                        arbitrary_bit_adder(e, lhs.data_mut(), rhs.data(), false, key);
130                    (lhs, FheBool { data: overflow })
131                })
132            }
133
134            pub fn overflowing_sub(&self, rhs: &FheUint8) -> (FheUint8, FheBool) {
135                BoolEvaluator::with_local_mut(|e| {
136                    let key = RuntimeServerKey::global();
137                    let (out, mut overflow, _) =
138                        arbitrary_bit_subtractor(e, self.data(), rhs.data(), key);
139                    e.not_inplace(&mut overflow);
140                    (FheUint8 { data: out }, FheBool { data: overflow })
141                })
142            }
143
144            pub fn div_rem(&self, rhs: &FheUint8) -> (FheUint8, FheUint8) {
145                BoolEvaluator::with_local_mut(|e| {
146                    let key = RuntimeServerKey::global();
147
148                    // set div by 0 error flag
149                    let is_zero = is_zero(e, rhs.data(), key);
150                    DIV_ZERO_ERROR.set(Some(FheBool { data: is_zero }));
151
152                    let (quotient, remainder) = arbitrary_bit_division_for_quotient_and_rem(
153                        e,
154                        self.data(),
155                        rhs.data(),
156                        key,
157                    );
158                    (FheUint8 { data: quotient }, FheUint8 { data: remainder })
159                })
160            }
161        }
162    }
163
164    mod booleans {
165        use crate::shortint::ops::{arbitrary_bit_comparator, arbitrary_bit_equality};
166
167        use super::*;
168
169        impl FheUint8 {
170            /// a == b
171            pub fn eq(&self, other: &FheUint8) -> FheBool {
172                BoolEvaluator::with_local_mut(|e| {
173                    let key = RuntimeServerKey::global();
174                    let out = arbitrary_bit_equality(e, self.data(), other.data(), key);
175                    FheBool { data: out }
176                })
177            }
178
179            /// a != b
180            pub fn neq(&self, other: &FheUint8) -> FheBool {
181                BoolEvaluator::with_local_mut(|e| {
182                    let key = RuntimeServerKey::global();
183                    let mut is_equal = arbitrary_bit_equality(e, self.data(), other.data(), key);
184                    e.not_inplace(&mut is_equal);
185                    FheBool { data: is_equal }
186                })
187            }
188
189            /// a < b
190            pub fn lt(&self, other: &FheUint8) -> FheBool {
191                BoolEvaluator::with_local_mut(|e| {
192                    let key = RuntimeServerKey::global();
193                    let out = arbitrary_bit_comparator(e, other.data(), self.data(), key);
194                    FheBool { data: out }
195                })
196            }
197
198            /// a > b
199            pub fn gt(&self, other: &FheUint8) -> FheBool {
200                BoolEvaluator::with_local_mut(|e| {
201                    let key = RuntimeServerKey::global();
202                    let out = arbitrary_bit_comparator(e, self.data(), other.data(), key);
203                    FheBool { data: out }
204                })
205            }
206
207            /// a <= b
208            pub fn le(&self, other: &FheUint8) -> FheBool {
209                BoolEvaluator::with_local_mut(|e| {
210                    let key = RuntimeServerKey::global();
211                    let mut a_greater_b =
212                        arbitrary_bit_comparator(e, self.data(), other.data(), key);
213                    e.not_inplace(&mut a_greater_b);
214                    FheBool { data: a_greater_b }
215                })
216            }
217
218            /// a >= b
219            pub fn ge(&self, other: &FheUint8) -> FheBool {
220                BoolEvaluator::with_local_mut(|e| {
221                    let key = RuntimeServerKey::global();
222                    let mut a_less_b = arbitrary_bit_comparator(e, other.data(), self.data(), key);
223                    e.not_inplace(&mut a_less_b);
224                    FheBool { data: a_less_b }
225                })
226            }
227        }
228    }
229}