mirror of
https://github.com/arnaucube/phantom-zone.git
synced 2026-01-09 23:51: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 {
|
mod impl_ck {
|
||||||
use crate::{
|
use crate::{
|
||||||
random::DefaultSecureRng,
|
parameters::SecretKeyDistribution,
|
||||||
|
random::{DefaultSecureRng, RandomFillGaussian},
|
||||||
utils::{fill_random_ternary_secret_with_hamming_weight, puncture_p_rng},
|
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 lwe_seed = puncture_p_rng::<[u8; 32], DefaultSecureRng>(&mut p_rng, 2);
|
||||||
|
|
||||||
let mut lwe_prng = DefaultSecureRng::new_seeded(lwe_seed);
|
let mut lwe_prng = DefaultSecureRng::new_seeded(lwe_seed);
|
||||||
|
|
||||||
let mut out = vec![0i32; self.parameters.lwe_n().0];
|
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(
|
fill_random_ternary_secret_with_hamming_weight(
|
||||||
&mut out,
|
&mut out,
|
||||||
self.parameters.lwe_n().0 >> 1,
|
self.parameters.lwe_n().0 >> 1,
|
||||||
&mut lwe_prng,
|
&mut lwe_prng,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
fn sk_rlwe(&self) -> Vec<Self::Element> {
|
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 mut p_rng = DefaultSecureRng::new_seeded(self.seed);
|
||||||
let rlwe_seed = puncture_p_rng::<[u8; 32], DefaultSecureRng>(&mut p_rng, 1);
|
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)
|
<Self as SinglePartyClientKey>::sk_rlwe(&self)
|
||||||
}
|
}
|
||||||
fn sk_u_rlwe(&self) -> Vec<Self::Element> {
|
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 mut p_rng = DefaultSecureRng::new_seeded(self.seed);
|
||||||
let rlwe_seed = puncture_p_rng::<[u8; 32], DefaultSecureRng>(&mut p_rng, 3);
|
let rlwe_seed = puncture_p_rng::<[u8; 32], DefaultSecureRng>(&mut p_rng, 3);
|
||||||
|
|
||||||
@@ -1486,7 +1506,7 @@ pub(super) mod tests {
|
|||||||
bool::ClientKey,
|
bool::ClientKey,
|
||||||
decomposer::NumInfo,
|
decomposer::NumInfo,
|
||||||
lwe::decrypt_lwe,
|
lwe::decrypt_lwe,
|
||||||
parameters::CiphertextModulus,
|
parameters::{CiphertextModulus, I_2P},
|
||||||
utils::TryConvertFrom1,
|
utils::TryConvertFrom1,
|
||||||
ArithmeticOps, Row,
|
ArithmeticOps, Row,
|
||||||
};
|
};
|
||||||
@@ -1540,4 +1560,11 @@ pub(super) mod tests {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.log2()
|
.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 rand::{thread_rng, RngCore};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
backend::Modulus,
|
||||||
bool::{
|
bool::{
|
||||||
keys::tests::{ideal_sk_rlwe, measure_noise_lwe},
|
keys::tests::{ideal_sk_rlwe, measure_noise_lwe},
|
||||||
BooleanGates,
|
BooleanGates,
|
||||||
},
|
},
|
||||||
Encoder, Encryptor, KeySwitchWithId, MultiPartyDecryptor,
|
lwe::decrypt_lwe,
|
||||||
|
utils::tests::Stats,
|
||||||
|
ArithmeticOps, Encoder, Encryptor, KeySwitchWithId, MultiPartyDecryptor,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn non_interactive_mp_bool_nand() {
|
fn non_interactive_mp_bool_nand() {
|
||||||
set_parameter_set(ParameterSelector::NonInteractiveLTE4Party);
|
set_parameter_set(ParameterSelector::NonInteractiveLTE2Party);
|
||||||
let mut seed = [0u8; 32];
|
let mut seed = [0u8; 32];
|
||||||
thread_rng().fill_bytes(&mut seed);
|
thread_rng().fill_bytes(&mut seed);
|
||||||
set_common_reference_seed(seed);
|
set_common_reference_seed(seed);
|
||||||
|
|
||||||
let parties = 3;
|
let parties = 2;
|
||||||
|
|
||||||
let cks = (0..parties).map(|_| gen_client_key()).collect_vec();
|
let cks = (0..parties).map(|_| gen_client_key()).collect_vec();
|
||||||
|
|
||||||
@@ -495,6 +498,8 @@ mod tests {
|
|||||||
ct.extract(0)
|
ct.extract(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut stats = Stats::new();
|
||||||
|
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
// let now = std::time::Instant::now();
|
// let now = std::time::Instant::now();
|
||||||
let ct_out =
|
let ct_out =
|
||||||
@@ -510,13 +515,17 @@ mod tests {
|
|||||||
let m_expected = m0 ^ m1;
|
let m_expected = m0 ^ m1;
|
||||||
|
|
||||||
{
|
{
|
||||||
let noise = measure_noise_lwe(
|
// let noise = measure_noise_lwe(
|
||||||
&ct_out,
|
// &ct_out,
|
||||||
parameters.rlwe_q().encode(m_expected),
|
// parameters.rlwe_q().encode(m_expected),
|
||||||
&ideal_sk_rlwe,
|
// &ideal_sk_rlwe,
|
||||||
&rlwe_modop,
|
// &rlwe_modop,
|
||||||
);
|
// );
|
||||||
println!("Noise: {noise}");
|
// 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}");
|
assert!(m_out == m_expected, "Expected {m_expected} but got {m_out}");
|
||||||
@@ -527,5 +536,7 @@ mod tests {
|
|||||||
ct1 = ct0;
|
ct1 = ct0;
|
||||||
ct0 = ct_out;
|
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)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub(crate) enum ParameterVariant {
|
pub(crate) enum ParameterVariant {
|
||||||
SingleParty,
|
SingleParty,
|
||||||
@@ -86,6 +96,10 @@ pub(crate) enum ParameterVariant {
|
|||||||
}
|
}
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct BoolParameters<El> {
|
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 ciphertext modulus Q
|
||||||
rlwe_q: CiphertextModulus<El>,
|
rlwe_q: CiphertextModulus<El>,
|
||||||
/// LWE ciphertext modulus q (usually referred to as Q_{ks})
|
/// LWE ciphertext modulus q (usually referred to as Q_{ks})
|
||||||
@@ -153,6 +167,14 @@ pub struct BoolParameters<El> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<El> 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> {
|
pub(crate) fn rlwe_q(&self) -> &CiphertextModulus<El> {
|
||||||
&self.rlwe_q
|
&self.rlwe_q
|
||||||
}
|
}
|
||||||
@@ -502,6 +524,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) const MP_BOOL_PARAMS: BoolParameters<u64> = BoolParameters::<u64> {
|
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),
|
rlwe_q: CiphertextModulus::new_non_native(1152921504606830593),
|
||||||
lwe_q: CiphertextModulus::new_non_native(1 << 20),
|
lwe_q: CiphertextModulus::new_non_native(1 << 20),
|
||||||
br_q: 1 << 11,
|
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> {
|
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),
|
rlwe_q: CiphertextModulus::new_non_native(36028797018820609),
|
||||||
lwe_q: CiphertextModulus::new_non_native(1 << 20),
|
lwe_q: CiphertextModulus::new_non_native(1 << 20),
|
||||||
br_q: 1 << 11,
|
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> {
|
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),
|
rlwe_q: CiphertextModulus::new_non_native(18014398509404161),
|
||||||
lwe_q: CiphertextModulus::new_non_native(1 << 15),
|
lwe_q: CiphertextModulus::new_non_native(1 << 15),
|
||||||
br_q: 1 << 11,
|
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> {
|
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),
|
rlwe_q: CiphertextModulus::new_non_native(18014398509404161),
|
||||||
lwe_q: CiphertextModulus::new_non_native(1 << 15),
|
lwe_q: CiphertextModulus::new_non_native(1 << 15),
|
||||||
br_q: 1 << 11,
|
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> {
|
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),
|
rlwe_q: CiphertextModulus::new_non_native(18014398509404161),
|
||||||
lwe_q: CiphertextModulus::new_non_native(1 << 16),
|
lwe_q: CiphertextModulus::new_non_native(1 << 16),
|
||||||
br_q: 1 << 11,
|
br_q: 1 << 11,
|
||||||
@@ -619,6 +651,8 @@ pub(crate) const NI_4P: BoolParameters<u64> = BoolParameters::<u64> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) const SP_TEST_BOOL_PARAMS: BoolParameters<u64> = BoolParameters::<u64> {
|
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),
|
rlwe_q: CiphertextModulus::new_non_native(268369921u64),
|
||||||
lwe_q: CiphertextModulus::new_non_native(1 << 16),
|
lwe_q: CiphertextModulus::new_non_native(1 << 16),
|
||||||
br_q: 1 << 9,
|
br_q: 1 << 9,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use itertools::izip;
|
use itertools::izip;
|
||||||
use num_traits::{PrimInt, Zero};
|
use num_traits::{FromPrimitive, PrimInt, Zero};
|
||||||
use rand::{distributions::Uniform, Rng, RngCore, SeedableRng};
|
use rand::{distributions::Uniform, Rng, RngCore, SeedableRng};
|
||||||
use rand_chacha::ChaCha8Rng;
|
use rand_chacha::ChaCha8Rng;
|
||||||
use rand_distr::{uniform::SampleUniform, Distribution};
|
use rand_distr::{uniform::SampleUniform, Distribution};
|
||||||
@@ -36,6 +36,15 @@ where
|
|||||||
fn random_fill(&mut self, container: &mut M);
|
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>
|
pub trait RandomFillUniformInModulus<M, P>
|
||||||
where
|
where
|
||||||
M: ?Sized,
|
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
|
impl<T> RandomFill<[T; 32]> for DefaultSecureRng
|
||||||
where
|
where
|
||||||
T: PrimInt + SampleUniform,
|
T: PrimInt + SampleUniform,
|
||||||
|
|||||||
Reference in New Issue
Block a user