mirror of
https://github.com/arnaucube/phantom-zone.git
synced 2026-01-09 15:41:30 +01:00
change LWE secret distribution to Error distribution for all parameters
This commit is contained in:
@@ -54,7 +54,8 @@ pub struct ClientKey<S, E> {
|
||||
|
||||
mod impl_ck {
|
||||
use crate::{
|
||||
random::DefaultSecureRng,
|
||||
parameters::SecretKeyDistribution,
|
||||
random::{DefaultSecureRng, RandomFillGaussian},
|
||||
utils::{fill_random_ternary_secret_with_hamming_weight, puncture_p_rng},
|
||||
};
|
||||
|
||||
@@ -76,15 +77,29 @@ mod impl_ck {
|
||||
let lwe_seed = puncture_p_rng::<[u8; 32], DefaultSecureRng>(&mut p_rng, 2);
|
||||
|
||||
let mut lwe_prng = DefaultSecureRng::new_seeded(lwe_seed);
|
||||
|
||||
let mut out = vec![0i32; self.parameters.lwe_n().0];
|
||||
|
||||
match self.parameters.lwe_secret_key_dist() {
|
||||
&SecretKeyDistribution::ErrorDistribution => {
|
||||
RandomFillGaussian::random_fill(&mut lwe_prng, &mut out);
|
||||
}
|
||||
&SecretKeyDistribution::TernaryDistribution => {
|
||||
fill_random_ternary_secret_with_hamming_weight(
|
||||
&mut out,
|
||||
self.parameters.lwe_n().0 >> 1,
|
||||
&mut lwe_prng,
|
||||
);
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
fn sk_rlwe(&self) -> Vec<Self::Element> {
|
||||
assert!(
|
||||
self.parameters.rlwe_secret_key_dist()
|
||||
== &SecretKeyDistribution::TernaryDistribution
|
||||
);
|
||||
|
||||
let mut p_rng = DefaultSecureRng::new_seeded(self.seed);
|
||||
let rlwe_seed = puncture_p_rng::<[u8; 32], DefaultSecureRng>(&mut p_rng, 1);
|
||||
|
||||
@@ -120,6 +135,11 @@ mod impl_ck {
|
||||
<Self as SinglePartyClientKey>::sk_rlwe(&self)
|
||||
}
|
||||
fn sk_u_rlwe(&self) -> Vec<Self::Element> {
|
||||
assert!(
|
||||
self.parameters.rlwe_secret_key_dist()
|
||||
== &SecretKeyDistribution::TernaryDistribution
|
||||
);
|
||||
|
||||
let mut p_rng = DefaultSecureRng::new_seeded(self.seed);
|
||||
let rlwe_seed = puncture_p_rng::<[u8; 32], DefaultSecureRng>(&mut p_rng, 3);
|
||||
|
||||
@@ -1486,7 +1506,7 @@ pub(super) mod tests {
|
||||
bool::ClientKey,
|
||||
decomposer::NumInfo,
|
||||
lwe::decrypt_lwe,
|
||||
parameters::CiphertextModulus,
|
||||
parameters::{CiphertextModulus, I_2P},
|
||||
utils::TryConvertFrom1,
|
||||
ArithmeticOps, Row,
|
||||
};
|
||||
@@ -1540,4 +1560,11 @@ pub(super) mod tests {
|
||||
.unwrap()
|
||||
.log2()
|
||||
}
|
||||
// #[test]
|
||||
// fn trial() {
|
||||
// let parameters = I_2P;
|
||||
// let ck = ClientKey::new(parameters);
|
||||
// let lwe = ck.sk_lwe();
|
||||
// dbg!(lwe);
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -447,23 +447,26 @@ mod tests {
|
||||
use rand::{thread_rng, RngCore};
|
||||
|
||||
use crate::{
|
||||
backend::Modulus,
|
||||
bool::{
|
||||
keys::tests::{ideal_sk_rlwe, measure_noise_lwe},
|
||||
BooleanGates,
|
||||
},
|
||||
Encoder, Encryptor, KeySwitchWithId, MultiPartyDecryptor,
|
||||
lwe::decrypt_lwe,
|
||||
utils::tests::Stats,
|
||||
ArithmeticOps, Encoder, Encryptor, KeySwitchWithId, MultiPartyDecryptor,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn non_interactive_mp_bool_nand() {
|
||||
set_parameter_set(ParameterSelector::NonInteractiveLTE4Party);
|
||||
set_parameter_set(ParameterSelector::NonInteractiveLTE2Party);
|
||||
let mut seed = [0u8; 32];
|
||||
thread_rng().fill_bytes(&mut seed);
|
||||
set_common_reference_seed(seed);
|
||||
|
||||
let parties = 3;
|
||||
let parties = 2;
|
||||
|
||||
let cks = (0..parties).map(|_| gen_client_key()).collect_vec();
|
||||
|
||||
@@ -495,6 +498,8 @@ mod tests {
|
||||
ct.extract(0)
|
||||
};
|
||||
|
||||
let mut stats = Stats::new();
|
||||
|
||||
for _ in 0..1000 {
|
||||
// let now = std::time::Instant::now();
|
||||
let ct_out =
|
||||
@@ -510,13 +515,17 @@ mod tests {
|
||||
let m_expected = m0 ^ m1;
|
||||
|
||||
{
|
||||
let noise = measure_noise_lwe(
|
||||
&ct_out,
|
||||
parameters.rlwe_q().encode(m_expected),
|
||||
&ideal_sk_rlwe,
|
||||
&rlwe_modop,
|
||||
);
|
||||
println!("Noise: {noise}");
|
||||
// let noise = measure_noise_lwe(
|
||||
// &ct_out,
|
||||
// parameters.rlwe_q().encode(m_expected),
|
||||
// &ideal_sk_rlwe,
|
||||
// &rlwe_modop,
|
||||
// );
|
||||
// println!("Noise: {noise}");
|
||||
|
||||
let noisy_m = decrypt_lwe(&ct_out, &ideal_sk_rlwe, &rlwe_modop);
|
||||
let noise = rlwe_modop.sub(¶meters.rlwe_q().encode(m_expected), &noisy_m);
|
||||
stats.add_more(&vec![parameters.rlwe_q().map_element_to_i64(&noise)]);
|
||||
}
|
||||
|
||||
assert!(m_out == m_expected, "Expected {m_expected} but got {m_out}");
|
||||
@@ -527,5 +536,7 @@ mod tests {
|
||||
ct1 = ct0;
|
||||
ct0 = ct_out;
|
||||
}
|
||||
|
||||
println!("Noise std dev log2: {}", stats.std_dev().abs().log2());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,16 @@ impl SingleDecomposerParams for (DecompostionLogBase, DecompositionCount) {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub(crate) enum SecretKeyDistribution {
|
||||
/// Elements of secret key are sample from Gaussian distribitution with
|
||||
/// \sigma = 3.19 and \mu = 0.0
|
||||
ErrorDistribution,
|
||||
/// Elements of secret key are chosen from the set {1,0,-1} with hamming
|
||||
/// weight `floor(N/2)` where `N` is the secret dimension.
|
||||
TernaryDistribution,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub(crate) enum ParameterVariant {
|
||||
SingleParty,
|
||||
@@ -86,6 +96,10 @@ pub(crate) enum ParameterVariant {
|
||||
}
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct BoolParameters<El> {
|
||||
/// RLWE secret key distribution
|
||||
rlwe_secret_key_dist: SecretKeyDistribution,
|
||||
/// LWE secret key distribtuion
|
||||
lwe_secret_key_dist: SecretKeyDistribution,
|
||||
/// RLWE ciphertext modulus Q
|
||||
rlwe_q: CiphertextModulus<El>,
|
||||
/// LWE ciphertext modulus q (usually referred to as Q_{ks})
|
||||
@@ -153,6 +167,14 @@ pub struct BoolParameters<El> {
|
||||
}
|
||||
|
||||
impl<El> BoolParameters<El> {
|
||||
pub(crate) fn rlwe_secret_key_dist(&self) -> &SecretKeyDistribution {
|
||||
&self.rlwe_secret_key_dist
|
||||
}
|
||||
|
||||
pub(crate) fn lwe_secret_key_dist(&self) -> &SecretKeyDistribution {
|
||||
&self.lwe_secret_key_dist
|
||||
}
|
||||
|
||||
pub(crate) fn rlwe_q(&self) -> &CiphertextModulus<El> {
|
||||
&self.rlwe_q
|
||||
}
|
||||
@@ -502,6 +524,8 @@ where
|
||||
}
|
||||
|
||||
pub(crate) const MP_BOOL_PARAMS: BoolParameters<u64> = BoolParameters::<u64> {
|
||||
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||
lwe_secret_key_dist: SecretKeyDistribution::ErrorDistribution,
|
||||
rlwe_q: CiphertextModulus::new_non_native(1152921504606830593),
|
||||
lwe_q: CiphertextModulus::new_non_native(1 << 20),
|
||||
br_q: 1 << 11,
|
||||
@@ -524,6 +548,8 @@ pub(crate) const MP_BOOL_PARAMS: BoolParameters<u64> = BoolParameters::<u64> {
|
||||
};
|
||||
|
||||
pub(crate) const SMALL_MP_BOOL_PARAMS: BoolParameters<u64> = BoolParameters::<u64> {
|
||||
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||
lwe_secret_key_dist: SecretKeyDistribution::ErrorDistribution,
|
||||
rlwe_q: CiphertextModulus::new_non_native(36028797018820609),
|
||||
lwe_q: CiphertextModulus::new_non_native(1 << 20),
|
||||
br_q: 1 << 11,
|
||||
@@ -546,6 +572,8 @@ pub(crate) const SMALL_MP_BOOL_PARAMS: BoolParameters<u64> = BoolParameters::<u6
|
||||
};
|
||||
|
||||
pub(crate) const I_2P: BoolParameters<u64> = BoolParameters::<u64> {
|
||||
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||
lwe_secret_key_dist: SecretKeyDistribution::ErrorDistribution,
|
||||
rlwe_q: CiphertextModulus::new_non_native(18014398509404161),
|
||||
lwe_q: CiphertextModulus::new_non_native(1 << 15),
|
||||
br_q: 1 << 11,
|
||||
@@ -568,6 +596,8 @@ pub(crate) const I_2P: BoolParameters<u64> = BoolParameters::<u64> {
|
||||
};
|
||||
|
||||
pub(crate) const NI_2P: BoolParameters<u64> = BoolParameters::<u64> {
|
||||
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||
lwe_secret_key_dist: SecretKeyDistribution::ErrorDistribution,
|
||||
rlwe_q: CiphertextModulus::new_non_native(18014398509404161),
|
||||
lwe_q: CiphertextModulus::new_non_native(1 << 15),
|
||||
br_q: 1 << 11,
|
||||
@@ -593,6 +623,8 @@ pub(crate) const NI_2P: BoolParameters<u64> = BoolParameters::<u64> {
|
||||
};
|
||||
|
||||
pub(crate) const NI_4P: BoolParameters<u64> = BoolParameters::<u64> {
|
||||
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||
lwe_secret_key_dist: SecretKeyDistribution::ErrorDistribution,
|
||||
rlwe_q: CiphertextModulus::new_non_native(18014398509404161),
|
||||
lwe_q: CiphertextModulus::new_non_native(1 << 16),
|
||||
br_q: 1 << 11,
|
||||
@@ -619,6 +651,8 @@ pub(crate) const NI_4P: BoolParameters<u64> = BoolParameters::<u64> {
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) const SP_TEST_BOOL_PARAMS: BoolParameters<u64> = BoolParameters::<u64> {
|
||||
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||
lwe_secret_key_dist: SecretKeyDistribution::ErrorDistribution,
|
||||
rlwe_q: CiphertextModulus::new_non_native(268369921u64),
|
||||
lwe_q: CiphertextModulus::new_non_native(1 << 16),
|
||||
br_q: 1 << 9,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::cell::RefCell;
|
||||
|
||||
use itertools::izip;
|
||||
use num_traits::{PrimInt, Zero};
|
||||
use num_traits::{FromPrimitive, PrimInt, Zero};
|
||||
use rand::{distributions::Uniform, Rng, RngCore, SeedableRng};
|
||||
use rand_chacha::ChaCha8Rng;
|
||||
use rand_distr::{uniform::SampleUniform, Distribution};
|
||||
@@ -36,6 +36,15 @@ where
|
||||
fn random_fill(&mut self, container: &mut M);
|
||||
}
|
||||
|
||||
pub trait RandomFillGaussian<M>
|
||||
where
|
||||
M: ?Sized,
|
||||
{
|
||||
/// Fill container with random elements sampled from normal distribtuion
|
||||
/// with \mu = 0.0 and \sigma = 3.19.
|
||||
fn random_fill(&mut self, container: &mut M);
|
||||
}
|
||||
|
||||
pub trait RandomFillUniformInModulus<M, P>
|
||||
where
|
||||
M: ?Sized,
|
||||
@@ -133,6 +142,23 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> RandomFillGaussian<[T]> for DefaultSecureRng
|
||||
where
|
||||
T: FromPrimitive,
|
||||
{
|
||||
fn random_fill(&mut self, 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 = T::from_f64(from).unwrap();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> RandomFill<[T; 32]> for DefaultSecureRng
|
||||
where
|
||||
T: PrimInt + SampleUniform,
|
||||
|
||||
Reference in New Issue
Block a user