mirror of
https://github.com/arnaucube/phantom-zone.git
synced 2026-01-09 23:51:30 +01:00
add div by zero
This commit is contained in:
@@ -508,13 +508,15 @@ mod tests {
|
|||||||
fn all_uint8_apis() {
|
fn all_uint8_apis() {
|
||||||
use num_traits::Euclid;
|
use num_traits::Euclid;
|
||||||
|
|
||||||
|
use crate::div_zero_error_flag;
|
||||||
|
|
||||||
set_single_party_parameter_sets(SP_TEST_BOOL_PARAMS);
|
set_single_party_parameter_sets(SP_TEST_BOOL_PARAMS);
|
||||||
|
|
||||||
let (ck, sk) = gen_keys();
|
let (ck, sk) = gen_keys();
|
||||||
sk.set_server_key();
|
sk.set_server_key();
|
||||||
|
|
||||||
for i in 144..=255 {
|
for i in 0..=255 {
|
||||||
for j in 100..=255 {
|
for j in 0..=255 {
|
||||||
let m0 = i;
|
let m0 = i;
|
||||||
let m1 = j;
|
let m1 = j;
|
||||||
let c0 = ck.encrypt(&m0);
|
let c0 = ck.encrypt(&m0);
|
||||||
@@ -574,7 +576,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
m_remainder, r,
|
m_remainder, r,
|
||||||
"Expected {} but got {m_quotient} for {i}%{j}",
|
"Expected {} but got {m_remainder} for {i}%{j}",
|
||||||
r
|
r
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -584,8 +586,14 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
m_remainder, i,
|
m_remainder, i,
|
||||||
"Expected {i} but got {m_quotient}. Case div by zero"
|
"Expected {i} but got {m_remainder}. Case div by zero"
|
||||||
)
|
);
|
||||||
|
|
||||||
|
let div_by_zero = ck.decrypt(&div_zero_error_flag().unwrap());
|
||||||
|
assert_eq!(
|
||||||
|
div_by_zero, true,
|
||||||
|
"Expected true but got {div_by_zero}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ pub use backend::{
|
|||||||
// ParameterSelector, };
|
// ParameterSelector, };
|
||||||
pub use bool::*;
|
pub use bool::*;
|
||||||
pub use ntt::{Ntt, NttBackendU64, NttInit};
|
pub use ntt::{Ntt, NttBackendU64, NttInit};
|
||||||
pub use shortint::FheUint8;
|
pub use shortint::{div_zero_error_flag, FheUint8};
|
||||||
|
|
||||||
pub use decomposer::{Decomposer, DecomposerIter, DefaultDecomposer};
|
pub use decomposer::{Decomposer, DecomposerIter, DefaultDecomposer};
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,20 @@ mod types;
|
|||||||
pub type FheUint8 = enc_dec::FheUint8<Vec<u64>>;
|
pub type FheUint8 = enc_dec::FheUint8<Vec<u64>>;
|
||||||
pub type FheBool = Vec<u64>;
|
pub type FheBool = Vec<u64>;
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use crate::bool::{evaluator::BooleanGates, BoolEvaluator, RuntimeServerKey};
|
use crate::bool::{evaluator::BooleanGates, BoolEvaluator, RuntimeServerKey};
|
||||||
|
|
||||||
|
thread_local! {
|
||||||
|
static DIV_ZERO_ERROR: RefCell<Option<FheBool>> = RefCell::new(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns Boolean ciphertext indicating whether last division was attempeted
|
||||||
|
/// with decnomiantor set to 0.
|
||||||
|
pub fn div_zero_error_flag() -> Option<Vec<u64>> {
|
||||||
|
DIV_ZERO_ERROR.with_borrow(|c| c.clone())
|
||||||
|
}
|
||||||
|
|
||||||
mod frontend {
|
mod frontend {
|
||||||
use super::ops::{
|
use super::ops::{
|
||||||
arbitrary_bit_adder, arbitrary_bit_division_for_quotient_and_rem, arbitrary_bit_subtractor,
|
arbitrary_bit_adder, arbitrary_bit_division_for_quotient_and_rem, arbitrary_bit_subtractor,
|
||||||
@@ -18,6 +30,8 @@ mod frontend {
|
|||||||
|
|
||||||
mod arithetic {
|
mod arithetic {
|
||||||
|
|
||||||
|
use ops::is_zero;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::ops::{Add, AddAssign, Div, Mul, Rem, Sub};
|
use std::ops::{Add, AddAssign, Div, Mul, Rem, Sub};
|
||||||
|
|
||||||
@@ -64,9 +78,13 @@ mod frontend {
|
|||||||
impl Div<&FheUint8> for &FheUint8 {
|
impl Div<&FheUint8> for &FheUint8 {
|
||||||
type Output = FheUint8;
|
type Output = FheUint8;
|
||||||
fn div(self, rhs: &FheUint8) -> Self::Output {
|
fn div(self, rhs: &FheUint8) -> Self::Output {
|
||||||
// TODO(Jay:) Figure out how to set zero error flag
|
|
||||||
BoolEvaluator::with_local_mut(|e| {
|
BoolEvaluator::with_local_mut(|e| {
|
||||||
let key = RuntimeServerKey::global();
|
let key = RuntimeServerKey::global();
|
||||||
|
|
||||||
|
// set div by 0 error flag
|
||||||
|
let is_zero = is_zero(e, rhs.data(), key);
|
||||||
|
DIV_ZERO_ERROR.set(Some(is_zero));
|
||||||
|
|
||||||
let (quotient, _) = arbitrary_bit_division_for_quotient_and_rem(
|
let (quotient, _) = arbitrary_bit_division_for_quotient_and_rem(
|
||||||
e,
|
e,
|
||||||
self.data(),
|
self.data(),
|
||||||
@@ -125,9 +143,13 @@ mod frontend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn div_rem(&self, rhs: &FheUint8) -> (FheUint8, FheUint8) {
|
pub fn div_rem(&self, rhs: &FheUint8) -> (FheUint8, FheUint8) {
|
||||||
// TODO(Jay:) Figure out how to set zero error flag
|
|
||||||
BoolEvaluator::with_local_mut(|e| {
|
BoolEvaluator::with_local_mut(|e| {
|
||||||
let key = RuntimeServerKey::global();
|
let key = RuntimeServerKey::global();
|
||||||
|
|
||||||
|
// set div by 0 error flag
|
||||||
|
let is_zero = is_zero(e, rhs.data(), key);
|
||||||
|
DIV_ZERO_ERROR.set(Some(is_zero));
|
||||||
|
|
||||||
let (quotient, remainder) = arbitrary_bit_division_for_quotient_and_rem(
|
let (quotient, remainder) = arbitrary_bit_division_for_quotient_and_rem(
|
||||||
e,
|
e,
|
||||||
self.data(),
|
self.data(),
|
||||||
@@ -141,9 +163,7 @@ mod frontend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod booleans {
|
mod booleans {
|
||||||
use crate::shortint::ops::{
|
use crate::shortint::ops::{arbitrary_bit_comparator, arbitrary_bit_equality};
|
||||||
arbitrary_bit_comparator, arbitrary_bit_equality, arbitrary_signed_bit_comparator,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
|||||||
@@ -256,7 +256,11 @@ where
|
|||||||
(quotient, remainder)
|
(quotient, remainder)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_zero<E: BooleanGates>(evaluator: &mut E, a: &[E::Ciphertext], key: &E::Key) -> E::Ciphertext {
|
pub(super) fn is_zero<E: BooleanGates>(
|
||||||
|
evaluator: &mut E,
|
||||||
|
a: &[E::Ciphertext],
|
||||||
|
key: &E::Key,
|
||||||
|
) -> E::Ciphertext {
|
||||||
let mut a = a.iter().map(|v| evaluator.not(v)).collect_vec();
|
let mut a = a.iter().map(|v| evaluator.not(v)).collect_vec();
|
||||||
let (out, rest_a) = a.split_at_mut(1);
|
let (out, rest_a) = a.split_at_mut(1);
|
||||||
rest_a.iter().for_each(|c| {
|
rest_a.iter().for_each(|c| {
|
||||||
|
|||||||
Reference in New Issue
Block a user