mirror of
https://github.com/arnaucube/phantom-zone.git
synced 2026-01-09 23:51:30 +01:00
add more MP params
This commit is contained in:
@@ -1499,16 +1499,11 @@ pub(crate) mod key_size {
|
|||||||
|
|
||||||
pub(super) mod tests {
|
pub(super) mod tests {
|
||||||
use itertools::izip;
|
use itertools::izip;
|
||||||
use num_traits::{FromPrimitive, PrimInt, ToPrimitive, Zero};
|
use num_traits::{FromPrimitive, PrimInt, Zero};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{GetModulus, Modulus},
|
backend::GetModulus, bool::ClientKey, decomposer::NumInfo, lwe::decrypt_lwe,
|
||||||
bool::ClientKey,
|
parameters::CiphertextModulus, utils::TryConvertFrom1, ArithmeticOps, Row,
|
||||||
decomposer::NumInfo,
|
|
||||||
lwe::decrypt_lwe,
|
|
||||||
parameters::{CiphertextModulus, I_2P},
|
|
||||||
utils::TryConvertFrom1,
|
|
||||||
ArithmeticOps, Row,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::SinglePartyClientKey;
|
use super::SinglePartyClientKey;
|
||||||
@@ -1545,20 +1540,14 @@ pub(super) mod tests {
|
|||||||
m_expected: R::Element,
|
m_expected: R::Element,
|
||||||
sk: &[S],
|
sk: &[S],
|
||||||
modop: &Modop,
|
modop: &Modop,
|
||||||
) -> f64
|
) -> R::Element
|
||||||
where
|
where
|
||||||
R: TryConvertFrom1<[S], CiphertextModulus<R::Element>>,
|
R: TryConvertFrom1<[S], CiphertextModulus<R::Element>>,
|
||||||
R::Element: Zero + FromPrimitive + PrimInt + NumInfo,
|
R::Element: Zero + FromPrimitive + PrimInt + NumInfo,
|
||||||
{
|
{
|
||||||
let noisy_m = decrypt_lwe(lwe_ct, &sk, modop);
|
let noisy_m = decrypt_lwe(lwe_ct, &sk, modop);
|
||||||
let noise = modop.sub(&m_expected, &noisy_m);
|
let noise = modop.sub(&m_expected, &noisy_m);
|
||||||
modop
|
noise
|
||||||
.modulus()
|
|
||||||
.map_element_to_i64(&noise)
|
|
||||||
.abs()
|
|
||||||
.to_f64()
|
|
||||||
.unwrap()
|
|
||||||
.log2()
|
|
||||||
}
|
}
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn trial() {
|
// fn trial() {
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ pub enum ParameterSelector {
|
|||||||
pub fn set_parameter_set(select: ParameterSelector) {
|
pub fn set_parameter_set(select: ParameterSelector) {
|
||||||
match select {
|
match select {
|
||||||
ParameterSelector::InteractiveLTE2Party => {
|
ParameterSelector::InteractiveLTE2Party => {
|
||||||
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(I_2P)));
|
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(I_2P_LB_SR)));
|
||||||
}
|
}
|
||||||
ParameterSelector::InteractiveLTE4Party => {
|
ParameterSelector::InteractiveLTE4Party => {
|
||||||
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(I_4P)));
|
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(I_4P)));
|
||||||
}
|
}
|
||||||
ParameterSelector::InteractiveLTE8Party => {
|
ParameterSelector::InteractiveLTE8Party => {
|
||||||
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(I_8P_LB_SR)));
|
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(I_8P)));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Paramerter not supported")
|
panic!("Paramerter not supported")
|
||||||
@@ -311,24 +311,27 @@ mod tests {
|
|||||||
use rand::{thread_rng, Rng, RngCore};
|
use rand::{thread_rng, Rng, RngCore};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
backend::Modulus,
|
||||||
bool::{
|
bool::{
|
||||||
evaluator::BoolEncoding,
|
evaluator::BoolEncoding,
|
||||||
keys::tests::{ideal_sk_rlwe, measure_noise_lwe},
|
keys::tests::{ideal_sk_rlwe, measure_noise_lwe},
|
||||||
BooleanGates,
|
BooleanGates,
|
||||||
},
|
},
|
||||||
Encryptor, MultiPartyDecryptor, SampleExtractor,
|
lwe::decrypt_lwe,
|
||||||
|
utils::tests::Stats,
|
||||||
|
Encoder, Encryptor, MultiPartyDecryptor, SampleExtractor,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multi_party_bool_gates() {
|
fn multi_party_bool_gates() {
|
||||||
set_parameter_set(ParameterSelector::InteractiveLTE2Party);
|
set_parameter_set(ParameterSelector::InteractiveLTE8Party);
|
||||||
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 = 2;
|
let parties = 8;
|
||||||
let cks = (0..parties).map(|_| gen_client_key()).collect_vec();
|
let cks = (0..parties).map(|_| gen_client_key()).collect_vec();
|
||||||
|
|
||||||
// round 1
|
// round 1
|
||||||
@@ -361,7 +364,9 @@ mod tests {
|
|||||||
let parameters = BoolEvaluator::with_local(|e| e.parameters().clone());
|
let parameters = BoolEvaluator::with_local(|e| e.parameters().clone());
|
||||||
let rlwe_modop = parameters.default_rlwe_modop();
|
let rlwe_modop = parameters.default_rlwe_modop();
|
||||||
|
|
||||||
for _ in 0..500 {
|
let mut stats = Stats::new();
|
||||||
|
|
||||||
|
for _ in 0..1000 {
|
||||||
let now = std::time::Instant::now();
|
let now = std::time::Instant::now();
|
||||||
let ct_out =
|
let ct_out =
|
||||||
BoolEvaluator::with_local_mut(|e| e.nand(&ct0, &ct1, RuntimeServerKey::global()));
|
BoolEvaluator::with_local_mut(|e| e.nand(&ct0, &ct1, RuntimeServerKey::global()));
|
||||||
@@ -376,14 +381,15 @@ mod tests {
|
|||||||
let m_out = cks[0].aggregate_decryption_shares(&ct_out, &decryption_shares);
|
let m_out = cks[0].aggregate_decryption_shares(&ct_out, &decryption_shares);
|
||||||
|
|
||||||
assert!(m_out == m_expected, "Expected {m_expected}, got {m_out}");
|
assert!(m_out == m_expected, "Expected {m_expected}, got {m_out}");
|
||||||
|
|
||||||
{
|
{
|
||||||
let m_expected_el = if m_expected == true {
|
let noise = measure_noise_lwe(
|
||||||
parameters.rlwe_q().true_el()
|
&ct_out,
|
||||||
} else {
|
parameters.rlwe_q().encode(m_expected),
|
||||||
parameters.rlwe_q().false_el()
|
&ideal_sk_rlwe,
|
||||||
};
|
&rlwe_modop,
|
||||||
let noise = measure_noise_lwe(&ct_out, m_expected_el, &ideal_sk_rlwe, &rlwe_modop);
|
);
|
||||||
println!("NAND Noise: {noise}");
|
stats.add_sample(parameters.rlwe_q().map_element_to_i64(&noise));
|
||||||
}
|
}
|
||||||
|
|
||||||
m1 = m0;
|
m1 = m0;
|
||||||
@@ -393,7 +399,7 @@ mod tests {
|
|||||||
ct0 = ct_out;
|
ct0 = ct_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for _ in 0..500 {
|
for _ in 0..1000 {
|
||||||
let ct_out =
|
let ct_out =
|
||||||
BoolEvaluator::with_local_mut(|e| e.xnor(&ct0, &ct1, RuntimeServerKey::global()));
|
BoolEvaluator::with_local_mut(|e| e.xnor(&ct0, &ct1, RuntimeServerKey::global()));
|
||||||
|
|
||||||
@@ -407,12 +413,24 @@ mod tests {
|
|||||||
|
|
||||||
assert!(m_out == m_expected, "Expected {m_expected}, got {m_out}");
|
assert!(m_out == m_expected, "Expected {m_expected}, got {m_out}");
|
||||||
|
|
||||||
|
{
|
||||||
|
let noise = measure_noise_lwe(
|
||||||
|
&ct_out,
|
||||||
|
parameters.rlwe_q().encode(m_expected),
|
||||||
|
&ideal_sk_rlwe,
|
||||||
|
&rlwe_modop,
|
||||||
|
);
|
||||||
|
stats.add_sample(parameters.rlwe_q().map_element_to_i64(&noise));
|
||||||
|
}
|
||||||
|
|
||||||
m1 = m0;
|
m1 = m0;
|
||||||
m0 = m_expected;
|
m0 = m_expected;
|
||||||
|
|
||||||
ct1 = ct0;
|
ct1 = ct0;
|
||||||
ct0 = ct_out;
|
ct0 = ct_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("Noise std_dev log2: {}", stats.std_dev().abs().log2());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use std::{cell::RefCell, sync::OnceLock};
|
|||||||
use crate::{
|
use crate::{
|
||||||
backend::ModulusPowerOf2,
|
backend::ModulusPowerOf2,
|
||||||
bool::parameters::ParameterVariant,
|
bool::parameters::ParameterVariant,
|
||||||
parameters::NI_4P,
|
|
||||||
random::DefaultSecureRng,
|
random::DefaultSecureRng,
|
||||||
utils::{Global, WithLocal},
|
utils::{Global, WithLocal},
|
||||||
ModularOpsU64, NttBackendU64,
|
ModularOpsU64, NttBackendU64,
|
||||||
@@ -16,7 +15,7 @@ use super::{
|
|||||||
NonInteractiveServerKeyEvaluationDomain, SeededNonInteractiveMultiPartyServerKey,
|
NonInteractiveServerKeyEvaluationDomain, SeededNonInteractiveMultiPartyServerKey,
|
||||||
ShoupNonInteractiveServerKeyEvaluationDomain,
|
ShoupNonInteractiveServerKeyEvaluationDomain,
|
||||||
},
|
},
|
||||||
parameters::{BoolParameters, CiphertextModulus, NI_2P},
|
parameters::{BoolParameters, CiphertextModulus, NI_2P, NI_4P_HB_FR, NI_8P},
|
||||||
ClientKey,
|
ClientKey,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,6 +39,7 @@ static MULTI_PARTY_CRS: OnceLock<NonInteractiveMultiPartyCrs<[u8; 32]>> = OnceLo
|
|||||||
pub enum ParameterSelector {
|
pub enum ParameterSelector {
|
||||||
NonInteractiveLTE2Party,
|
NonInteractiveLTE2Party,
|
||||||
NonInteractiveLTE4Party,
|
NonInteractiveLTE4Party,
|
||||||
|
NonInteractiveLTE8Party,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_parameter_set(select: ParameterSelector) {
|
pub fn set_parameter_set(select: ParameterSelector) {
|
||||||
@@ -48,11 +48,10 @@ pub fn set_parameter_set(select: ParameterSelector) {
|
|||||||
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(NI_2P)));
|
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(NI_2P)));
|
||||||
}
|
}
|
||||||
ParameterSelector::NonInteractiveLTE4Party => {
|
ParameterSelector::NonInteractiveLTE4Party => {
|
||||||
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(NI_4P)));
|
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(NI_4P_HB_FR)));
|
||||||
}
|
}
|
||||||
|
ParameterSelector::NonInteractiveLTE8Party => {
|
||||||
_ => {
|
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(NI_8P)));
|
||||||
panic!("Paramerters not supported")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -461,12 +460,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn non_interactive_mp_bool_nand() {
|
fn non_interactive_mp_bool_nand() {
|
||||||
set_parameter_set(ParameterSelector::NonInteractiveLTE2Party);
|
set_parameter_set(ParameterSelector::NonInteractiveLTE8Party);
|
||||||
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 = 2;
|
let parties = 8;
|
||||||
|
|
||||||
let cks = (0..parties).map(|_| gen_client_key()).collect_vec();
|
let cks = (0..parties).map(|_| gen_client_key()).collect_vec();
|
||||||
|
|
||||||
@@ -501,10 +500,10 @@ mod tests {
|
|||||||
let mut stats = Stats::new();
|
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 =
|
||||||
BoolEvaluator::with_local_mut(|e| e.xor(&ct0, &ct1, RuntimeServerKey::global()));
|
BoolEvaluator::with_local_mut(|e| e.xor(&ct0, &ct1, RuntimeServerKey::global()));
|
||||||
// println!("Time: {:?}", now.elapsed());
|
println!("Time: {:?}", now.elapsed());
|
||||||
|
|
||||||
let decryption_shares = cks
|
let decryption_shares = cks
|
||||||
.iter()
|
.iter()
|
||||||
@@ -515,17 +514,13 @@ 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}");
|
stats.add_sample(parameters.rlwe_q().map_element_to_i64(&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}");
|
||||||
|
|||||||
@@ -523,62 +523,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) const MP_BOOL_PARAMS: BoolParameters<u64> = BoolParameters::<u64> {
|
pub(crate) const I_2P_LB_SR: BoolParameters<u64> = BoolParameters::<u64> {
|
||||||
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
lwe_secret_key_dist: SecretKeyDistribution::ErrorDistribution,
|
lwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
rlwe_q: CiphertextModulus::new_non_native(1152921504606830593),
|
|
||||||
lwe_q: CiphertextModulus::new_non_native(1 << 20),
|
|
||||||
br_q: 1 << 11,
|
|
||||||
rlwe_n: PolynomialSize(1 << 11),
|
|
||||||
lwe_n: LweDimension(500),
|
|
||||||
lwe_decomposer_params: (DecompostionLogBase(4), DecompositionCount(5)),
|
|
||||||
rlrg_decomposer_params: (
|
|
||||||
DecompostionLogBase(12),
|
|
||||||
(DecompositionCount(5), DecompositionCount(5)),
|
|
||||||
),
|
|
||||||
rgrg_decomposer_params: Some((
|
|
||||||
DecompostionLogBase(12),
|
|
||||||
(DecompositionCount(5), DecompositionCount(5)),
|
|
||||||
)),
|
|
||||||
auto_decomposer_params: (DecompostionLogBase(12), DecompositionCount(5)),
|
|
||||||
non_interactive_ui_to_s_key_switch_decomposer: None,
|
|
||||||
g: 5,
|
|
||||||
w: 10,
|
|
||||||
variant: ParameterVariant::InteractiveMultiParty,
|
|
||||||
};
|
|
||||||
|
|
||||||
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,
|
|
||||||
rlwe_n: PolynomialSize(1 << 11),
|
|
||||||
lwe_n: LweDimension(600),
|
|
||||||
lwe_decomposer_params: (DecompostionLogBase(4), DecompositionCount(5)),
|
|
||||||
rlrg_decomposer_params: (
|
|
||||||
DecompostionLogBase(11),
|
|
||||||
(DecompositionCount(2), DecompositionCount(1)),
|
|
||||||
),
|
|
||||||
rgrg_decomposer_params: Some((
|
|
||||||
DecompostionLogBase(11),
|
|
||||||
(DecompositionCount(5), DecompositionCount(4)),
|
|
||||||
)),
|
|
||||||
auto_decomposer_params: (DecompostionLogBase(11), DecompositionCount(2)),
|
|
||||||
non_interactive_ui_to_s_key_switch_decomposer: None,
|
|
||||||
g: 5,
|
|
||||||
w: 10,
|
|
||||||
variant: ParameterVariant::InteractiveMultiParty,
|
|
||||||
};
|
|
||||||
|
|
||||||
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,
|
||||||
rlwe_n: PolynomialSize(1 << 11),
|
rlwe_n: PolynomialSize(1 << 11),
|
||||||
lwe_n: LweDimension(480),
|
lwe_n: LweDimension(580),
|
||||||
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(12)),
|
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(12)),
|
||||||
rlrg_decomposer_params: (
|
rlrg_decomposer_params: (
|
||||||
DecompostionLogBase(17),
|
DecompostionLogBase(17),
|
||||||
@@ -597,12 +549,12 @@ pub(crate) const I_2P: BoolParameters<u64> = BoolParameters::<u64> {
|
|||||||
|
|
||||||
pub(crate) const I_4P: BoolParameters<u64> = BoolParameters::<u64> {
|
pub(crate) const I_4P: BoolParameters<u64> = BoolParameters::<u64> {
|
||||||
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
lwe_secret_key_dist: SecretKeyDistribution::ErrorDistribution,
|
lwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
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,
|
||||||
rlwe_n: PolynomialSize(1 << 11),
|
rlwe_n: PolynomialSize(1 << 11),
|
||||||
lwe_n: LweDimension(520),
|
lwe_n: LweDimension(620),
|
||||||
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(13)),
|
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(13)),
|
||||||
rlrg_decomposer_params: (
|
rlrg_decomposer_params: (
|
||||||
DecompostionLogBase(17),
|
DecompostionLogBase(17),
|
||||||
@@ -619,38 +571,14 @@ pub(crate) const I_4P: BoolParameters<u64> = BoolParameters::<u64> {
|
|||||||
variant: ParameterVariant::InteractiveMultiParty,
|
variant: ParameterVariant::InteractiveMultiParty,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) const I_8P_HB_FR: BoolParameters<u64> = BoolParameters::<u64> {
|
pub(crate) const I_8P: BoolParameters<u64> = BoolParameters::<u64> {
|
||||||
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
lwe_secret_key_dist: SecretKeyDistribution::ErrorDistribution,
|
lwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
rlwe_q: CiphertextModulus::new_non_native(18014398509404161),
|
|
||||||
lwe_q: CiphertextModulus::new_non_native(1 << 16),
|
|
||||||
br_q: 1 << 11,
|
|
||||||
rlwe_n: PolynomialSize(1 << 11),
|
|
||||||
lwe_n: LweDimension(520),
|
|
||||||
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(13)),
|
|
||||||
rlrg_decomposer_params: (
|
|
||||||
DecompostionLogBase(17),
|
|
||||||
(DecompositionCount(1), DecompositionCount(1)),
|
|
||||||
),
|
|
||||||
rgrg_decomposer_params: Some((
|
|
||||||
DecompostionLogBase(4),
|
|
||||||
(DecompositionCount(12), DecompositionCount(11)),
|
|
||||||
)),
|
|
||||||
auto_decomposer_params: (DecompostionLogBase(24), DecompositionCount(1)),
|
|
||||||
non_interactive_ui_to_s_key_switch_decomposer: None,
|
|
||||||
g: 5,
|
|
||||||
w: 10,
|
|
||||||
variant: ParameterVariant::InteractiveMultiParty,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub(crate) const I_8P_LB_SR: 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 << 17),
|
lwe_q: CiphertextModulus::new_non_native(1 << 17),
|
||||||
br_q: 1 << 11,
|
br_q: 1 << 12,
|
||||||
rlwe_n: PolynomialSize(1 << 11),
|
rlwe_n: PolynomialSize(1 << 11),
|
||||||
lwe_n: LweDimension(560),
|
lwe_n: LweDimension(660),
|
||||||
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(14)),
|
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(14)),
|
||||||
rlrg_decomposer_params: (
|
rlrg_decomposer_params: (
|
||||||
DecompostionLogBase(17),
|
DecompostionLogBase(17),
|
||||||
@@ -658,7 +586,7 @@ pub(crate) const I_8P_LB_SR: BoolParameters<u64> = BoolParameters::<u64> {
|
|||||||
),
|
),
|
||||||
rgrg_decomposer_params: Some((
|
rgrg_decomposer_params: Some((
|
||||||
DecompostionLogBase(5),
|
DecompostionLogBase(5),
|
||||||
(DecompositionCount(8), DecompositionCount(7)),
|
(DecompositionCount(9), DecompositionCount(8)),
|
||||||
)),
|
)),
|
||||||
auto_decomposer_params: (DecompostionLogBase(24), DecompositionCount(1)),
|
auto_decomposer_params: (DecompostionLogBase(24), DecompositionCount(1)),
|
||||||
non_interactive_ui_to_s_key_switch_decomposer: None,
|
non_interactive_ui_to_s_key_switch_decomposer: None,
|
||||||
@@ -671,18 +599,18 @@ pub(crate) const NI_2P: BoolParameters<u64> = BoolParameters::<u64> {
|
|||||||
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
lwe_secret_key_dist: SecretKeyDistribution::ErrorDistribution,
|
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 << 16),
|
||||||
br_q: 1 << 11,
|
br_q: 1 << 12,
|
||||||
rlwe_n: PolynomialSize(1 << 11),
|
rlwe_n: PolynomialSize(1 << 11),
|
||||||
lwe_n: LweDimension(480),
|
lwe_n: LweDimension(520),
|
||||||
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(12)),
|
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(13)),
|
||||||
rlrg_decomposer_params: (
|
rlrg_decomposer_params: (
|
||||||
DecompostionLogBase(16),
|
DecompostionLogBase(17),
|
||||||
(DecompositionCount(1), DecompositionCount(1)),
|
(DecompositionCount(1), DecompositionCount(1)),
|
||||||
),
|
),
|
||||||
rgrg_decomposer_params: Some((
|
rgrg_decomposer_params: Some((
|
||||||
DecompostionLogBase(6),
|
DecompostionLogBase(4),
|
||||||
(DecompositionCount(7), DecompositionCount(7)),
|
(DecompositionCount(10), DecompositionCount(9)),
|
||||||
)),
|
)),
|
||||||
auto_decomposer_params: (DecompostionLogBase(24), DecompositionCount(1)),
|
auto_decomposer_params: (DecompostionLogBase(24), DecompositionCount(1)),
|
||||||
non_interactive_ui_to_s_key_switch_decomposer: Some((
|
non_interactive_ui_to_s_key_switch_decomposer: Some((
|
||||||
@@ -694,15 +622,42 @@ pub(crate) const NI_2P: BoolParameters<u64> = BoolParameters::<u64> {
|
|||||||
variant: ParameterVariant::NonInteractiveMultiParty,
|
variant: ParameterVariant::NonInteractiveMultiParty,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) const NI_4P: BoolParameters<u64> = BoolParameters::<u64> {
|
pub(crate) const NI_4P_HB_FR: BoolParameters<u64> = BoolParameters::<u64> {
|
||||||
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
lwe_secret_key_dist: SecretKeyDistribution::ErrorDistribution,
|
lwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
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,
|
||||||
rlwe_n: PolynomialSize(1 << 11),
|
rlwe_n: PolynomialSize(1 << 11),
|
||||||
lwe_n: LweDimension(510),
|
lwe_n: LweDimension(620),
|
||||||
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(12)),
|
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(13)),
|
||||||
|
rlrg_decomposer_params: (
|
||||||
|
DecompostionLogBase(17),
|
||||||
|
(DecompositionCount(1), DecompositionCount(1)),
|
||||||
|
),
|
||||||
|
rgrg_decomposer_params: Some((
|
||||||
|
DecompostionLogBase(3),
|
||||||
|
(DecompositionCount(13), DecompositionCount(12)),
|
||||||
|
)),
|
||||||
|
auto_decomposer_params: (DecompostionLogBase(24), DecompositionCount(1)),
|
||||||
|
non_interactive_ui_to_s_key_switch_decomposer: Some((
|
||||||
|
DecompostionLogBase(1),
|
||||||
|
DecompositionCount(50),
|
||||||
|
)),
|
||||||
|
g: 5,
|
||||||
|
w: 10,
|
||||||
|
variant: ParameterVariant::NonInteractiveMultiParty,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub(crate) const NI_4P_LB_SR: BoolParameters<u64> = BoolParameters::<u64> {
|
||||||
|
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
|
lwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
|
rlwe_q: CiphertextModulus::new_non_native(18014398509404161),
|
||||||
|
lwe_q: CiphertextModulus::new_non_native(1 << 16),
|
||||||
|
br_q: 1 << 12,
|
||||||
|
rlwe_n: PolynomialSize(1 << 11),
|
||||||
|
lwe_n: LweDimension(620),
|
||||||
|
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(13)),
|
||||||
rlrg_decomposer_params: (
|
rlrg_decomposer_params: (
|
||||||
DecompostionLogBase(17),
|
DecompostionLogBase(17),
|
||||||
(DecompositionCount(1), DecompositionCount(1)),
|
(DecompositionCount(1), DecompositionCount(1)),
|
||||||
@@ -721,6 +676,33 @@ pub(crate) const NI_4P: BoolParameters<u64> = BoolParameters::<u64> {
|
|||||||
variant: ParameterVariant::NonInteractiveMultiParty,
|
variant: ParameterVariant::NonInteractiveMultiParty,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub(crate) const NI_8P: BoolParameters<u64> = BoolParameters::<u64> {
|
||||||
|
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
|
lwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
|
rlwe_q: CiphertextModulus::new_non_native(18014398509404161),
|
||||||
|
lwe_q: CiphertextModulus::new_non_native(1 << 17),
|
||||||
|
br_q: 1 << 12,
|
||||||
|
rlwe_n: PolynomialSize(1 << 11),
|
||||||
|
lwe_n: LweDimension(660),
|
||||||
|
lwe_decomposer_params: (DecompostionLogBase(1), DecompositionCount(14)),
|
||||||
|
rlrg_decomposer_params: (
|
||||||
|
DecompostionLogBase(17),
|
||||||
|
(DecompositionCount(1), DecompositionCount(1)),
|
||||||
|
),
|
||||||
|
rgrg_decomposer_params: Some((
|
||||||
|
DecompostionLogBase(2),
|
||||||
|
(DecompositionCount(20), DecompositionCount(18)),
|
||||||
|
)),
|
||||||
|
auto_decomposer_params: (DecompostionLogBase(24), DecompositionCount(1)),
|
||||||
|
non_interactive_ui_to_s_key_switch_decomposer: Some((
|
||||||
|
DecompostionLogBase(1),
|
||||||
|
DecompositionCount(50),
|
||||||
|
)),
|
||||||
|
g: 5,
|
||||||
|
w: 10,
|
||||||
|
variant: ParameterVariant::NonInteractiveMultiParty,
|
||||||
|
};
|
||||||
|
|
||||||
#[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,
|
rlwe_secret_key_dist: SecretKeyDistribution::TernaryDistribution,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ use super::keys::tests::{ideal_sk_lwe, ideal_sk_rlwe};
|
|||||||
|
|
||||||
pub(crate) trait CollectRuntimeServerKeyStats {
|
pub(crate) trait CollectRuntimeServerKeyStats {
|
||||||
type M;
|
type M;
|
||||||
/// RGSW ciphertext X^{s[s_index]} in evaluation domain where s the LWE
|
/// RGSW ciphertext X^{s[s_index]} in evaluation domain where `s` the LWE
|
||||||
/// secret
|
/// secret
|
||||||
fn rgsw_cts_lwe_si(&self, s_index: usize) -> &Self::M;
|
fn rgsw_cts_lwe_si(&self, s_index: usize) -> &Self::M;
|
||||||
/// Auto key in evaluation domain for automorphism g^k. For auto key for
|
/// Auto key in evaluation domain for automorphism g^k. For auto key for
|
||||||
@@ -33,9 +33,20 @@ pub(crate) trait CollectRuntimeServerKeyStats {
|
|||||||
fn lwe_ksk(&self) -> &Self::M;
|
fn lwe_ksk(&self) -> &Self::M;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
struct ServerKeyStats<T> {
|
struct ServerKeyStats<T> {
|
||||||
|
/// Distribution of noise in RGSW ciphertexts
|
||||||
|
///
|
||||||
|
/// We collect statistics for RLWE'(-sm) separately from RLWE'(m) because
|
||||||
|
/// non-interactive protocol differents between the two. Although we expect
|
||||||
|
/// the distribution of noise in both to be the same.
|
||||||
brk_rgsw_cts: (Stats<T>, Stats<T>),
|
brk_rgsw_cts: (Stats<T>, Stats<T>),
|
||||||
|
/// Distribtion of noise added to RLWE ciphertext after automorphism using
|
||||||
|
/// Server auto keys.
|
||||||
post_1_auto: Stats<T>,
|
post_1_auto: Stats<T>,
|
||||||
|
/// Distribution of noise added in LWE key switching from LWE_{q, s} to
|
||||||
|
/// LWE_{q, z} where `z` is ideal LWE secret and `s` is ideal RLWE secret
|
||||||
|
/// using Server's LWE key switching key.
|
||||||
post_lwe_key_switch: Stats<T>,
|
post_lwe_key_switch: Stats<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,19 +63,28 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_noise_brk_rgsw_cts_nsm(&mut self, noise: &[T]) {
|
fn add_noise_brk_rgsw_cts_nsm(&mut self, noise: &[T]) {
|
||||||
self.brk_rgsw_cts.0.add_more(noise);
|
self.brk_rgsw_cts.0.add_many_samples(noise);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_noise_brk_rgsw_cts_m(&mut self, noise: &[T]) {
|
fn add_noise_brk_rgsw_cts_m(&mut self, noise: &[T]) {
|
||||||
self.brk_rgsw_cts.1.add_more(noise);
|
self.brk_rgsw_cts.1.add_many_samples(noise);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_noise_post_1_auto(&mut self, noise: &[T]) {
|
fn add_noise_post_1_auto(&mut self, noise: &[T]) {
|
||||||
self.post_1_auto.add_more(&noise);
|
self.post_1_auto.add_many_samples(&noise);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_noise_post_kwe_key_switch(&mut self, noise: &[T]) {
|
fn add_noise_post_kwe_key_switch(&mut self, noise: &[T]) {
|
||||||
self.post_lwe_key_switch.add_more(&noise);
|
self.post_lwe_key_switch.add_many_samples(&noise);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge_in(&mut self, other: &Self) {
|
||||||
|
self.brk_rgsw_cts.0.merge_in(&other.brk_rgsw_cts.0);
|
||||||
|
self.brk_rgsw_cts.1.merge_in(&other.brk_rgsw_cts.1);
|
||||||
|
|
||||||
|
self.post_1_auto.merge_in(&other.post_1_auto);
|
||||||
|
self.post_lwe_key_switch
|
||||||
|
.merge_in(&other.post_lwe_key_switch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,8 +383,6 @@ where
|
|||||||
mod tests {
|
mod tests {
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use super::collect_server_key_stats;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "interactive_mp")]
|
#[cfg(feature = "interactive_mp")]
|
||||||
fn interactive_key_noise() {
|
fn interactive_key_noise() {
|
||||||
@@ -382,9 +400,16 @@ mod tests {
|
|||||||
BoolEvaluator, DefaultDecomposer, ModularOpsU64, NttBackendU64,
|
BoolEvaluator, DefaultDecomposer, ModularOpsU64, NttBackendU64,
|
||||||
};
|
};
|
||||||
|
|
||||||
set_parameter_set(crate::ParameterSelector::InteractiveLTE2Party);
|
use super::*;
|
||||||
|
|
||||||
|
set_parameter_set(crate::ParameterSelector::InteractiveLTE8Party);
|
||||||
set_common_reference_seed(InteractiveMultiPartyCrs::random().seed);
|
set_common_reference_seed(InteractiveMultiPartyCrs::random().seed);
|
||||||
let parties = 2;
|
let parties = 8;
|
||||||
|
|
||||||
|
let mut server_key_stats = ServerKeyStats::default();
|
||||||
|
let mut server_key_share_size = 0usize;
|
||||||
|
|
||||||
|
for i in 0..2 {
|
||||||
let cks = (0..parties).map(|_| gen_client_key()).collect_vec();
|
let cks = (0..parties).map(|_| gen_client_key()).collect_vec();
|
||||||
let pk_shares = cks
|
let pk_shares = cks
|
||||||
.iter()
|
.iter()
|
||||||
@@ -398,6 +423,16 @@ mod tests {
|
|||||||
.map(|(index, k)| gen_mp_keys_phase2(k, index, parties, &pk))
|
.map(|(index, k)| gen_mp_keys_phase2(k, index, parties, &pk))
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
|
// In 0th iteration measure server key size
|
||||||
|
if i == 0 {
|
||||||
|
// Server key share size of user with last id may not equal server key share
|
||||||
|
// sizes of other users if LWE dimension does not divides number of parties.
|
||||||
|
server_key_share_size = std::cmp::max(
|
||||||
|
server_key_shares.first().unwrap().size(),
|
||||||
|
server_key_shares.last().unwrap().size(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// println!("Size: {}", server_key_shares[0].size());
|
// println!("Size: {}", server_key_shares[0].size());
|
||||||
let seeded_server_key = aggregate_server_key_shares(&server_key_shares);
|
let seeded_server_key = aggregate_server_key_shares(&server_key_shares);
|
||||||
let server_key_eval =
|
let server_key_eval =
|
||||||
@@ -406,40 +441,41 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let parameters = BoolEvaluator::with_local(|e| e.parameters().clone());
|
let parameters = BoolEvaluator::with_local(|e| e.parameters().clone());
|
||||||
let server_key_stats = collect_server_key_stats::<
|
server_key_stats.merge_in(&collect_server_key_stats::<
|
||||||
_,
|
_,
|
||||||
DefaultDecomposer<u64>,
|
DefaultDecomposer<u64>,
|
||||||
NttBackendU64,
|
NttBackendU64,
|
||||||
ModularOpsU64<CiphertextModulus<u64>>,
|
ModularOpsU64<CiphertextModulus<u64>>,
|
||||||
_,
|
_,
|
||||||
>(parameters, &cks, &server_key_eval);
|
>(parameters, &cks, &server_key_eval));
|
||||||
|
}
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Common reference seeded server key share key size size: {} Bits",
|
"Common reference seeded server key share key size: {} Bits",
|
||||||
server_key_shares[0].size()
|
server_key_share_size
|
||||||
);
|
);
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Rgsw nsm std log2 {}",
|
"Rgsw nsm std log2 {}",
|
||||||
server_key_stats.brk_rgsw_cts.0.std_dev().abs().log2()
|
server_key_stats.brk_rgsw_cts.0.std_dev().log2()
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
"Rgsw m std log2 {}",
|
"Rgsw m std log2 {}",
|
||||||
server_key_stats.brk_rgsw_cts.1.std_dev().abs().log2()
|
server_key_stats.brk_rgsw_cts.1.std_dev().log2()
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
"rlwe post 1 auto std log2 {}",
|
"rlwe post 1 auto std log2 {}",
|
||||||
server_key_stats.post_1_auto.std_dev().abs().log2()
|
server_key_stats.post_1_auto.std_dev().log2()
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
"key switching noise rlwe secret s to lwe secret z std log2 {}",
|
"key switching noise rlwe secret s to lwe secret z std log2 {}",
|
||||||
server_key_stats.post_lwe_key_switch.std_dev().abs().log2()
|
server_key_stats.post_lwe_key_switch.std_dev().log2()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "non_interactive_mp")]
|
#[cfg(feature = "non_interactive_mp")]
|
||||||
fn querty2() {
|
fn non_interactive_key_noise() {
|
||||||
use crate::{
|
use crate::{
|
||||||
aggregate_server_key_shares,
|
aggregate_server_key_shares,
|
||||||
bool::{
|
bool::{
|
||||||
@@ -455,9 +491,15 @@ mod tests {
|
|||||||
BoolEvaluator, ModularOpsU64, NttBackendU64,
|
BoolEvaluator, ModularOpsU64, NttBackendU64,
|
||||||
};
|
};
|
||||||
|
|
||||||
set_parameter_set(crate::ParameterSelector::NonInteractiveLTE2Party);
|
use super::*;
|
||||||
|
|
||||||
|
set_parameter_set(crate::ParameterSelector::NonInteractiveLTE8Party);
|
||||||
set_common_reference_seed(NonInteractiveMultiPartyCrs::random().seed);
|
set_common_reference_seed(NonInteractiveMultiPartyCrs::random().seed);
|
||||||
let parties = 2;
|
let parties = 8;
|
||||||
|
|
||||||
|
let mut server_key_stats = ServerKeyStats::default();
|
||||||
|
let mut server_key_share_size = 0;
|
||||||
|
for i in 0..2 {
|
||||||
let cks = (0..parties).map(|_| gen_client_key()).collect_vec();
|
let cks = (0..parties).map(|_| gen_client_key()).collect_vec();
|
||||||
let server_key_shares = cks
|
let server_key_shares = cks
|
||||||
.iter()
|
.iter()
|
||||||
@@ -465,25 +507,39 @@ mod tests {
|
|||||||
.map(|(user_id, k)| gen_server_key_share(user_id, parties, k))
|
.map(|(user_id, k)| gen_server_key_share(user_id, parties, k))
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
|
// Collect server key size in the 0th iteration
|
||||||
|
if i == 0 {
|
||||||
|
// Server key share size may differ for user with last id from
|
||||||
|
// the share size of other users if the LWE dimension `n` is not
|
||||||
|
// divisible by no. of parties.
|
||||||
|
server_key_share_size = std::cmp::max(
|
||||||
|
server_key_shares.first().unwrap().size(),
|
||||||
|
server_key_shares.last().unwrap().size(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let server_key = aggregate_server_key_shares(&server_key_shares);
|
let server_key = aggregate_server_key_shares(&server_key_shares);
|
||||||
|
|
||||||
let server_key_eval =
|
let server_key_eval = NonInteractiveServerKeyEvaluationDomain::<
|
||||||
NonInteractiveServerKeyEvaluationDomain::<_, _, DefaultSecureRng, NttBackendU64>::from(
|
_,
|
||||||
&server_key,
|
_,
|
||||||
);
|
DefaultSecureRng,
|
||||||
|
NttBackendU64,
|
||||||
|
>::from(&server_key);
|
||||||
|
|
||||||
let parameters = BoolEvaluator::with_local(|e| e.parameters().clone());
|
let parameters = BoolEvaluator::with_local(|e| e.parameters().clone());
|
||||||
let server_key_stats = collect_server_key_stats::<
|
server_key_stats.merge_in(&collect_server_key_stats::<
|
||||||
_,
|
_,
|
||||||
DefaultDecomposer<u64>,
|
DefaultDecomposer<u64>,
|
||||||
NttBackendU64,
|
NttBackendU64,
|
||||||
ModularOpsU64<CiphertextModulus<u64>>,
|
ModularOpsU64<CiphertextModulus<u64>>,
|
||||||
_,
|
_,
|
||||||
>(parameters, &cks, &server_key_eval);
|
>(parameters, &cks, &server_key_eval));
|
||||||
|
}
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Common reference seeded server key share key size size: {} Bits",
|
"Common reference seeded server key share key size: {} Bits",
|
||||||
server_key_shares[0].size()
|
server_key_share_size
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
"Rgsw nsm std log2 {}",
|
"Rgsw nsm std log2 {}",
|
||||||
@@ -565,10 +621,136 @@ mod tests {
|
|||||||
rlwe_q_modop.elwise_sub_mut(diff.as_mut_slice(), message.as_ref());
|
rlwe_q_modop.elwise_sub_mut(diff.as_mut_slice(), message.as_ref());
|
||||||
|
|
||||||
let mut stats = Stats::new();
|
let mut stats = Stats::new();
|
||||||
stats.add_more(&Vec::<i64>::try_convert_from(
|
stats.add_many_samples(&Vec::<i64>::try_convert_from(
|
||||||
diff.as_slice(),
|
diff.as_slice(),
|
||||||
parameters.rlwe_q(),
|
parameters.rlwe_q(),
|
||||||
));
|
));
|
||||||
println!("Noise std log2: {}", stats.std_dev().abs().log2());
|
println!("Noise std log2: {}", stats.std_dev().abs().log2());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mod_switch_noise() {
|
||||||
|
// Experiment to check mod switch noise using different secret dist in
|
||||||
|
// multi-party setting
|
||||||
|
|
||||||
|
use itertools::izip;
|
||||||
|
use num_traits::ToPrimitive;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
backend::{Modulus, ModulusPowerOf2},
|
||||||
|
parameters::SecretKeyDistribution,
|
||||||
|
random::{DefaultSecureRng, RandomFillGaussian, RandomFillUniformInModulus},
|
||||||
|
utils::{fill_random_ternary_secret_with_hamming_weight, tests::Stats},
|
||||||
|
ArithmeticOps, ModInit,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn mod_switch(v: u64, q_from: u64, q_to: u64) -> f64 {
|
||||||
|
(v as f64) * (q_to as f64) / q_from as f64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mod_switch_round(v: u64, q_from: u64, q_to: u64) -> u64 {
|
||||||
|
mod_switch(v, q_from, q_to).round().to_u64().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mod_switch_odd(v: u64, q_from: u64, q_to: u64) -> u64 {
|
||||||
|
let odd_v = mod_switch(v, q_from, q_to).floor().to_u64().unwrap();
|
||||||
|
odd_v + ((odd_v & 1) ^ 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sample_secret(n: usize, dist: &SecretKeyDistribution) -> Vec<i32> {
|
||||||
|
let mut s = vec![0i32; n];
|
||||||
|
let mut rng = DefaultSecureRng::new();
|
||||||
|
|
||||||
|
match dist {
|
||||||
|
SecretKeyDistribution::ErrorDistribution => {
|
||||||
|
RandomFillGaussian::random_fill(&mut rng, s.as_mut_slice());
|
||||||
|
}
|
||||||
|
SecretKeyDistribution::TernaryDistribution => {
|
||||||
|
fill_random_ternary_secret_with_hamming_weight(&mut s, n >> 1, &mut rng);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s
|
||||||
|
}
|
||||||
|
|
||||||
|
let parties = 2;
|
||||||
|
let q_from = 1 << 40;
|
||||||
|
let q_to = 1 << 20;
|
||||||
|
let n = 480;
|
||||||
|
let lweq_in_modop = ModulusPowerOf2::new(q_from);
|
||||||
|
let lweq_out_modop = ModulusPowerOf2::new(q_to);
|
||||||
|
let secret_dist = SecretKeyDistribution::ErrorDistribution;
|
||||||
|
|
||||||
|
let mut stats_ms_noise = Stats::new();
|
||||||
|
let mut stats_ms_rounding_err = Stats::new();
|
||||||
|
|
||||||
|
for _ in 0..1000000 {
|
||||||
|
let mut rng = DefaultSecureRng::new();
|
||||||
|
|
||||||
|
// sample secrets
|
||||||
|
|
||||||
|
let s = {
|
||||||
|
let mut s = vec![0i32; n];
|
||||||
|
for _ in 0..parties {
|
||||||
|
let temp = sample_secret(n, &secret_dist);
|
||||||
|
izip!(s.iter_mut(), temp.iter()).for_each(|(si, ti)| {
|
||||||
|
*si = *si + *ti;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
s
|
||||||
|
};
|
||||||
|
|
||||||
|
let m = 10;
|
||||||
|
|
||||||
|
// LWE encryption without noise
|
||||||
|
let mut lwe_in = vec![0u64; n + 1];
|
||||||
|
{
|
||||||
|
RandomFillUniformInModulus::random_fill(&mut rng, &q_from, &mut lwe_in[1..]);
|
||||||
|
let mut b = m;
|
||||||
|
izip!(lwe_in.iter().skip(1), s.iter()).for_each(|(ai, si)| {
|
||||||
|
b = lweq_in_modop.add(
|
||||||
|
&b,
|
||||||
|
&lweq_in_modop.mul(ai, &q_from.map_element_from_i64(*si as i64)),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
lwe_in[0] = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mod switch
|
||||||
|
let lwe_out = lwe_in
|
||||||
|
.iter()
|
||||||
|
.map(|v| {
|
||||||
|
// mod_switch_round(*v, q_from, q_to)
|
||||||
|
mod_switch_odd(*v, q_from, q_to)
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
let rounding_errors = izip!(lwe_out.iter(), lwe_in.iter())
|
||||||
|
.map(|(v_out, v_in)| {
|
||||||
|
let r_i = mod_switch(*v_in, q_from, q_to) - (*v_out as f64);
|
||||||
|
r_i
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
stats_ms_rounding_err.add_many_samples(&rounding_errors);
|
||||||
|
|
||||||
|
// LWE decrypt and calculate ms noise
|
||||||
|
let mut m_back = 0;
|
||||||
|
izip!(lwe_out.iter().skip(1), s.iter()).for_each(|(ai, si)| {
|
||||||
|
m_back = lweq_out_modop.add(
|
||||||
|
&m_back,
|
||||||
|
&lweq_out_modop.mul(ai, &q_from.map_element_from_i64(*si as i64)),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
m_back = lweq_out_modop.sub(&lwe_out[0], &m_back);
|
||||||
|
let noise = lweq_out_modop.sub(&m_back, &m);
|
||||||
|
stats_ms_noise.add_many_samples(&vec![q_to.map_element_to_i64(&noise)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("ms noise variance: {}", stats_ms_noise.variance());
|
||||||
|
println!("ms rounding errors mean: {}", stats_ms_rounding_err.mean());
|
||||||
|
println!(
|
||||||
|
"ms rounding errors variance: {}",
|
||||||
|
stats_ms_rounding_err.variance()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,6 +194,7 @@ trait SizeInBitsWithLogModulus {
|
|||||||
/// 2^{log_modulus-1} < Q <= `2^log_modulus`
|
/// 2^{log_modulus-1} < Q <= `2^log_modulus`
|
||||||
fn size(&self, log_modulus: usize) -> usize;
|
fn size(&self, log_modulus: usize) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SizeInBitsWithLogModulus for Vec<Vec<u64>> {
|
impl SizeInBitsWithLogModulus for Vec<Vec<u64>> {
|
||||||
fn size(&self, log_modulus: usize) -> usize {
|
fn size(&self, log_modulus: usize) -> usize {
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
|
|||||||
@@ -878,7 +878,7 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
let mut diff = want_m;
|
let mut diff = want_m;
|
||||||
mod_op.elwise_sub_mut(diff.as_mut(), got_m.as_ref());
|
mod_op.elwise_sub_mut(diff.as_mut(), got_m.as_ref());
|
||||||
stats.add_more(&Vec::<i64>::try_convert_from(&diff, q));
|
stats.add_many_samples(&Vec::<i64>::try_convert_from(&diff, q));
|
||||||
}
|
}
|
||||||
|
|
||||||
// RLWE(\beta^j m)
|
// RLWE(\beta^j m)
|
||||||
@@ -899,7 +899,7 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
let mut diff = want_m;
|
let mut diff = want_m;
|
||||||
mod_op.elwise_sub_mut(diff.as_mut(), got_m.as_ref());
|
mod_op.elwise_sub_mut(diff.as_mut(), got_m.as_ref());
|
||||||
stats.add_more(&Vec::<i64>::try_convert_from(&diff, q));
|
stats.add_many_samples(&Vec::<i64>::try_convert_from(&diff, q));
|
||||||
}
|
}
|
||||||
|
|
||||||
stats
|
stats
|
||||||
|
|||||||
22
src/utils.rs
22
src/utils.rs
@@ -271,7 +271,7 @@ impl<P: Modulus> TryConvertFrom1<[P::Element], P> for Vec<i64> {
|
|||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use num_traits::{FromPrimitive, PrimInt};
|
use num_traits::ToPrimitive;
|
||||||
|
|
||||||
use crate::random::DefaultSecureRng;
|
use crate::random::DefaultSecureRng;
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ pub(crate) mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PrimInt + FromPrimitive + Debug> Stats<T>
|
impl<T: Copy + ToPrimitive + Debug> Stats<T>
|
||||||
where
|
where
|
||||||
// T: for<'a> Sum<&'a T>,
|
// T: for<'a> Sum<&'a T>,
|
||||||
T: for<'a> std::iter::Sum<&'a T> + std::iter::Sum<T>,
|
T: for<'a> std::iter::Sum<&'a T> + std::iter::Sum<T>,
|
||||||
@@ -301,7 +301,7 @@ pub(crate) mod tests {
|
|||||||
self.samples.iter().sum::<T>().to_f64().unwrap() / (self.samples.len() as f64)
|
self.samples.iter().sum::<T>().to_f64().unwrap() / (self.samples.len() as f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn std_dev(&self) -> f64 {
|
pub(crate) fn variance(&self) -> f64 {
|
||||||
let mean = self.mean();
|
let mean = self.mean();
|
||||||
|
|
||||||
// diff
|
// diff
|
||||||
@@ -315,12 +315,24 @@ pub(crate) mod tests {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.sum::<f64>();
|
.sum::<f64>();
|
||||||
|
|
||||||
(diff_sq / (self.samples.len() as f64)).sqrt()
|
diff_sq / (self.samples.len() as f64 - 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_more(&mut self, values: &[T]) {
|
pub(crate) fn std_dev(&self) -> f64 {
|
||||||
|
self.variance().sqrt()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn add_many_samples(&mut self, values: &[T]) {
|
||||||
self.samples.extend(values.iter());
|
self.samples.extend(values.iter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn add_sample(&mut self, value: T) {
|
||||||
|
self.samples.push(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn merge_in(&mut self, other: &Self) {
|
||||||
|
self.samples.extend(other.samples.iter());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user