Browse Source

add high but fast communication for 2pc

par-agg-key-shares
Janmajaya Mall 11 months ago
parent
commit
53a0ec49af
5 changed files with 83 additions and 39 deletions
  1. +53
    -0
      src/bool/keys.rs
  2. +1
    -0
      src/bool/mod.rs
  3. +28
    -2
      src/bool/mp_api.rs
  4. +1
    -36
      src/bool/ni_mp_api.rs
  5. +0
    -1
      src/utils.rs

+ 53
- 0
src/bool/keys.rs

@ -1243,3 +1243,56 @@ impl WithShoupRepr for NormalAndShoup {
&self.1
}
}
pub(super) mod tests {
use itertools::izip;
use num_traits::{FromPrimitive, PrimInt, ToPrimitive, Zero};
use crate::{
backend::{GetModulus, Modulus},
bool::ClientKey,
lwe::decrypt_lwe,
parameters::CiphertextModulus,
utils::TryConvertFrom1,
ArithmeticOps, Row,
};
use super::SinglePartyClientKey;
pub(crate) fn ideal_sk_rlwe(cks: &[ClientKey]) -> Vec<i32> {
let mut ideal_rlwe_sk = cks[0].sk_rlwe();
cks.iter().skip(1).for_each(|k| {
let sk_rlwe = k.sk_rlwe();
izip!(ideal_rlwe_sk.iter_mut(), sk_rlwe.iter()).for_each(|(a, b)| {
*a = *a + b;
});
});
ideal_rlwe_sk
}
pub(crate) fn measure_noise_lwe<
R: Row,
S,
Modop: ArithmeticOps<Element = R::Element>
+ GetModulus<M = CiphertextModulus<R::Element>, Element = R::Element>,
>(
lwe_ct: &R,
m_expected: R::Element,
sk: &[S],
modop: &Modop,
) -> f64
where
R: TryConvertFrom1<[S], CiphertextModulus<R::Element>>,
R::Element: Zero + FromPrimitive + PrimInt,
{
let noisy_m = decrypt_lwe(lwe_ct, &sk, modop);
let noise = modop.sub(&m_expected, &noisy_m);
modop
.modulus()
.map_element_to_i64(&noise)
.abs()
.to_f64()
.unwrap()
.log2()
}
}

+ 1
- 0
src/bool/mod.rs

@ -21,6 +21,7 @@ pub use mp_api::*;
pub type ClientKey = keys::ClientKey<[u8; 32], u64>;
pub enum ParameterSelector {
HighCommunicationButFast2Party,
MultiPartyLessThanOrEqualTo16,
NonInteractiveMultiPartyLessThanOrEqualTo16,
}

+ 28
- 2
src/bool/mp_api.rs

@ -30,6 +30,10 @@ pub fn set_parameter_set(select: ParameterSelector) {
ParameterSelector::MultiPartyLessThanOrEqualTo16 => {
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(SMALL_MP_BOOL_PARAMS)));
}
ParameterSelector::HighCommunicationButFast2Party => {
BOOL_EVALUATOR
.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(OPTIMISED_SMALL_MP_BOOL_PARAMS)));
}
_ => {
panic!("Paramerters not supported")
}
@ -234,16 +238,25 @@ mod impl_enc_dec {
#[cfg(test)]
mod tests {
use std::thread::panicking;
use itertools::Itertools;
use rand::{thread_rng, RngCore};
use crate::{bool::evaluator::BooleanGates, Encryptor, MultiPartyDecryptor};
use crate::{
bool::{
evaluator::BooleanGates,
keys::tests::{ideal_sk_rlwe, measure_noise_lwe},
},
evaluator::{BoolEncoding, BoolEvaluator},
Encryptor, MultiPartyDecryptor,
};
use super::*;
#[test]
fn multi_party_bool_gates() {
set_parameter_set(ParameterSelector::MultiPartyLessThanOrEqualTo16);
set_parameter_set(ParameterSelector::HighCommunicationButFast2Party);
let mut seed = [0u8; 32];
thread_rng().fill_bytes(&mut seed);
set_mp_seed(seed);
@ -274,6 +287,10 @@ mod tests {
let mut ct0 = pk.encrypt(&m0);
let mut ct1 = pk.encrypt(&m1);
let ideal_sk_rlwe = ideal_sk_rlwe(&cks);
let parameters = BoolEvaluator::with_local(|e| e.parameters().clone());
let rlwe_modop = parameters.default_rlwe_modop();
for _ in 0..500 {
let ct_out =
BoolEvaluator::with_local_mut(|e| e.nand(&ct0, &ct1, RuntimeServerKey::global()));
@ -287,6 +304,15 @@ mod tests {
let m_out = cks[0].aggregate_decryption_shares(&ct_out, &decryption_shares);
assert!(m_out == m_expected, "Expected {m_expected}, got {m_out}");
{
let m_expected_el = if m_expected == true {
parameters.rlwe_q().true_el()
} else {
parameters.rlwe_q().false_el()
};
let noise = measure_noise_lwe(&ct_out, m_expected_el, &ideal_sk_rlwe, &rlwe_modop);
println!("NAND Noise: {noise}");
}
m1 = m0;
m0 = m_expected;

+ 1
- 36
src/bool/ni_mp_api.rs

@ -368,42 +368,7 @@ mod tests {
use super::*;
pub(crate) fn ideal_sk_rlwe(cks: &[ClientKey]) -> Vec<i32> {
let mut ideal_rlwe_sk = cks[0].sk_rlwe();
cks.iter().skip(1).for_each(|k| {
let sk_rlwe = k.sk_rlwe();
izip!(ideal_rlwe_sk.iter_mut(), sk_rlwe.iter()).for_each(|(a, b)| {
*a = *a + b;
});
});
ideal_rlwe_sk
}
pub(crate) fn measure_noise_lwe<
R: Row,
S,
Modop: ArithmeticOps<Element = R::Element>
+ GetModulus<M = CiphertextModulus<R::Element>, Element = R::Element>,
>(
lwe_ct: &R,
m_expected: R::Element,
sk: &[S],
modop: &Modop,
) -> f64
where
R: TryConvertFrom1<[S], CiphertextModulus<R::Element>>,
R::Element: Zero + FromPrimitive + PrimInt,
{
let noisy_m = decrypt_lwe(lwe_ct, &sk, modop);
let noise = modop.sub(&m_expected, &noisy_m);
modop
.modulus()
.map_element_to_i64(&noise)
.abs()
.to_f64()
.unwrap()
.log2()
}
#[test]
fn non_interactive_mp_bool_nand() {

+ 0
- 1
src/utils.rs

@ -262,7 +262,6 @@ pub(crate) mod tests {
use std::fmt::Debug;
use num_traits::{FromPrimitive, PrimInt};
use rand::thread_rng;
use crate::random::DefaultSecureRng;

Loading…
Cancel
Save