mirror of
https://github.com/arnaucube/phantom-zone.git
synced 2026-01-07 22:51:29 +01:00
add bool noise
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use std::{
|
||||
borrow::BorrowMut,
|
||||
cell::{OnceCell, RefCell},
|
||||
clone,
|
||||
collections::HashMap,
|
||||
@@ -1808,11 +1809,11 @@ mod tests {
|
||||
NttBackendU64,
|
||||
ModularOpsU64<CiphertextModulus<u64>>,
|
||||
ModularOpsU64<CiphertextModulus<u64>>,
|
||||
>::new(MP_BOOL_PARAMS);
|
||||
>::new(SP_BOOL_PARAMS);
|
||||
|
||||
// let (_, collective_pk, _, _, server_key_eval, ideal_client_key) =
|
||||
// _multi_party_all_keygen(&bool_evaluator, 20);
|
||||
let no_of_parties = 32;
|
||||
let no_of_parties = 2;
|
||||
let lwe_q = bool_evaluator.pbs_info.parameters.lwe_q();
|
||||
let rlwe_q = bool_evaluator.pbs_info.parameters.rlwe_q();
|
||||
let lwe_n = bool_evaluator.pbs_info.parameters.lwe_n().0;
|
||||
@@ -1938,7 +1939,7 @@ mod tests {
|
||||
bool_evaluator.aggregate_multi_party_server_key_shares(&server_key_shares);
|
||||
|
||||
// Check noise in RGSW ciphertexts of ideal LWE secret elements
|
||||
if true {
|
||||
if false {
|
||||
let mut check = Stats { samples: vec![] };
|
||||
izip!(
|
||||
ideal_client_key.sk_lwe().values.iter(),
|
||||
@@ -2040,7 +2041,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// check noise in RLWE x RGSW(X^{s_i}) where RGSW is accunulated RGSW ciphertext
|
||||
if true {
|
||||
if false {
|
||||
let mut check = Stats { samples: vec![] };
|
||||
|
||||
izip!(
|
||||
@@ -2151,7 +2152,7 @@ mod tests {
|
||||
}
|
||||
|
||||
// check noise in Auto key
|
||||
if true {
|
||||
if false {
|
||||
let mut check = Stats { samples: vec![] };
|
||||
|
||||
let mut neg_s_poly =
|
||||
@@ -2219,7 +2220,7 @@ mod tests {
|
||||
// auto key
|
||||
if true {
|
||||
let mut check = Stats { samples: vec![] };
|
||||
|
||||
let br_q = bool_evaluator.pbs_info.br_q();
|
||||
let g = bool_evaluator.pbs_info.g();
|
||||
let auto_element_dlogs = bool_evaluator.pbs_info.parameters.auto_element_dlogs();
|
||||
for i in auto_element_dlogs.into_iter() {
|
||||
@@ -2252,8 +2253,8 @@ mod tests {
|
||||
);
|
||||
|
||||
let auto_key = server_key_eval_domain.galois_key_for_auto(i);
|
||||
let g_pow = if i == 0 { -g } else { g.pow(i as u32) };
|
||||
let (auto_map_index, auto_map_sign) = generate_auto_map(rlwe_n, g_pow);
|
||||
let (auto_map_index, auto_map_sign) =
|
||||
bool_evaluator.pbs_info.rlwe_auto_map(i);
|
||||
let mut scratch =
|
||||
vec![vec![0u64; rlwe_n]; auto_decomposer.decomposition_count() + 2];
|
||||
galois_auto(
|
||||
|
||||
@@ -19,7 +19,7 @@ use crate::{
|
||||
};
|
||||
|
||||
thread_local! {
|
||||
static BOOL_EVALUATOR: RefCell<BoolEvaluator<Vec<Vec<u64>>, NttBackendU64, ModularOpsU64<CiphertextModulus<u64>>, ModularOpsU64<CiphertextModulus<u64>>>> = RefCell::new(BoolEvaluator::new(MP_BOOL_PARAMS));
|
||||
static BOOL_EVALUATOR: RefCell<Option<BoolEvaluator<Vec<Vec<u64>>, NttBackendU64, ModularOpsU64<CiphertextModulus<u64>>, ModularOpsU64<CiphertextModulus<u64>>>>> = RefCell::new(None);
|
||||
|
||||
}
|
||||
static BOOL_SERVER_KEY: OnceLock<
|
||||
@@ -29,7 +29,7 @@ static BOOL_SERVER_KEY: OnceLock<
|
||||
static MULTI_PARTY_CRS: OnceLock<MultiPartyCrs<[u8; 32]>> = OnceLock::new();
|
||||
|
||||
pub fn set_parameter_set(parameter: &BoolParameters<u64>) {
|
||||
BoolEvaluator::with_local_mut(|e| *e = BoolEvaluator::new(parameter.clone()))
|
||||
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(parameter.clone())));
|
||||
}
|
||||
|
||||
pub fn set_mp_seed(seed: [u8; 32]) {
|
||||
@@ -158,20 +158,20 @@ impl WithLocal
|
||||
where
|
||||
F: Fn(&Self) -> R,
|
||||
{
|
||||
BOOL_EVALUATOR.with_borrow(|s| func(s))
|
||||
BOOL_EVALUATOR.with_borrow(|s| func(s.as_ref().expect("Parameters not set")))
|
||||
}
|
||||
|
||||
fn with_local_mut<F, R>(func: F) -> R
|
||||
where
|
||||
F: Fn(&mut Self) -> R,
|
||||
{
|
||||
BOOL_EVALUATOR.with_borrow_mut(|s| func(s))
|
||||
BOOL_EVALUATOR.with_borrow_mut(|s| func(s.as_mut().expect("Parameters not set")))
|
||||
}
|
||||
|
||||
fn with_local_mut_mut<F, R>(func: &mut F) -> R
|
||||
where
|
||||
F: FnMut(&mut Self) -> R,
|
||||
{
|
||||
BOOL_EVALUATOR.with_borrow_mut(|s| func(s))
|
||||
BOOL_EVALUATOR.with_borrow_mut(|s| func(s.as_mut().expect("Parameters not set")))
|
||||
}
|
||||
}
|
||||
|
||||
159
src/bool/noise.rs
Normal file
159
src/bool/noise.rs
Normal file
@@ -0,0 +1,159 @@
|
||||
use std::cell::RefCell;
|
||||
|
||||
mod test {
|
||||
use itertools::{izip, Itertools};
|
||||
|
||||
use crate::{
|
||||
backend::{ArithmeticOps, ModularOpsU64, Modulus},
|
||||
bool::{
|
||||
set_parameter_set, BoolEncoding, BoolEvaluator, BooleanGates, CiphertextModulus,
|
||||
ClientKey, PublicKey, ServerKeyEvaluationDomain, MP_BOOL_PARAMS, SMALL_MP_BOOL_PARAMS,
|
||||
},
|
||||
lwe::{decrypt_lwe, LweSecret},
|
||||
ntt::NttBackendU64,
|
||||
pbs::PbsInfo,
|
||||
random::DefaultSecureRng,
|
||||
rgsw::RlweSecret,
|
||||
utils::Stats,
|
||||
Secret,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn mp_noise() {
|
||||
// set_parameter_set(&SMALL_MP_BOOL_PARAMS);
|
||||
let mut evaluator = BoolEvaluator::<
|
||||
Vec<Vec<u64>>,
|
||||
NttBackendU64,
|
||||
ModularOpsU64<CiphertextModulus<u64>>,
|
||||
ModularOpsU64<CiphertextModulus<u64>>,
|
||||
>::new(SMALL_MP_BOOL_PARAMS);
|
||||
|
||||
let parties = 16;
|
||||
|
||||
let mut rng = DefaultSecureRng::new();
|
||||
let mut pk_cr_seed = [0u8; 32];
|
||||
let mut bk_cr_seed = [0u8; 32];
|
||||
rng.fill_bytes(&mut pk_cr_seed);
|
||||
rng.fill_bytes(&mut bk_cr_seed);
|
||||
|
||||
let cks = (0..parties)
|
||||
.into_iter()
|
||||
.map(|_| evaluator.client_key())
|
||||
.collect_vec();
|
||||
|
||||
// construct ideal rlwe sk for meauring noise
|
||||
let ideal_client_key = {
|
||||
let mut ideal_rlwe_sk = vec![0i32; evaluator.parameters().rlwe_n().0];
|
||||
cks.iter().for_each(|k| {
|
||||
izip!(ideal_rlwe_sk.iter_mut(), k.sk_rlwe().values()).for_each(|(ideal_i, s_i)| {
|
||||
*ideal_i = *ideal_i + s_i;
|
||||
});
|
||||
});
|
||||
let mut ideal_lwe_sk = vec![0i32; evaluator.parameters().lwe_n().0];
|
||||
cks.iter().for_each(|k| {
|
||||
izip!(ideal_lwe_sk.iter_mut(), k.sk_lwe().values()).for_each(|(ideal_i, s_i)| {
|
||||
*ideal_i = *ideal_i + s_i;
|
||||
});
|
||||
});
|
||||
|
||||
ClientKey::new(
|
||||
RlweSecret {
|
||||
values: ideal_rlwe_sk,
|
||||
},
|
||||
LweSecret {
|
||||
values: ideal_lwe_sk,
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
// round 1
|
||||
let pk_shares = cks
|
||||
.iter()
|
||||
.map(|c| evaluator.multi_party_public_key_share(pk_cr_seed, c))
|
||||
.collect_vec();
|
||||
|
||||
// public key
|
||||
let pk = PublicKey::<Vec<Vec<u64>>, DefaultSecureRng, ModularOpsU64<CiphertextModulus<u64>>>::from(
|
||||
pk_shares.as_slice(),
|
||||
);
|
||||
|
||||
// round 2
|
||||
let server_key_shares = cks
|
||||
.iter()
|
||||
.map(|c| evaluator.multi_party_server_key_share(bk_cr_seed, &pk.key(), c))
|
||||
.collect_vec();
|
||||
|
||||
let server_key = evaluator.aggregate_multi_party_server_key_shares(&server_key_shares);
|
||||
let server_key_eval_domain = ServerKeyEvaluationDomain::from(&server_key);
|
||||
|
||||
let mut m0 = false;
|
||||
let mut m1 = true;
|
||||
|
||||
let mut c_m0 = evaluator.pk_encrypt(pk.key(), m0);
|
||||
let mut c_m1 = evaluator.pk_encrypt(pk.key(), m1);
|
||||
|
||||
// println!(
|
||||
// "Evaluator ciphertext modulus: {:?}",
|
||||
// evaluator.parameters().rlwe_q()
|
||||
// );
|
||||
|
||||
// {
|
||||
// // let v = LWE_VEC.take();
|
||||
// let added = decrypt_lwe(
|
||||
// &c_m1,
|
||||
// ideal_client_key.sk_rlwe().values(),
|
||||
// evaluator.pbs_info().modop_rlweq(),
|
||||
// );
|
||||
// println!("Of interest {added}");
|
||||
// }
|
||||
|
||||
let true_el_encoded = evaluator.parameters().rlwe_q().true_el();
|
||||
let false_el_encoded = evaluator.parameters().rlwe_q().false_el();
|
||||
|
||||
let mut stats = Stats::new();
|
||||
|
||||
for _ in 0..1000 {
|
||||
let c_out = evaluator.xor(&c_m0, &c_m1, &server_key_eval_domain);
|
||||
|
||||
// mp decrypt
|
||||
let decryption_shares = cks
|
||||
.iter()
|
||||
.map(|c| evaluator.multi_party_decryption_share(&c_out, c))
|
||||
.collect_vec();
|
||||
let m_out = evaluator.multi_party_decrypt(&decryption_shares, &c_out);
|
||||
let m_expected = (m0 ^ m1);
|
||||
assert_eq!(m_expected, m_out, "Expected {m_expected} but got {m_out}");
|
||||
|
||||
// find noise update
|
||||
{
|
||||
let out = decrypt_lwe(
|
||||
&c_out,
|
||||
ideal_client_key.sk_rlwe().values(),
|
||||
evaluator.pbs_info().modop_rlweq(),
|
||||
);
|
||||
|
||||
let out_want = {
|
||||
if m_expected == true {
|
||||
true_el_encoded
|
||||
} else {
|
||||
false_el_encoded
|
||||
}
|
||||
};
|
||||
let diff = evaluator.pbs_info().modop_rlweq().sub(&out, &out_want);
|
||||
|
||||
stats.add_more(&vec![evaluator
|
||||
.pbs_info()
|
||||
.rlwe_q()
|
||||
.map_element_to_i64(&diff)]);
|
||||
}
|
||||
|
||||
m1 = m0;
|
||||
m0 = m_out;
|
||||
|
||||
c_m1 = c_m0;
|
||||
c_m0 = c_out;
|
||||
}
|
||||
|
||||
println!("log2 std dev {}", stats.std_dev().abs().log2());
|
||||
}
|
||||
}
|
||||
@@ -177,7 +177,7 @@ impl AsRef<usize> for DecompositionCount {
|
||||
pub(crate) struct LweDimension(pub(crate) usize);
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub(crate) struct PolynomialSize(pub(crate) usize);
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
|
||||
/// T equals modulus when modulus is non-native. Otherwise T equals 0. bool is
|
||||
/// true when modulus is native, false otherwise.
|
||||
@@ -328,38 +328,20 @@ pub(crate) const MP_BOOL_PARAMS: BoolParameters<u64> = BoolParameters::<u64> {
|
||||
w: 10,
|
||||
};
|
||||
|
||||
// pub(crate) const SMALL_MP_BOOL_PARAMS: BoolParameters<u64> =
|
||||
// BoolParameters::<u64> { rlwe_q:
|
||||
// CiphertextModulus::new_non_native(36028797018820609), lwe_q:
|
||||
// CiphertextModulus::new_non_native(1 << 20), br_q: 1 << 11,
|
||||
// rlwe_n: PolynomialSize(1 << 11),
|
||||
// lwe_n: LweDimension(600),
|
||||
// lwe_decomposer_base: DecompostionLogBase(4),
|
||||
// lwe_decomposer_count: DecompositionCount(5),
|
||||
// rlrg_decomposer_base: DecompostionLogBase(11),
|
||||
// rlrg_decomposer_count: (DecompositionCount(2), DecompositionCount(2)),
|
||||
// rgrg_decomposer_base: DecompostionLogBase(11),
|
||||
// rgrg_decomposer_count: (DecompositionCount(5), DecompositionCount(4)),
|
||||
// auto_decomposer_base: DecompostionLogBase(11),
|
||||
// auto_decomposer_count: DecompositionCount(2),
|
||||
// g: 5,
|
||||
// w: 10,
|
||||
// };
|
||||
|
||||
pub(crate) const SMALL_MP_BOOL_PARAMS: BoolParameters<u64> = BoolParameters::<u64> {
|
||||
rlwe_q: CiphertextModulus::new_non_native(36028797018820609),
|
||||
lwe_q: CiphertextModulus::new_non_native(1 << 20),
|
||||
br_q: 1 << 11,
|
||||
rlwe_n: PolynomialSize(1 << 11),
|
||||
lwe_n: LweDimension(500),
|
||||
lwe_n: LweDimension(600),
|
||||
lwe_decomposer_base: DecompostionLogBase(4),
|
||||
lwe_decomposer_count: DecompositionCount(5),
|
||||
rlrg_decomposer_base: DecompostionLogBase(11),
|
||||
rlrg_decomposer_count: (DecompositionCount(5), DecompositionCount(5)),
|
||||
rlrg_decomposer_count: (DecompositionCount(2), DecompositionCount(2)),
|
||||
rgrg_decomposer_base: DecompostionLogBase(11),
|
||||
rgrg_decomposer_count: (DecompositionCount(5), DecompositionCount(5)),
|
||||
rgrg_decomposer_count: (DecompositionCount(5), DecompositionCount(4)),
|
||||
auto_decomposer_base: DecompostionLogBase(11),
|
||||
auto_decomposer_count: DecompositionCount(5),
|
||||
auto_decomposer_count: DecompositionCount(2),
|
||||
g: 5,
|
||||
w: 10,
|
||||
};
|
||||
|
||||
@@ -107,19 +107,19 @@ where
|
||||
|
||||
impl<T, C> RandomFillGaussianInModulus<[T], C> for DefaultSecureRng
|
||||
where
|
||||
T: PrimInt + SampleUniform,
|
||||
T: PrimInt,
|
||||
C: Modulus<Element = T>,
|
||||
{
|
||||
fn random_fill(&mut self, modulus: &C, container: &mut [T]) {
|
||||
// izip!(
|
||||
// rand_distr::Normal::new(0.0, 3.19f64)
|
||||
// .unwrap()
|
||||
// .sample_iter(&mut self.rng),
|
||||
// container.iter_mut()
|
||||
// )
|
||||
// .for_each(|(from, to)| {
|
||||
// *to = modulus.map_element_from_f64(from);
|
||||
// });
|
||||
izip!(
|
||||
rand_distr::Normal::new(0.0, 3.19f64)
|
||||
.unwrap()
|
||||
.sample_iter(&mut self.rng),
|
||||
container.iter_mut()
|
||||
)
|
||||
.for_each(|(from, to)| {
|
||||
*to = modulus.map_element_from_f64(from);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,12 +173,11 @@ where
|
||||
|
||||
impl<T, M: Modulus<Element = T>> RandomGaussianElementInModulus<T, M> for DefaultSecureRng {
|
||||
fn random(&mut self, modulus: &M) -> T {
|
||||
// modulus.map_element_from_f64(
|
||||
// rand_distr::Normal::new(0.0, 3.19f64)
|
||||
// .unwrap()
|
||||
// .sample(&mut self.rng),
|
||||
// )
|
||||
modulus.map_element_from_f64(0.0)
|
||||
modulus.map_element_from_f64(
|
||||
rand_distr::Normal::new(0.0, 3.19f64)
|
||||
.unwrap()
|
||||
.sample(&mut self.rng),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1906,13 +1906,13 @@ pub(crate) mod tests {
|
||||
|
||||
#[test]
|
||||
fn galois_auto_works() {
|
||||
let logq = 50;
|
||||
let ring_size = 1 << 8;
|
||||
let logq = 55;
|
||||
let ring_size = 1 << 11;
|
||||
let q = generate_prime(logq, 2 * ring_size, 1u64 << logq).unwrap();
|
||||
let logp = 3;
|
||||
let p = 1u64 << logp;
|
||||
let d_rgsw = 10;
|
||||
let logb = 5;
|
||||
let d_rgsw = 5;
|
||||
let logb = 11;
|
||||
|
||||
let mut rng = DefaultSecureRng::new();
|
||||
let s = RlweSecret::random((ring_size >> 1) as usize, ring_size as usize);
|
||||
|
||||
Reference in New Issue
Block a user