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}