make tests
Janmajaya Mall janmajayamall@protonmail.com
Tue, 18 Jun 2024 20:14:03 +0530
5 files changed,
83 insertions(+),
30 deletions(-)
M
src/bool/evaluator.rs
→
src/bool/evaluator.rs
@@ -42,8 +42,8 @@ utils::{
fill_random_ternary_secret_with_hamming_weight, generate_prime, mod_exponent, puncture_p_rng, Global, TryConvertFrom1, WithLocal, }, - Decryptor, Encryptor, Matrix, MatrixEntity, MatrixMut, MultiPartyDecryptor, Row, RowEntity, - RowMut, Secret, + Decryptor, Encoder, Encryptor, Matrix, MatrixEntity, MatrixMut, MultiPartyDecryptor, Row, + RowEntity, RowMut, Secret, }; use super::{@@ -288,6 +288,19 @@ } else if m == 1 {
return true; } else { panic!("Incorrect bool decryption. Got m={m} but expected m to be 0 or 1") + } + } +} + +impl<B> Encoder<bool, B::Element> for B +where + B: BoolEncoding, +{ + fn encode(&self, v: bool) -> B::Element { + if v { + self.true_el() + } else { + self.false_el() } } }
M
src/bool/ni_mp_api.rs
→
src/bool/ni_mp_api.rs
@@ -372,11 +372,11 @@ #[cfg(test)]
mod tests { use impl_enc_dec::NonInteractiveBatchedFheBools; use itertools::{izip, Itertools}; - use num_traits::ToPrimitive; + use num_traits::{FromPrimitive, PrimInt, ToPrimitive, Zero}; use rand::{thread_rng, RngCore}; use crate::{ - backend::Modulus, + backend::{GetModulus, Modulus}, bool::{ evaluator::{BoolEncoding, BooleanGates}, keys::SinglePartyClientKey,@@ -384,12 +384,49 @@ },
lwe::decrypt_lwe, rgsw::decrypt_rlwe, utils::{Stats, TryConvertFrom1}, - ArithmeticOps, Encryptor, KeySwitchWithId, ModInit, MultiPartyDecryptor, NttInit, - VectorOps, + ArithmeticOps, Encoder, Encryptor, KeySwitchWithId, ModInit, MultiPartyDecryptor, NttInit, + Row, VectorOps, }; use super::*; + pub(crate) fn ideal_sk_rlwe(cks: &[ClientKey]) -> Vec<i32> { + let mut ideal_rlwe_sk = cks[0].sk_rlwe(); + cks.iter().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() { set_parameter_set(ParameterSelector::NonInteractiveMultiPartyLessThanOrEqualTo16);@@ -411,16 +448,9 @@ let seeded_server_key = aggregate_server_key_shares(&key_shares);
seeded_server_key.set_server_key(); let parameters = BoolEvaluator::with_local(|e| e.parameters().clone()); - let nttop = NttBackendU64::new(parameters.rlwe_q(), parameters.rlwe_n().0); - let rlwe_q_modop = ModularOpsU64::new(*parameters.rlwe_q()); + let rlwe_modop = parameters.default_rlwe_modop(); - let mut ideal_rlwe_sk = vec![0i32; parameters.rlwe_n().0]; - cks.iter().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; - }); - }); + let ideal_sk_rlwe = ideal_sk_rlwe(&cks); let mut m0 = false; let mut m1 = true;@@ -449,12 +479,8 @@
let m_expected = (m0 ^ m1); { - let noisy_m = decrypt_lwe(&ct_out, &ideal_rlwe_sk, &rlwe_q_modop); - let noise = if m_expected { - rlwe_q_modop.sub(¶meters.rlwe_q().true_el(), &noisy_m) - } else { - rlwe_q_modop.sub(¶meters.rlwe_q().false_el(), &noisy_m) - }; + 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); println!( "Noise: {}", parameters@@ -464,7 +490,10 @@ .abs()
.to_f64() .unwrap() .log2() - ) + ); + // let noise = measure_noise_lwe(ct_out, + // parameters.rlwe_q().encode(m_expected), &ideal_sk_rlwe, + // &rlwe_modop); println!("Noise: {noise}"); } assert!(m_out == m_expected, "Expected {m_expected} but got {m_out}");@@ -513,13 +542,7 @@ });
let message = m .iter() - .map(|b| { - if *b { - parameters.rlwe_q().true_el() - } else { - parameters.rlwe_q().false_el() - } - }) + .map(|b| parameters.rlwe_q().encode(*b)) .collect_vec(); let mut m_out = vec![0u64; parameters.rlwe_n().0];
M
src/bool/parameters.rs
→
src/bool/parameters.rs
@@ -531,7 +531,19 @@ variant: ParameterVariant::NonInteractiveMultiParty,
}; #[cfg(test)] mod tests { - use crate::utils::generate_prime; + + impl BoolParameters<u64> { + pub(crate) fn default_rlwe_modop(&self) -> ModularOpsU64<CiphertextModulus<u64>> { + ModularOpsU64::new(self.rlwe_q) + } + pub(crate) fn default_rlwe_nttop(&self) -> NttBackendU64 { + NttBackendU64::new(&self.rlwe_q, self.rlwe_n.0) + } + } + + use crate::{utils::generate_prime, ModInit, ModularOpsU64, Ntt, NttBackendU64, NttInit}; + + use super::{BoolParameters, CiphertextModulus}; #[test] fn find_prime() {
M
src/lib.rs
→
src/lib.rs
@@ -183,3 +183,7 @@
pub trait KeySwitchWithId<C> { fn key_switch(&self, user_id: usize) -> C; } + +pub(crate) trait Encoder<F, T> { + fn encode(&self, v: F) -> T; +}
M
src/utils.rs
→
src/utils.rs
@@ -273,6 +273,7 @@ }
#[cfg(test)] mod tests { + use super::is_probably_prime; // let n = 1 << (11 + 1); // let mut start = 1 << 55;