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}