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