mirror of
https://github.com/arnaucube/phantom-zone.git
synced 2026-01-09 15:41:30 +01:00
add bool frontend
This commit is contained in:
@@ -33,7 +33,7 @@ use crate::{
|
||||
encode_x_pow_si_with_emebedding_factor, mod_exponent, puncture_p_rng, TryConvertFrom1,
|
||||
WithLocal,
|
||||
},
|
||||
Encoder, Matrix, MatrixEntity, MatrixMut, RowEntity, RowMut,
|
||||
BooleanGates, Encoder, Matrix, MatrixEntity, MatrixMut, RowEntity, RowMut,
|
||||
};
|
||||
|
||||
use super::{
|
||||
@@ -171,57 +171,6 @@ impl<S: Default + Copy> NonInteractiveMultiPartyCrs<S> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait BooleanGates {
|
||||
type Ciphertext: RowEntity;
|
||||
type Key;
|
||||
|
||||
fn and_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
|
||||
fn nand_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
|
||||
fn or_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
|
||||
fn nor_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
|
||||
fn xor_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
|
||||
fn xnor_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
|
||||
fn not_inplace(&mut self, c: &mut Self::Ciphertext);
|
||||
|
||||
fn and(
|
||||
&mut self,
|
||||
c0: &Self::Ciphertext,
|
||||
c1: &Self::Ciphertext,
|
||||
key: &Self::Key,
|
||||
) -> Self::Ciphertext;
|
||||
fn nand(
|
||||
&mut self,
|
||||
c0: &Self::Ciphertext,
|
||||
c1: &Self::Ciphertext,
|
||||
key: &Self::Key,
|
||||
) -> Self::Ciphertext;
|
||||
fn or(
|
||||
&mut self,
|
||||
c0: &Self::Ciphertext,
|
||||
c1: &Self::Ciphertext,
|
||||
key: &Self::Key,
|
||||
) -> Self::Ciphertext;
|
||||
fn nor(
|
||||
&mut self,
|
||||
c0: &Self::Ciphertext,
|
||||
c1: &Self::Ciphertext,
|
||||
key: &Self::Key,
|
||||
) -> Self::Ciphertext;
|
||||
fn xor(
|
||||
&mut self,
|
||||
c0: &Self::Ciphertext,
|
||||
c1: &Self::Ciphertext,
|
||||
key: &Self::Key,
|
||||
) -> Self::Ciphertext;
|
||||
fn xnor(
|
||||
&mut self,
|
||||
c0: &Self::Ciphertext,
|
||||
c1: &Self::Ciphertext,
|
||||
key: &Self::Key,
|
||||
) -> Self::Ciphertext;
|
||||
fn not(&mut self, c: &Self::Ciphertext) -> Self::Ciphertext;
|
||||
}
|
||||
|
||||
struct ScratchMemory<M>
|
||||
where
|
||||
M: Matrix,
|
||||
@@ -2324,7 +2273,7 @@ where
|
||||
);
|
||||
}
|
||||
|
||||
fn not_inplace(&mut self, c0: &mut M::R) {
|
||||
fn not_inplace(&self, c0: &mut M::R) {
|
||||
let modop = &self.pbs_info.rlwe_modop;
|
||||
c0.as_mut().iter_mut().for_each(|v| *v = modop.neg(v));
|
||||
}
|
||||
@@ -2395,7 +2344,7 @@ where
|
||||
out
|
||||
}
|
||||
|
||||
fn not(&mut self, c: &Self::Ciphertext) -> Self::Ciphertext {
|
||||
fn not(&self, c: &Self::Ciphertext) -> Self::Ciphertext {
|
||||
let mut out = c.clone();
|
||||
self.not_inplace(&mut out);
|
||||
out
|
||||
|
||||
@@ -497,7 +497,7 @@ pub(super) mod impl_server_key_eval_domain {
|
||||
use itertools::{izip, Itertools};
|
||||
|
||||
use crate::{
|
||||
evaluator::InteractiveMultiPartyCrs,
|
||||
bool::evaluator::InteractiveMultiPartyCrs,
|
||||
ntt::{Ntt, NttInit},
|
||||
pbs::PbsKey,
|
||||
random::RandomFill,
|
||||
@@ -1268,7 +1268,7 @@ pub struct CommonReferenceSeededNonInteractiveMultiPartyServerKeyShare<M: Matrix
|
||||
}
|
||||
|
||||
mod impl_common_ref_non_interactive_multi_party_server_share {
|
||||
use crate::evaluator::multi_party_user_id_lwe_segment;
|
||||
use crate::bool::evaluator::multi_party_user_id_lwe_segment;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
180
src/bool/mod.rs
180
src/bool/mod.rs
@@ -1,4 +1,4 @@
|
||||
pub(crate) mod evaluator;
|
||||
mod evaluator;
|
||||
mod keys;
|
||||
pub(crate) mod parameters;
|
||||
|
||||
@@ -13,7 +13,185 @@ pub use ni_mp_api::*;
|
||||
#[cfg(feature = "interactive_mp")]
|
||||
pub use mp_api::*;
|
||||
|
||||
use crate::RowEntity;
|
||||
|
||||
pub type ClientKey = keys::ClientKey<[u8; 32], u64>;
|
||||
pub type FheBool = impl_bool_frontend::FheBool<Vec<u64>>;
|
||||
|
||||
pub(crate) trait BooleanGates {
|
||||
type Ciphertext: RowEntity;
|
||||
type Key;
|
||||
|
||||
fn and_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
|
||||
fn nand_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
|
||||
fn or_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
|
||||
fn nor_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
|
||||
fn xor_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
|
||||
fn xnor_inplace(&mut self, c0: &mut Self::Ciphertext, c1: &Self::Ciphertext, key: &Self::Key);
|
||||
fn not_inplace(&self, c: &mut Self::Ciphertext);
|
||||
|
||||
fn and(
|
||||
&mut self,
|
||||
c0: &Self::Ciphertext,
|
||||
c1: &Self::Ciphertext,
|
||||
key: &Self::Key,
|
||||
) -> Self::Ciphertext;
|
||||
fn nand(
|
||||
&mut self,
|
||||
c0: &Self::Ciphertext,
|
||||
c1: &Self::Ciphertext,
|
||||
key: &Self::Key,
|
||||
) -> Self::Ciphertext;
|
||||
fn or(
|
||||
&mut self,
|
||||
c0: &Self::Ciphertext,
|
||||
c1: &Self::Ciphertext,
|
||||
key: &Self::Key,
|
||||
) -> Self::Ciphertext;
|
||||
fn nor(
|
||||
&mut self,
|
||||
c0: &Self::Ciphertext,
|
||||
c1: &Self::Ciphertext,
|
||||
key: &Self::Key,
|
||||
) -> Self::Ciphertext;
|
||||
fn xor(
|
||||
&mut self,
|
||||
c0: &Self::Ciphertext,
|
||||
c1: &Self::Ciphertext,
|
||||
key: &Self::Key,
|
||||
) -> Self::Ciphertext;
|
||||
fn xnor(
|
||||
&mut self,
|
||||
c0: &Self::Ciphertext,
|
||||
c1: &Self::Ciphertext,
|
||||
key: &Self::Key,
|
||||
) -> Self::Ciphertext;
|
||||
fn not(&self, c: &Self::Ciphertext) -> Self::Ciphertext;
|
||||
}
|
||||
|
||||
mod impl_bool_frontend {
|
||||
use crate::MultiPartyDecryptor;
|
||||
|
||||
/// Fhe Bool ciphertext
|
||||
#[derive(Clone)]
|
||||
pub struct FheBool<C> {
|
||||
pub(crate) data: C,
|
||||
}
|
||||
|
||||
impl<C> FheBool<C> {
|
||||
pub(crate) fn data(&self) -> &C {
|
||||
&self.data
|
||||
}
|
||||
|
||||
pub(crate) fn data_mut(&mut self) -> &mut C {
|
||||
&mut self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, K> MultiPartyDecryptor<bool, FheBool<C>> for K
|
||||
where
|
||||
K: MultiPartyDecryptor<bool, C>,
|
||||
{
|
||||
type DecryptionShare = <K as MultiPartyDecryptor<bool, C>>::DecryptionShare;
|
||||
|
||||
fn aggregate_decryption_shares(
|
||||
&self,
|
||||
c: &FheBool<C>,
|
||||
shares: &[Self::DecryptionShare],
|
||||
) -> bool {
|
||||
self.aggregate_decryption_shares(&c.data, shares)
|
||||
}
|
||||
|
||||
fn gen_decryption_share(&self, c: &FheBool<C>) -> Self::DecryptionShare {
|
||||
self.gen_decryption_share(&c.data)
|
||||
}
|
||||
}
|
||||
|
||||
mod ops {
|
||||
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
|
||||
|
||||
use crate::{
|
||||
utils::{Global, WithLocal},
|
||||
BooleanGates,
|
||||
};
|
||||
|
||||
use super::super::{BoolEvaluator, RuntimeServerKey};
|
||||
|
||||
type FheBool = super::super::FheBool;
|
||||
|
||||
impl BitAnd for &FheBool {
|
||||
type Output = FheBool;
|
||||
fn bitand(self, rhs: Self) -> Self::Output {
|
||||
BoolEvaluator::with_local_mut(|e| {
|
||||
let key = RuntimeServerKey::global();
|
||||
FheBool {
|
||||
data: e.and(self.data(), rhs.data(), key),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl BitAndAssign for FheBool {
|
||||
fn bitand_assign(&mut self, rhs: Self) {
|
||||
BoolEvaluator::with_local_mut_mut(&mut |e| {
|
||||
let key = RuntimeServerKey::global();
|
||||
e.and_inplace(&mut self.data_mut(), rhs.data(), key);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl BitOr for &FheBool {
|
||||
type Output = FheBool;
|
||||
fn bitor(self, rhs: Self) -> Self::Output {
|
||||
BoolEvaluator::with_local_mut(|e| {
|
||||
let key = RuntimeServerKey::global();
|
||||
FheBool {
|
||||
data: e.or(self.data(), rhs.data(), key),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl BitOrAssign for FheBool {
|
||||
fn bitor_assign(&mut self, rhs: Self) {
|
||||
BoolEvaluator::with_local_mut_mut(&mut |e| {
|
||||
let key = RuntimeServerKey::global();
|
||||
e.or_inplace(&mut self.data_mut(), rhs.data(), key);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl BitXor for &FheBool {
|
||||
type Output = FheBool;
|
||||
fn bitxor(self, rhs: Self) -> Self::Output {
|
||||
BoolEvaluator::with_local_mut(|e| {
|
||||
let key = RuntimeServerKey::global();
|
||||
FheBool {
|
||||
data: e.xor(self.data(), rhs.data(), key),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl BitXorAssign for FheBool {
|
||||
fn bitxor_assign(&mut self, rhs: Self) {
|
||||
BoolEvaluator::with_local_mut_mut(&mut |e| {
|
||||
let key = RuntimeServerKey::global();
|
||||
e.xor_inplace(&mut self.data_mut(), rhs.data(), key);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Not for &FheBool {
|
||||
type Output = FheBool;
|
||||
fn not(self) -> Self::Output {
|
||||
BoolEvaluator::with_local(|e| FheBool {
|
||||
data: e.not(self.data()),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod common_mp_enc_dec {
|
||||
use super::BoolEvaluator;
|
||||
|
||||
@@ -265,10 +265,10 @@ mod tests {
|
||||
|
||||
use crate::{
|
||||
bool::{
|
||||
evaluator::BooleanGates,
|
||||
evaluator::BoolEncoding,
|
||||
keys::tests::{ideal_sk_rlwe, measure_noise_lwe},
|
||||
BooleanGates,
|
||||
},
|
||||
evaluator::{BoolEncoding, BoolEvaluator},
|
||||
Encryptor, MultiPartyDecryptor,
|
||||
};
|
||||
|
||||
@@ -368,9 +368,8 @@ mod tests {
|
||||
use rand::Rng;
|
||||
|
||||
use crate::{
|
||||
backend::ModulusPowerOf2, evaluator::BoolEncoding, pbs::PbsInfo,
|
||||
rgsw::seeded_secret_key_encrypt_rlwe, utils::WithLocal, Decryptor, ModularOpsU64,
|
||||
NttBackendU64, SampleExtractor,
|
||||
bool::impl_bool_frontend::FheBool, pbs::PbsInfo, rgsw::seeded_secret_key_encrypt_rlwe,
|
||||
Decryptor, SampleExtractor,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
@@ -423,6 +422,27 @@ mod tests {
|
||||
BoolEvaluator::with_local(|e| e.sk_decrypt(c, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: SinglePartyClientKey<Element = i32>, C> Encryptor<bool, FheBool<C>> for K
|
||||
where
|
||||
K: Encryptor<bool, C>,
|
||||
{
|
||||
fn encrypt(&self, m: &bool) -> FheBool<C> {
|
||||
FheBool {
|
||||
data: self.encrypt(m),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: SinglePartyClientKey<Element = i32>, C> Decryptor<bool, FheBool<C>> for K
|
||||
where
|
||||
K: Decryptor<bool, C>,
|
||||
{
|
||||
fn decrypt(&self, c: &FheBool<C>) -> bool {
|
||||
self.decrypt(c.data())
|
||||
}
|
||||
}
|
||||
|
||||
impl<K> Encryptor<[bool], (Vec<Vec<u64>>, [u8; 32])> for K
|
||||
where
|
||||
K: SinglePartyClientKey<Element = i32>,
|
||||
@@ -658,5 +678,40 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "interactive_mp")]
|
||||
fn all_bool_apis() {
|
||||
use crate::FheBool;
|
||||
|
||||
set_single_party_parameter_sets(SP_TEST_BOOL_PARAMS);
|
||||
|
||||
let (ck, sk) = gen_keys();
|
||||
sk.set_server_key();
|
||||
|
||||
for _ in 0..100 {
|
||||
let a = thread_rng().gen_bool(0.5);
|
||||
let b = thread_rng().gen_bool(0.5);
|
||||
|
||||
let c_a: FheBool = ck.encrypt(&a);
|
||||
let c_b: FheBool = ck.encrypt(&b);
|
||||
|
||||
let c_out = &c_a & &c_b;
|
||||
let out = ck.decrypt(&c_out);
|
||||
assert_eq!(out, a & b, "Expected {} but got {out}", a & b);
|
||||
|
||||
let c_out = &c_a | &c_b;
|
||||
let out = ck.decrypt(&c_out);
|
||||
assert_eq!(out, a | b, "Expected {} but got {out}", a | b);
|
||||
|
||||
let c_out = &c_a ^ &c_b;
|
||||
let out = ck.decrypt(&c_out);
|
||||
assert_eq!(out, a ^ b, "Expected {} but got {out}", a ^ b);
|
||||
|
||||
let c_out = !(&c_a);
|
||||
let out = ck.decrypt(&c_out);
|
||||
assert_eq!(out, !a, "Expected {} but got {out}", !a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,8 +406,8 @@ mod tests {
|
||||
|
||||
use crate::{
|
||||
bool::{
|
||||
evaluator::BooleanGates,
|
||||
keys::tests::{ideal_sk_rlwe, measure_noise_lwe},
|
||||
BooleanGates,
|
||||
},
|
||||
Encoder, Encryptor, KeySwitchWithId, MultiPartyDecryptor,
|
||||
};
|
||||
|
||||
@@ -370,8 +370,10 @@ mod tests {
|
||||
fn qwerty() {
|
||||
use crate::{
|
||||
aggregate_public_key_shares, aggregate_server_key_shares,
|
||||
bool::keys::{key_size::KeySize, ServerKeyEvaluationDomain},
|
||||
bool::{
|
||||
evaluator::InteractiveMultiPartyCrs,
|
||||
keys::{key_size::KeySize, ServerKeyEvaluationDomain},
|
||||
},
|
||||
gen_client_key, gen_mp_keys_phase1, gen_mp_keys_phase2,
|
||||
parameters::CiphertextModulus,
|
||||
random::DefaultSecureRng,
|
||||
@@ -432,9 +434,11 @@ mod tests {
|
||||
fn querty2() {
|
||||
use crate::{
|
||||
aggregate_server_key_shares,
|
||||
bool::keys::{key_size::KeySize, NonInteractiveServerKeyEvaluationDomain},
|
||||
decomposer::DefaultDecomposer,
|
||||
bool::{
|
||||
evaluator::NonInteractiveMultiPartyCrs,
|
||||
keys::{key_size::KeySize, NonInteractiveServerKeyEvaluationDomain},
|
||||
},
|
||||
decomposer::DefaultDecomposer,
|
||||
gen_client_key, gen_server_key_share,
|
||||
parameters::CiphertextModulus,
|
||||
random::DefaultSecureRng,
|
||||
|
||||
@@ -22,7 +22,7 @@ pub use backend::{
|
||||
// ParameterSelector, };
|
||||
pub use bool::*;
|
||||
pub use ntt::{Ntt, NttBackendU64, NttInit};
|
||||
pub use shortint::{div_zero_error_flag, FheBool, FheUint8};
|
||||
pub use shortint::{div_zero_error_flag, FheUint8};
|
||||
|
||||
pub use decomposer::{Decomposer, DecomposerIter, DefaultDecomposer};
|
||||
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::{
|
||||
bool::BoolEvaluator,
|
||||
bool::{BoolEvaluator, FheBool},
|
||||
random::{DefaultSecureRng, RandomFillUniformInModulus},
|
||||
utils::WithLocal,
|
||||
Decryptor, Encryptor, KeySwitchWithId, Matrix, MatrixEntity, MatrixMut, MultiPartyDecryptor,
|
||||
RowMut, SampleExtractor,
|
||||
};
|
||||
|
||||
/// Fhe Bool ciphertext
|
||||
#[derive(Clone)]
|
||||
pub struct FheBool<C> {
|
||||
pub(super) data: C,
|
||||
}
|
||||
|
||||
/// Fhe UInt8 type
|
||||
///
|
||||
/// - Stores encryptions of bits in little endian (i.e least signficant bit
|
||||
@@ -210,25 +204,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, K> MultiPartyDecryptor<bool, FheBool<C>> for K
|
||||
where
|
||||
K: MultiPartyDecryptor<bool, C>,
|
||||
{
|
||||
type DecryptionShare = <K as MultiPartyDecryptor<bool, C>>::DecryptionShare;
|
||||
|
||||
fn aggregate_decryption_shares(
|
||||
&self,
|
||||
c: &FheBool<C>,
|
||||
shares: &[Self::DecryptionShare],
|
||||
) -> bool {
|
||||
self.aggregate_decryption_shares(&c.data, shares)
|
||||
}
|
||||
|
||||
fn gen_decryption_share(&self, c: &FheBool<C>) -> Self::DecryptionShare {
|
||||
self.gen_decryption_share(&c.data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, K> Encryptor<u8, FheUint8<C>> for K
|
||||
where
|
||||
K: Encryptor<bool, C>,
|
||||
|
||||
@@ -2,11 +2,10 @@ mod enc_dec;
|
||||
mod ops;
|
||||
|
||||
pub type FheUint8 = enc_dec::FheUint8<Vec<u64>>;
|
||||
pub type FheBool = enc_dec::FheBool<Vec<u64>>;
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
use crate::bool::{evaluator::BooleanGates, BoolEvaluator, RuntimeServerKey};
|
||||
use crate::bool::{BoolEvaluator, BooleanGates, FheBool, RuntimeServerKey};
|
||||
|
||||
thread_local! {
|
||||
static DIV_ZERO_ERROR: RefCell<Option<FheBool>> = RefCell::new(None);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use itertools::{izip, Itertools};
|
||||
|
||||
use crate::bool::evaluator::BooleanGates;
|
||||
use crate::bool::BooleanGates;
|
||||
|
||||
pub(super) fn half_adder<E: BooleanGates>(
|
||||
evaluator: &mut E,
|
||||
|
||||
Reference in New Issue
Block a user