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}