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