commit before transation to shoup pbs
@@ -1125,14 +1125,9 @@ + GetModulus<Element = M::MatElement, M = CiphertextModulus<M::MatElement>>,
NttOp: Ntt<Element = M::MatElement>, { type Ciphertext = M::R; - type Key = ServerKeyEvaluationDomain<M, DefaultSecureRng, NttOp>; + type Key = ServerKeyEvaluationDomain<M, BoolParameters<u64>, DefaultSecureRng, NttOp>; - fn nand_inplace( - &mut self, - c0: &mut M::R, - c1: &M::R, - server_key: &ServerKeyEvaluationDomain<M, DefaultSecureRng, NttOp>, - ) { + fn nand_inplace(&mut self, c0: &mut M::R, c1: &M::R, server_key: &Self::Key) { self._add_and_shift_lwe_cts(c0, c1); // PBS@@ -1146,12 +1141,7 @@ &mut self.scratch_memory.decomposition_matrix,
); } - fn and_inplace( - &mut self, - c0: &mut M::R, - c1: &M::R, - server_key: &ServerKeyEvaluationDomain<M, DefaultSecureRng, NttOp>, - ) { + fn and_inplace(&mut self, c0: &mut M::R, c1: &M::R, server_key: &Self::Key) { self._add_and_shift_lwe_cts(c0, c1); // PBS@@ -1165,12 +1155,7 @@ &mut self.scratch_memory.decomposition_matrix,
); } - fn or_inplace( - &mut self, - c0: &mut M::R, - c1: &M::R, - server_key: &ServerKeyEvaluationDomain<M, DefaultSecureRng, NttOp>, - ) { + fn or_inplace(&mut self, c0: &mut M::R, c1: &M::R, server_key: &Self::Key) { self._add_and_shift_lwe_cts(c0, c1); // PBS@@ -1184,12 +1169,7 @@ &mut self.scratch_memory.decomposition_matrix,
); } - fn nor_inplace( - &mut self, - c0: &mut M::R, - c1: &M::R, - server_key: &ServerKeyEvaluationDomain<M, DefaultSecureRng, NttOp>, - ) { + fn nor_inplace(&mut self, c0: &mut M::R, c1: &M::R, server_key: &Self::Key) { self._add_and_shift_lwe_cts(c0, c1); // PBS@@ -1203,12 +1183,7 @@ &mut self.scratch_memory.decomposition_matrix,
) } - fn xor_inplace( - &mut self, - c0: &mut M::R, - c1: &M::R, - server_key: &ServerKeyEvaluationDomain<M, DefaultSecureRng, NttOp>, - ) { + fn xor_inplace(&mut self, c0: &mut M::R, c1: &M::R, server_key: &Self::Key) { self._subtract_double_lwe_cts(c0, c1); // PBS@@ -1222,12 +1197,7 @@ &mut self.scratch_memory.decomposition_matrix,
); } - fn xnor_inplace( - &mut self, - c0: &mut M::R, - c1: &M::R, - server_key: &ServerKeyEvaluationDomain<M, DefaultSecureRng, NttOp>, - ) { + fn xnor_inplace(&mut self, c0: &mut M::R, c1: &M::R, server_key: &Self::Key) { self._subtract_double_lwe_cts(c0, c1); // PBS@@ -1319,1084 +1289,1114 @@ out
} } -#[cfg(test)] -mod tests { - use bool::parameters::{MP_BOOL_PARAMS, SP_BOOL_PARAMS}; - use rand::{thread_rng, Rng}; - use rand_distr::Uniform; +// #[cfg(test)] +// mod tests { +// use bool::parameters::{MP_BOOL_PARAMS, SP_BOOL_PARAMS}; +// use rand::{thread_rng, Rng}; +// use rand_distr::Uniform; - use crate::{ - backend::{GetModulus, ModInit, ModularOpsU64, WordSizeModulus}, - bool::{ - self, CommonReferenceSeededMultiPartyServerKeyShare, PublicKey, - SeededMultiPartyServerKey, - }, - ntt::NttBackendU64, - random::{RandomElementInModulus, DEFAULT_RNG}, - rgsw::{ - self, measure_noise, public_key_encrypt_rlwe, secret_key_encrypt_rlwe, - tests::{_measure_noise_rgsw, _sk_encrypt_rlwe}, - RgswCiphertext, RgswCiphertextEvaluationDomain, SeededRgswCiphertext, - SeededRlweCiphertext, - }, - utils::{negacyclic_mul, Stats}, - }; +// use crate::{ +// backend::{GetModulus, ModInit, ModularOpsU64, WordSizeModulus}, +// bool::{ +// self, CommonReferenceSeededMultiPartyServerKeyShare, PublicKey, +// SeededMultiPartyServerKey, +// }, +// ntt::NttBackendU64, +// random::{RandomElementInModulus, DEFAULT_RNG}, +// rgsw::{ +// self, measure_noise, public_key_encrypt_rlwe, +// secret_key_encrypt_rlwe, tests::{_measure_noise_rgsw, +// _sk_encrypt_rlwe}, RgswCiphertext, +// RgswCiphertextEvaluationDomain, SeededRgswCiphertext, +// SeededRlweCiphertext, }, +// utils::{negacyclic_mul, Stats}, +// }; - use super::*; +// use super::*; - #[test] - fn bool_encrypt_decrypt_works() { - let bool_evaluator = BoolEvaluator::< - Vec<Vec<u64>>, - NttBackendU64, - ModularOpsU64<CiphertextModulus<u64>>, - ModularOpsU64<CiphertextModulus<u64>>, - >::new(SP_BOOL_PARAMS); - let client_key = bool_evaluator.client_key(); +// #[test] +// fn bool_encrypt_decrypt_works() { +// let bool_evaluator = BoolEvaluator::< +// Vec<Vec<u64>>, +// NttBackendU64, +// ModularOpsU64<CiphertextModulus<u64>>, +// ModularOpsU64<CiphertextModulus<u64>>, +// >::new(SP_BOOL_PARAMS); +// let client_key = bool_evaluator.client_key(); - let mut m = true; - for _ in 0..1000 { - let lwe_ct = bool_evaluator.sk_encrypt(m, &client_key); - let m_back = bool_evaluator.sk_decrypt(&lwe_ct, &client_key); - assert_eq!(m, m_back); - m = !m; - } - } +// let mut m = true; +// for _ in 0..1000 { +// let lwe_ct = bool_evaluator.sk_encrypt(m, &client_key); +// let m_back = bool_evaluator.sk_decrypt(&lwe_ct, &client_key); +// assert_eq!(m, m_back); +// m = !m; +// } +// } - #[test] - fn bool_nand() { - let mut bool_evaluator = BoolEvaluator::< - Vec<Vec<u64>>, - NttBackendU64, - ModularOpsU64<CiphertextModulus<u64>>, - ModularOpsU64<CiphertextModulus<u64>>, - >::new(SP_BOOL_PARAMS); +// #[test] +// fn bool_nand() { +// let mut bool_evaluator = BoolEvaluator::< +// Vec<Vec<u64>>, +// NttBackendU64, +// ModularOpsU64<CiphertextModulus<u64>>, +// ModularOpsU64<CiphertextModulus<u64>>, +// >::new(SP_BOOL_PARAMS); - // println!("{:?}", bool_evaluator.nand_test_vec); - let client_key = bool_evaluator.client_key(); - let seeded_server_key = bool_evaluator.server_key(&client_key); - let server_key_eval_domain = - ServerKeyEvaluationDomain::<_, DefaultSecureRng, NttBackendU64>::from( - &seeded_server_key, - ); +// // println!("{:?}", bool_evaluator.nand_test_vec); +// let client_key = bool_evaluator.client_key(); +// let seeded_server_key = bool_evaluator.server_key(&client_key); +// let server_key_eval_domain = +// ServerKeyEvaluationDomain::<_, DefaultSecureRng, +// NttBackendU64>::from( &seeded_server_key, +// ); - let mut m0 = false; - let mut m1 = true; +// let mut m0 = false; +// let mut m1 = true; - let mut ct0 = bool_evaluator.sk_encrypt(m0, &client_key); - let mut ct1 = bool_evaluator.sk_encrypt(m1, &client_key); +// let mut ct0 = bool_evaluator.sk_encrypt(m0, &client_key); +// let mut ct1 = bool_evaluator.sk_encrypt(m1, &client_key); - for _ in 0..500 { - let ct_back = bool_evaluator.nand(&ct0, &ct1, &server_key_eval_domain); +// for _ in 0..500 { +// let ct_back = bool_evaluator.nand(&ct0, &ct1, +// &server_key_eval_domain); - let m_out = !(m0 && m1); +// let m_out = !(m0 && m1); - let m_back = bool_evaluator.sk_decrypt(&ct_back, &client_key); - assert!(m_out == m_back, "Expected {m_out}, got {m_back}"); +// let m_back = bool_evaluator.sk_decrypt(&ct_back, &client_key); +// assert!(m_out == m_back, "Expected {m_out}, got {m_back}"); - m1 = m0; - m0 = m_out; +// m1 = m0; +// m0 = m_out; - ct1 = ct0; - ct0 = ct_back; - } - } +// ct1 = ct0; +// ct0 = ct_back; +// } +// } - #[test] - fn bool_xor() { - let mut bool_evaluator = BoolEvaluator::< - Vec<Vec<u64>>, - NttBackendU64, - ModularOpsU64<CiphertextModulus<u64>>, - ModularOpsU64<CiphertextModulus<u64>>, - >::new(SP_BOOL_PARAMS); +// #[test] +// fn bool_xor() { +// let mut bool_evaluator = BoolEvaluator::< +// Vec<Vec<u64>>, +// NttBackendU64, +// ModularOpsU64<CiphertextModulus<u64>>, +// ModularOpsU64<CiphertextModulus<u64>>, +// >::new(SP_BOOL_PARAMS); - // println!("{:?}", bool_evaluator.nand_test_vec); - let client_key = bool_evaluator.client_key(); - let seeded_server_key = bool_evaluator.server_key(&client_key); - let server_key_eval_domain = - ServerKeyEvaluationDomain::<_, DefaultSecureRng, NttBackendU64>::from( - &seeded_server_key, - ); +// // println!("{:?}", bool_evaluator.nand_test_vec); +// let client_key = bool_evaluator.client_key(); +// let seeded_server_key = bool_evaluator.server_key(&client_key); +// let server_key_eval_domain = +// ServerKeyEvaluationDomain::<_, DefaultSecureRng, +// NttBackendU64>::from( &seeded_server_key, +// ); - let mut m0 = false; - let mut m1 = true; +// let mut m0 = false; +// let mut m1 = true; - let mut ct0 = bool_evaluator.sk_encrypt(m0, &client_key); - let mut ct1 = bool_evaluator.sk_encrypt(m1, &client_key); +// let mut ct0 = bool_evaluator.sk_encrypt(m0, &client_key); +// let mut ct1 = bool_evaluator.sk_encrypt(m1, &client_key); - for _ in 0..1000 { - let ct_back = bool_evaluator.xor(&ct0, &ct1, &server_key_eval_domain); - let m_out = (m0 ^ m1); +// for _ in 0..1000 { +// let ct_back = bool_evaluator.xor(&ct0, &ct1, +// &server_key_eval_domain); let m_out = (m0 ^ m1); - let m_back = bool_evaluator.sk_decrypt(&ct_back, &client_key); - assert!(m_out == m_back, "Expected {m_out}, got {m_back}"); +// let m_back = bool_evaluator.sk_decrypt(&ct_back, &client_key); +// assert!(m_out == m_back, "Expected {m_out}, got {m_back}"); - m1 = m0; - m0 = m_out; +// m1 = m0; +// m0 = m_out; - ct1 = ct0; - ct0 = ct_back; - } - } +// ct1 = ct0; +// ct0 = ct_back; +// } +// } - #[test] - fn multi_party_encryption_decryption() { - let bool_evaluator = BoolEvaluator::< - Vec<Vec<u64>>, - NttBackendU64, - ModularOpsU64<CiphertextModulus<u64>>, - ModularOpsU64<CiphertextModulus<u64>>, - >::new(MP_BOOL_PARAMS); +// #[test] +// fn multi_party_encryption_decryption() { +// let bool_evaluator = BoolEvaluator::< +// Vec<Vec<u64>>, +// NttBackendU64, +// ModularOpsU64<CiphertextModulus<u64>>, +// ModularOpsU64<CiphertextModulus<u64>>, +// >::new(MP_BOOL_PARAMS); - let no_of_parties = 500; - let parties = (0..no_of_parties) - .map(|_| bool_evaluator.client_key()) - .collect_vec(); +// let no_of_parties = 500; +// let parties = (0..no_of_parties) +// .map(|_| bool_evaluator.client_key()) +// .collect_vec(); - let mut ideal_rlwe_sk = vec![0i32; bool_evaluator.pbs_info.rlwe_n()]; - parties.iter().for_each(|k| { - izip!(ideal_rlwe_sk.iter_mut(), k.sk_rlwe().values()).for_each(|(ideal_i, s_i)| { - *ideal_i = *ideal_i + s_i; - }); - }); +// let mut ideal_rlwe_sk = vec![0i32; bool_evaluator.pbs_info.rlwe_n()]; +// parties.iter().for_each(|k| { +// izip!(ideal_rlwe_sk.iter_mut(), +// k.sk_rlwe().values()).for_each(|(ideal_i, s_i)| { *ideal_i = +// *ideal_i + s_i; }); +// }); - let mut m = true; - for i in 0..100 { - let pk_cr_seed = [0u8; 32]; +// let mut m = true; +// for i in 0..100 { +// let pk_cr_seed = [0u8; 32]; - let public_key_share = parties - .iter() - .map(|k| bool_evaluator.multi_party_public_key_share(pk_cr_seed, k)) - .collect_vec(); +// let public_key_share = parties +// .iter() +// .map(|k| +// bool_evaluator.multi_party_public_key_share(pk_cr_seed, k)) +// .collect_vec(); - let collective_pk = PublicKey::< - Vec<Vec<u64>>, - DefaultSecureRng, - ModularOpsU64<CiphertextModulus<u64>>, - >::from(public_key_share.as_slice()); - let lwe_ct = bool_evaluator.pk_encrypt(collective_pk.key(), m); +// let collective_pk = PublicKey::< +// Vec<Vec<u64>>, +// DefaultSecureRng, +// ModularOpsU64<CiphertextModulus<u64>>, +// >::from(public_key_share.as_slice()); +// let lwe_ct = bool_evaluator.pk_encrypt(collective_pk.key(), m); - let decryption_shares = parties - .iter() - .map(|k| bool_evaluator.multi_party_decryption_share(&lwe_ct, k)) - .collect_vec(); +// let decryption_shares = parties +// .iter() +// .map(|k| bool_evaluator.multi_party_decryption_share(&lwe_ct, +// k)) .collect_vec(); - let m_back = bool_evaluator.multi_party_decrypt(&decryption_shares, &lwe_ct); +// let m_back = +// bool_evaluator.multi_party_decrypt(&decryption_shares, &lwe_ct); - { - let ideal_m = if m { - bool_evaluator.pbs_info.parameters.rlwe_q().true_el() - } else { - bool_evaluator.pbs_info.parameters.rlwe_q().false_el() - }; - let noise = measure_noise_lwe( - &lwe_ct, - &ideal_rlwe_sk, - &bool_evaluator.pbs_info.rlwe_modop, - &ideal_m, - ); - println!("Noise: {noise}"); - } +// { +// let ideal_m = if m { +// bool_evaluator.pbs_info.parameters.rlwe_q().true_el() +// } else { +// bool_evaluator.pbs_info.parameters.rlwe_q().false_el() +// }; +// let noise = measure_noise_lwe( +// &lwe_ct, +// &ideal_rlwe_sk, +// &bool_evaluator.pbs_info.rlwe_modop, +// &ideal_m, +// ); +// println!("Noise: {noise}"); +// } - assert_eq!(m_back, m); - m = !m; - } - } +// assert_eq!(m_back, m); +// m = !m; +// } +// } - fn _collecitve_public_key_gen(rlwe_q: u64, parties_rlwe_sk: &[RlweSecret]) -> Vec<Vec<u64>> { - let ring_size = parties_rlwe_sk[0].values.len(); - assert!(ring_size.is_power_of_two()); - let mut rng = DefaultSecureRng::new(); - let nttop = NttBackendU64::new(&rlwe_q, ring_size); - let modop = ModularOpsU64::new(rlwe_q); +// fn _collecitve_public_key_gen(rlwe_q: u64, parties_rlwe_sk: +// &[RlweSecret]) -> Vec<Vec<u64>> { let ring_size = +// parties_rlwe_sk[0].values.len(); assert!(ring_size. +// is_power_of_two()); let mut rng = DefaultSecureRng::new(); +// let nttop = NttBackendU64::new(&rlwe_q, ring_size); +// let modop = ModularOpsU64::new(rlwe_q); - // Generate Pk shares - let pk_seed = [0u8; 32]; - let pk_shares = parties_rlwe_sk.iter().map(|sk| { - let mut p_rng = DefaultSecureRng::new_seeded(pk_seed); - let mut share_out = vec![0u64; ring_size]; - public_key_share( - &mut share_out, - sk.values(), - &modop, - &nttop, - &mut p_rng, - &mut rng, - ); - share_out - }); +// // Generate Pk shares +// let pk_seed = [0u8; 32]; +// let pk_shares = parties_rlwe_sk.iter().map(|sk| { +// let mut p_rng = DefaultSecureRng::new_seeded(pk_seed); +// let mut share_out = vec![0u64; ring_size]; +// public_key_share( +// &mut share_out, +// sk.values(), +// &modop, +// &nttop, +// &mut p_rng, +// &mut rng, +// ); +// share_out +// }); - let mut pk_part_b = vec![0u64; ring_size]; - pk_shares.for_each(|share| modop.elwise_add_mut(&mut pk_part_b, &share)); - let mut pk_part_a = vec![0u64; ring_size]; - let mut p_rng = DefaultSecureRng::new_seeded(pk_seed); - RandomFillUniformInModulus::random_fill(&mut p_rng, &rlwe_q, pk_part_a.as_mut_slice()); +// let mut pk_part_b = vec![0u64; ring_size]; +// pk_shares.for_each(|share| modop.elwise_add_mut(&mut pk_part_b, +// &share)); let mut pk_part_a = vec![0u64; ring_size]; +// let mut p_rng = DefaultSecureRng::new_seeded(pk_seed); +// RandomFillUniformInModulus::random_fill(&mut p_rng, &rlwe_q, +// pk_part_a.as_mut_slice()); - vec![pk_part_a, pk_part_b] - } +// vec![pk_part_a, pk_part_b] +// } - fn _multi_party_all_keygen( - bool_evaluator: &BoolEvaluator< - Vec<Vec<u64>>, - NttBackendU64, - ModularOpsU64<CiphertextModulus<u64>>, - ModularOpsU64<CiphertextModulus<u64>>, - >, - no_of_parties: usize, - ) -> ( - Vec<ClientKey>, - PublicKey<Vec<Vec<u64>>, DefaultSecureRng, ModularOpsU64<CiphertextModulus<u64>>>, - Vec< - CommonReferenceSeededMultiPartyServerKeyShare< - Vec<Vec<u64>>, - BoolParameters<u64>, - [u8; 32], - >, - >, - SeededMultiPartyServerKey<Vec<Vec<u64>>, [u8; 32], BoolParameters<u64>>, - ServerKeyEvaluationDomain<Vec<Vec<u64>>, DefaultSecureRng, NttBackendU64>, - ClientKey, - ) { - let parties = (0..no_of_parties) - .map(|_| bool_evaluator.client_key()) - .collect_vec(); +// fn _multi_party_all_keygen( +// bool_evaluator: &BoolEvaluator< +// Vec<Vec<u64>>, +// NttBackendU64, +// ModularOpsU64<CiphertextModulus<u64>>, +// ModularOpsU64<CiphertextModulus<u64>>, +// >, +// no_of_parties: usize, +// ) -> ( +// Vec<ClientKey>, +// PublicKey<Vec<Vec<u64>>, DefaultSecureRng, +// ModularOpsU64<CiphertextModulus<u64>>>, Vec< +// CommonReferenceSeededMultiPartyServerKeyShare< +// Vec<Vec<u64>>, +// BoolParameters<u64>, +// [u8; 32], +// >, +// >, +// SeededMultiPartyServerKey<Vec<Vec<u64>>, [u8; 32], +// BoolParameters<u64>>, ServerKeyEvaluationDomain<Vec<Vec<u64>>, +// DefaultSecureRng, NttBackendU64>, ClientKey, +// ) { +// let parties = (0..no_of_parties) +// .map(|_| bool_evaluator.client_key()) +// .collect_vec(); - let mut rng = DefaultSecureRng::new(); +// let mut rng = DefaultSecureRng::new(); - // Collective public key - let mut pk_cr_seed = [0u8; 32]; - rng.fill_bytes(&mut pk_cr_seed); - let public_key_share = parties - .iter() - .map(|k| bool_evaluator.multi_party_public_key_share(pk_cr_seed, k)) - .collect_vec(); - let collective_pk = - PublicKey::<Vec<Vec<u64>>, DefaultSecureRng, _>::from(public_key_share.as_slice()); +// // Collective public key +// let mut pk_cr_seed = [0u8; 32]; +// rng.fill_bytes(&mut pk_cr_seed); +// let public_key_share = parties +// .iter() +// .map(|k| bool_evaluator.multi_party_public_key_share(pk_cr_seed, +// k)) .collect_vec(); +// let collective_pk = +// PublicKey::<Vec<Vec<u64>>, DefaultSecureRng, +// _>::from(public_key_share.as_slice()); - // Server key - let mut pbs_cr_seed = [0u8; 32]; - rng.fill_bytes(&mut pbs_cr_seed); - let server_key_shares = parties - .iter() - .map(|k| { - bool_evaluator.multi_party_server_key_share(pbs_cr_seed, &collective_pk.key(), k) - }) - .collect_vec(); - let seeded_server_key = - bool_evaluator.aggregate_multi_party_server_key_shares(&server_key_shares); - let server_key_eval = ServerKeyEvaluationDomain::<_, DefaultSecureRng, NttBackendU64>::from( - &seeded_server_key, - ); +// // Server key +// let mut pbs_cr_seed = [0u8; 32]; +// rng.fill_bytes(&mut pbs_cr_seed); +// let server_key_shares = parties +// .iter() +// .map(|k| { +// bool_evaluator.multi_party_server_key_share(pbs_cr_seed, +// &collective_pk.key(), k) }) +// .collect_vec(); +// let seeded_server_key = +// +// bool_evaluator.aggregate_multi_party_server_key_shares(&server_key_shares); +// let server_key_eval = ServerKeyEvaluationDomain::<_, +// DefaultSecureRng, NttBackendU64>::from( &seeded_server_key, +// ); - // construct ideal rlwe sk for meauring noise - let ideal_client_key = { - let mut ideal_rlwe_sk = vec![0i32; bool_evaluator.pbs_info.rlwe_n()]; - parties.iter().for_each(|k| { - izip!(ideal_rlwe_sk.iter_mut(), k.sk_rlwe().values()).for_each(|(ideal_i, s_i)| { - *ideal_i = *ideal_i + s_i; - }); - }); - let mut ideal_lwe_sk = vec![0i32; bool_evaluator.pbs_info.lwe_n()]; - parties.iter().for_each(|k| { - izip!(ideal_lwe_sk.iter_mut(), k.sk_lwe().values()).for_each(|(ideal_i, s_i)| { - *ideal_i = *ideal_i + s_i; - }); - }); +// // construct ideal rlwe sk for meauring noise +// let ideal_client_key = { +// let mut ideal_rlwe_sk = vec![0i32; +// bool_evaluator.pbs_info.rlwe_n()]; parties.iter().for_each(|k| { +// izip!(ideal_rlwe_sk.iter_mut(), +// k.sk_rlwe().values()).for_each(|(ideal_i, s_i)| { +// *ideal_i = *ideal_i + s_i; }); +// }); +// let mut ideal_lwe_sk = vec![0i32; +// bool_evaluator.pbs_info.lwe_n()]; parties.iter().for_each(|k| { +// izip!(ideal_lwe_sk.iter_mut(), +// k.sk_lwe().values()).for_each(|(ideal_i, s_i)| { *ideal_i +// = *ideal_i + s_i; }); +// }); - ClientKey::new( - RlweSecret { - values: ideal_rlwe_sk, - }, - LweSecret { - values: ideal_lwe_sk, - }, - ) - }; +// ClientKey::new( +// RlweSecret { +// values: ideal_rlwe_sk, +// }, +// LweSecret { +// values: ideal_lwe_sk, +// }, +// ) +// }; - ( - parties, - collective_pk, - server_key_shares, - seeded_server_key, - server_key_eval, - ideal_client_key, - ) - } +// ( +// parties, +// collective_pk, +// server_key_shares, +// seeded_server_key, +// server_key_eval, +// ideal_client_key, +// ) +// } - #[test] - fn multi_party_nand() { - let mut bool_evaluator = BoolEvaluator::< - Vec<Vec<u64>>, - NttBackendU64, - ModularOpsU64<CiphertextModulus<u64>>, - ModularOpsU64<CiphertextModulus<u64>>, - >::new(MP_BOOL_PARAMS); +// #[test] +// fn multi_party_nand() { +// let mut bool_evaluator = BoolEvaluator::< +// Vec<Vec<u64>>, +// NttBackendU64, +// ModularOpsU64<CiphertextModulus<u64>>, +// ModularOpsU64<CiphertextModulus<u64>>, +// >::new(MP_BOOL_PARAMS); - let (parties, collective_pk, _, _, server_key_eval, ideal_client_key) = - _multi_party_all_keygen(&bool_evaluator, 2); +// let (parties, collective_pk, _, _, server_key_eval, ideal_client_key) +// = _multi_party_all_keygen(&bool_evaluator, 2); - let mut m0 = true; - let mut m1 = false; +// let mut m0 = true; +// let mut m1 = false; - let mut lwe0 = bool_evaluator.pk_encrypt(collective_pk.key(), m0); - let mut lwe1 = bool_evaluator.pk_encrypt(collective_pk.key(), m1); +// let mut lwe0 = bool_evaluator.pk_encrypt(collective_pk.key(), m0); +// let mut lwe1 = bool_evaluator.pk_encrypt(collective_pk.key(), m1); - for _ in 0..2000 { - let lwe_out = bool_evaluator.nand(&lwe0, &lwe1, &server_key_eval); +// for _ in 0..2000 { +// let lwe_out = bool_evaluator.nand(&lwe0, &lwe1, +// &server_key_eval); - let m_expected = !(m0 & m1); +// let m_expected = !(m0 & m1); - // multi-party decrypt - let decryption_shares = parties - .iter() - .map(|k| bool_evaluator.multi_party_decryption_share(&lwe_out, k)) - .collect_vec(); - let m_back = bool_evaluator.multi_party_decrypt(&decryption_shares, &lwe_out); +// // multi-party decrypt +// let decryption_shares = parties +// .iter() +// .map(|k| +// bool_evaluator.multi_party_decryption_share(&lwe_out, k)) +// .collect_vec(); let m_back = +// bool_evaluator.multi_party_decrypt(&decryption_shares, &lwe_out); - // let m_back = bool_evaluator.sk_decrypt(&lwe_out, &ideal_client_key); +// // let m_back = bool_evaluator.sk_decrypt(&lwe_out, +// &ideal_client_key); - assert!(m_expected == m_back, "Expected {m_expected}, got {m_back}"); - m1 = m0; - m0 = m_expected; +// assert!(m_expected == m_back, "Expected {m_expected}, got +// {m_back}"); m1 = m0; +// m0 = m_expected; - lwe1 = lwe0; - lwe0 = lwe_out; - } - } +// lwe1 = lwe0; +// lwe0 = lwe_out; +// } +// } - #[test] - fn noise_tester() { - let bool_evaluator = BoolEvaluator::< - Vec<Vec<u64>>, - NttBackendU64, - ModularOpsU64<CiphertextModulus<u64>>, - ModularOpsU64<CiphertextModulus<u64>>, - >::new(SP_BOOL_PARAMS); +// #[test] +// fn noise_tester() { +// let bool_evaluator = BoolEvaluator::< +// Vec<Vec<u64>>, +// NttBackendU64, +// ModularOpsU64<CiphertextModulus<u64>>, +// ModularOpsU64<CiphertextModulus<u64>>, +// >::new(SP_BOOL_PARAMS); - // let (_, collective_pk, _, _, server_key_eval, ideal_client_key) = - // _multi_party_all_keygen(&bool_evaluator, 20); - let no_of_parties = 2; - let lwe_q = bool_evaluator.pbs_info.parameters.lwe_q(); - let rlwe_q = bool_evaluator.pbs_info.parameters.rlwe_q(); - let lwe_n = bool_evaluator.pbs_info.parameters.lwe_n().0; - let rlwe_n = bool_evaluator.pbs_info.parameters.rlwe_n().0; - let lwe_modop = &bool_evaluator.pbs_info.lwe_modop; - let rlwe_nttop = &bool_evaluator.pbs_info.rlwe_nttop; - let rlwe_modop = &bool_evaluator.pbs_info.rlwe_modop; +// // let (_, collective_pk, _, _, server_key_eval, ideal_client_key) = +// // _multi_party_all_keygen(&bool_evaluator, 20); +// let no_of_parties = 2; +// let lwe_q = bool_evaluator.pbs_info.parameters.lwe_q(); +// let rlwe_q = bool_evaluator.pbs_info.parameters.rlwe_q(); +// let lwe_n = bool_evaluator.pbs_info.parameters.lwe_n().0; +// let rlwe_n = bool_evaluator.pbs_info.parameters.rlwe_n().0; +// let lwe_modop = &bool_evaluator.pbs_info.lwe_modop; +// let rlwe_nttop = &bool_evaluator.pbs_info.rlwe_nttop; +// let rlwe_modop = &bool_evaluator.pbs_info.rlwe_modop; - // let rgsw_rgsw_decomposer = &bool_evaluator - // .pbs_info - // .parameters - // .rgsw_rgsw_decomposer::<DefaultDecomposer<u64>>(); - // let rgsw_rgsw_gadget_a = rgsw_rgsw_decomposer.0.gadget_vector(); - // let rgsw_rgsw_gadget_b = rgsw_rgsw_decomposer.1.gadget_vector(); +// // let rgsw_rgsw_decomposer = &bool_evaluator +// // .pbs_info +// // .parameters +// // .rgsw_rgsw_decomposer::<DefaultDecomposer<u64>>(); +// // let rgsw_rgsw_gadget_a = rgsw_rgsw_decomposer.0.gadget_vector(); +// // let rgsw_rgsw_gadget_b = rgsw_rgsw_decomposer.1.gadget_vector(); - let rlwe_rgsw_decomposer = &bool_evaluator.pbs_info.rlwe_rgsw_decomposer; - let rlwe_rgsw_gadget_a = rlwe_rgsw_decomposer.0.gadget_vector(); - let rlwe_rgsw_gadget_b = rlwe_rgsw_decomposer.1.gadget_vector(); +// let rlwe_rgsw_decomposer = +// &bool_evaluator.pbs_info.rlwe_rgsw_decomposer; let rlwe_rgsw_gadget_a +// = rlwe_rgsw_decomposer.0.gadget_vector(); let rlwe_rgsw_gadget_b = +// rlwe_rgsw_decomposer.1.gadget_vector(); - let auto_decomposer = &bool_evaluator.pbs_info.auto_decomposer; - let auto_gadget = auto_decomposer.gadget_vector(); +// let auto_decomposer = &bool_evaluator.pbs_info.auto_decomposer; +// let auto_gadget = auto_decomposer.gadget_vector(); - let parties = (0..no_of_parties) - .map(|_| bool_evaluator.client_key()) - .collect_vec(); +// let parties = (0..no_of_parties) +// .map(|_| bool_evaluator.client_key()) +// .collect_vec(); - let ideal_client_key = { - let mut ideal_rlwe_sk = vec![0i32; bool_evaluator.pbs_info.rlwe_n()]; - parties.iter().for_each(|k| { - izip!(ideal_rlwe_sk.iter_mut(), k.sk_rlwe().values()).for_each(|(ideal_i, s_i)| { - *ideal_i = *ideal_i + s_i; - }); - }); - let mut ideal_lwe_sk = vec![0i32; bool_evaluator.pbs_info.lwe_n()]; - parties.iter().for_each(|k| { - izip!(ideal_lwe_sk.iter_mut(), k.sk_lwe().values()).for_each(|(ideal_i, s_i)| { - *ideal_i = *ideal_i + s_i; - }); - }); +// let ideal_client_key = { +// let mut ideal_rlwe_sk = vec![0i32; +// bool_evaluator.pbs_info.rlwe_n()]; parties.iter().for_each(|k| { +// izip!(ideal_rlwe_sk.iter_mut(), +// k.sk_rlwe().values()).for_each(|(ideal_i, s_i)| { +// *ideal_i = *ideal_i + s_i; }); +// }); +// let mut ideal_lwe_sk = vec![0i32; +// bool_evaluator.pbs_info.lwe_n()]; parties.iter().for_each(|k| { +// izip!(ideal_lwe_sk.iter_mut(), +// k.sk_lwe().values()).for_each(|(ideal_i, s_i)| { *ideal_i +// = *ideal_i + s_i; }); +// }); - ClientKey::new( - RlweSecret { - values: ideal_rlwe_sk, - }, - LweSecret { - values: ideal_lwe_sk, - }, - ) - }; +// ClientKey::new( +// RlweSecret { +// values: ideal_rlwe_sk, +// }, +// LweSecret { +// values: ideal_lwe_sk, +// }, +// ) +// }; - // check noise in freshly encrypted RLWE ciphertext (ie var_fresh) - if true { - let mut rng = DefaultSecureRng::new(); - let mut check = Stats { samples: vec![] }; - for _ in 0..10 { - // generate a new collective public key - let mut pk_cr_seed = [0u8; 32]; - rng.fill_bytes(&mut pk_cr_seed); - let public_key_share = parties - .iter() - .map(|k| bool_evaluator.multi_party_public_key_share(pk_cr_seed, k)) - .collect_vec(); - let collective_pk = PublicKey::< - Vec<Vec<u64>>, - DefaultSecureRng, - ModularOpsU64<CiphertextModulus<u64>>, - >::from(public_key_share.as_slice()); +// // check noise in freshly encrypted RLWE ciphertext (ie var_fresh) +// if true { +// let mut rng = DefaultSecureRng::new(); +// let mut check = Stats { samples: vec![] }; +// for _ in 0..10 { +// // generate a new collective public key +// let mut pk_cr_seed = [0u8; 32]; +// rng.fill_bytes(&mut pk_cr_seed); +// let public_key_share = parties +// .iter() +// .map(|k| +// bool_evaluator.multi_party_public_key_share(pk_cr_seed, k)) +// .collect_vec(); let collective_pk = PublicKey::< +// Vec<Vec<u64>>, +// DefaultSecureRng, +// ModularOpsU64<CiphertextModulus<u64>>, +// >::from(public_key_share.as_slice()); - let mut m = vec![0u64; rlwe_n]; - RandomFillUniformInModulus::random_fill(&mut rng, rlwe_q, m.as_mut_slice()); - let mut rlwe_ct = vec![vec![0u64; rlwe_n]; 2]; - public_key_encrypt_rlwe::<_, _, _, _, i32, _>( - &mut rlwe_ct, - collective_pk.key(), - &m, - rlwe_modop, - rlwe_nttop, - &mut rng, - ); +// let mut m = vec![0u64; rlwe_n]; +// RandomFillUniformInModulus::random_fill(&mut rng, rlwe_q, +// m.as_mut_slice()); let mut rlwe_ct = vec![vec![0u64; rlwe_n]; +// 2]; public_key_encrypt_rlwe::<_, _, _, _, i32, _>( +// &mut rlwe_ct, +// collective_pk.key(), +// &m, +// rlwe_modop, +// rlwe_nttop, +// &mut rng, +// ); - let mut m_back = vec![0u64; rlwe_n]; - decrypt_rlwe( - &rlwe_ct, - ideal_client_key.sk_rlwe().values(), - &mut m_back, - rlwe_nttop, - rlwe_modop, - ); +// let mut m_back = vec![0u64; rlwe_n]; +// decrypt_rlwe( +// &rlwe_ct, +// ideal_client_key.sk_rlwe().values(), +// &mut m_back, +// rlwe_nttop, +// rlwe_modop, +// ); - rlwe_modop.elwise_sub_mut(m_back.as_mut_slice(), m.as_slice()); +// rlwe_modop.elwise_sub_mut(m_back.as_mut_slice(), +// m.as_slice()); - check.add_more(Vec::<i64>::try_convert_from(&m_back, rlwe_q).as_slice()); - } +// check.add_more(Vec::<i64>::try_convert_from(&m_back, +// rlwe_q).as_slice()); } - println!("Public key Std: {}", check.std_dev().abs().log2()); - } +// println!("Public key Std: {}", check.std_dev().abs().log2()); +// } - if true { - // Generate server key shares - let mut rng = DefaultSecureRng::new(); - let mut pk_cr_seed = [0u8; 32]; - rng.fill_bytes(&mut pk_cr_seed); - let public_key_share = parties - .iter() - .map(|k| bool_evaluator.multi_party_public_key_share(pk_cr_seed, k)) - .collect_vec(); - let collective_pk = PublicKey::< - Vec<Vec<u64>>, - DefaultSecureRng, - ModularOpsU64<CiphertextModulus<u64>>, - >::from(public_key_share.as_slice()); +// if true { +// // Generate server key shares +// let mut rng = DefaultSecureRng::new(); +// let mut pk_cr_seed = [0u8; 32]; +// rng.fill_bytes(&mut pk_cr_seed); +// let public_key_share = parties +// .iter() +// .map(|k| +// bool_evaluator.multi_party_public_key_share(pk_cr_seed, k)) +// .collect_vec(); let collective_pk = PublicKey::< +// Vec<Vec<u64>>, +// DefaultSecureRng, +// ModularOpsU64<CiphertextModulus<u64>>, +// >::from(public_key_share.as_slice()); - let pbs_cr_seed = [0u8; 32]; - rng.fill_bytes(&mut pk_cr_seed); - let server_key_shares = parties - .iter() - .map(|k| { - bool_evaluator.multi_party_server_key_share(pbs_cr_seed, collective_pk.key(), k) - }) - .collect_vec(); +// let pbs_cr_seed = [0u8; 32]; +// rng.fill_bytes(&mut pk_cr_seed); +// let server_key_shares = parties +// .iter() +// .map(|k| { +// bool_evaluator.multi_party_server_key_share(pbs_cr_seed, +// collective_pk.key(), k) }) +// .collect_vec(); - let seeded_server_key = - bool_evaluator.aggregate_multi_party_server_key_shares(&server_key_shares); +// let seeded_server_key = +// +// bool_evaluator.aggregate_multi_party_server_key_shares(&server_key_shares); - // Check noise in RGSW ciphertexts of ideal LWE secret elements - if false { - let mut check = Stats { samples: vec![] }; - izip!( - ideal_client_key.sk_lwe().values.iter(), - seeded_server_key.rgsw_cts().iter() - ) - .for_each(|(s_i, rgsw_ct_i)| { - // X^{s[i]} - let mut m_si = vec![0u64; rlwe_n]; - let s_i = *s_i * (bool_evaluator.pbs_info.embedding_factor as i32); - if s_i < 0 { - m_si[rlwe_n - (s_i.abs() as usize)] = rlwe_q.neg_one(); - } else { - m_si[s_i as usize] = 1; - } +// // Check noise in RGSW ciphertexts of ideal LWE secret elements +// if false { +// let mut check = Stats { samples: vec![] }; +// izip!( +// ideal_client_key.sk_lwe().values.iter(), +// seeded_server_key.rgsw_cts().iter() +// ) +// .for_each(|(s_i, rgsw_ct_i)| { +// // X^{s[i]} +// let mut m_si = vec![0u64; rlwe_n]; +// let s_i = *s_i * +// (bool_evaluator.pbs_info.embedding_factor as i32); if s_i +// < 0 { m_si[rlwe_n - (s_i.abs() as usize)] = +// rlwe_q.neg_one(); } else { +// m_si[s_i as usize] = 1; +// } - // RLWE'(-sm) - let mut neg_s_eval = - Vec::<u64>::try_convert_from(ideal_client_key.sk_rlwe().values(), rlwe_q); - rlwe_modop.elwise_neg_mut(&mut neg_s_eval); - rlwe_nttop.forward(&mut neg_s_eval); - for j in 0..rlwe_rgsw_decomposer.a().decomposition_count() { - // RLWE(B^{j} * -s[X]*X^{s_lwe[i]}) +// // RLWE'(-sm) +// let mut neg_s_eval = +// +// Vec::<u64>::try_convert_from(ideal_client_key.sk_rlwe().values(), rlwe_q); +// rlwe_modop.elwise_neg_mut(&mut neg_s_eval); +// rlwe_nttop.forward(&mut neg_s_eval); +// for j in +// 0..rlwe_rgsw_decomposer.a().decomposition_count() { +// // RLWE(B^{j} * -s[X]*X^{s_lwe[i]}) - // -s[X]*X^{s_lwe[i]}*B_j - let mut m_ideal = m_si.clone(); - rlwe_nttop.forward(m_ideal.as_mut_slice()); - rlwe_modop.elwise_mul_mut(m_ideal.as_mut_slice(), neg_s_eval.as_slice()); - rlwe_nttop.backward(m_ideal.as_mut_slice()); - rlwe_modop - .elwise_scalar_mul_mut(m_ideal.as_mut_slice(), &rlwe_rgsw_gadget_a[j]); +// // -s[X]*X^{s_lwe[i]}*B_j +// let mut m_ideal = m_si.clone(); +// rlwe_nttop.forward(m_ideal.as_mut_slice()); +// rlwe_modop.elwise_mul_mut(m_ideal.as_mut_slice(), +// neg_s_eval.as_slice()); +// rlwe_nttop.backward(m_ideal.as_mut_slice()); +// rlwe_modop +// .elwise_scalar_mul_mut(m_ideal.as_mut_slice(), &rlwe_rgsw_gadget_a[j]); - // RLWE(-s*X^{s_lwe[i]}*B_j) - let mut rlwe_ct = vec![vec![0u64; rlwe_n]; 2]; - rlwe_ct[0].copy_from_slice(&rgsw_ct_i[j]); - rlwe_ct[1].copy_from_slice( - &rgsw_ct_i[j + rlwe_rgsw_decomposer.a().decomposition_count()], - ); +// // RLWE(-s*X^{s_lwe[i]}*B_j) +// let mut rlwe_ct = vec![vec![0u64; rlwe_n]; 2]; +// rlwe_ct[0].copy_from_slice(&rgsw_ct_i[j]); +// rlwe_ct[1].copy_from_slice( +// &rgsw_ct_i[j + +// rlwe_rgsw_decomposer.a().decomposition_count()], ); - let mut m_back = vec![0u64; rlwe_n]; - decrypt_rlwe( - &rlwe_ct, - ideal_client_key.sk_rlwe().values(), - &mut m_back, - rlwe_nttop, - rlwe_modop, - ); +// let mut m_back = vec![0u64; rlwe_n]; +// decrypt_rlwe( +// &rlwe_ct, +// ideal_client_key.sk_rlwe().values(), +// &mut m_back, +// rlwe_nttop, +// rlwe_modop, +// ); - // diff - rlwe_modop.elwise_sub_mut(&mut m_back, &m_ideal); - check.add_more(&Vec::<i64>::try_convert_from(&m_back, rlwe_q)); - } +// // diff +// rlwe_modop.elwise_sub_mut(&mut m_back, &m_ideal); +// check.add_more(&Vec::<i64>::try_convert_from(&m_back, +// rlwe_q)); } - // RLWE'(m) - for j in 0..rlwe_rgsw_decomposer.b().decomposition_count() { - // RLWE(B^{j} * X^{s_lwe[i]}) +// // RLWE'(m) +// for j in +// 0..rlwe_rgsw_decomposer.b().decomposition_count() { +// // RLWE(B^{j} * X^{s_lwe[i]}) - // X^{s_lwe[i]}*B_j - let mut m_ideal = m_si.clone(); - rlwe_modop - .elwise_scalar_mul_mut(m_ideal.as_mut_slice(), &rlwe_rgsw_gadget_b[j]); +// // X^{s_lwe[i]}*B_j +// let mut m_ideal = m_si.clone(); +// rlwe_modop +// .elwise_scalar_mul_mut(m_ideal.as_mut_slice(), +// &rlwe_rgsw_gadget_b[j]); - // RLWE(X^{s_lwe[i]}*B_j) - let mut rlwe_ct = vec![vec![0u64; rlwe_n]; 2]; - rlwe_ct[0].copy_from_slice( - &rgsw_ct_i[j + (2 * rlwe_rgsw_decomposer.a().decomposition_count())], - ); - rlwe_ct[1].copy_from_slice( - &rgsw_ct_i[j - + (2 * rlwe_rgsw_decomposer.a().decomposition_count() - + rlwe_rgsw_decomposer.b().decomposition_count())], - ); +// // RLWE(X^{s_lwe[i]}*B_j) +// let mut rlwe_ct = vec![vec![0u64; rlwe_n]; 2]; +// rlwe_ct[0].copy_from_slice( +// &rgsw_ct_i[j + (2 * +// rlwe_rgsw_decomposer.a().decomposition_count())], ); +// rlwe_ct[1].copy_from_slice( +// &rgsw_ct_i[j +// + (2 * rlwe_rgsw_decomposer.a(). +// decomposition_count() +// + rlwe_rgsw_decomposer.b(). +// decomposition_count())], +// ); - let mut m_back = vec![0u64; rlwe_n]; - decrypt_rlwe( - &rlwe_ct, - ideal_client_key.sk_rlwe().values(), - &mut m_back, - rlwe_nttop, - rlwe_modop, - ); +// let mut m_back = vec![0u64; rlwe_n]; +// decrypt_rlwe( +// &rlwe_ct, +// ideal_client_key.sk_rlwe().values(), +// &mut m_back, +// rlwe_nttop, +// rlwe_modop, +// ); - // diff - rlwe_modop.elwise_sub_mut(&mut m_back, &m_ideal); - check.add_more(&Vec::<i64>::try_convert_from(&m_back, rlwe_q)); - } - }); - println!( - "RGSW Std: {} {} ;; max={}", - check.mean(), - check.std_dev().abs().log2(), - check.samples.iter().max().unwrap() - ); - } +// // diff +// rlwe_modop.elwise_sub_mut(&mut m_back, &m_ideal); +// check.add_more(&Vec::<i64>::try_convert_from(&m_back, +// rlwe_q)); } +// }); +// println!( +// "RGSW Std: {} {} ;; max={}", +// check.mean(), +// check.std_dev().abs().log2(), +// check.samples.iter().max().unwrap() +// ); +// } - // server key in Evaluation domain - let server_key_eval_domain = - ServerKeyEvaluationDomain::<_, DefaultSecureRng, NttBackendU64>::from( - &seeded_server_key, - ); +// // server key in Evaluation domain +// let server_key_eval_domain = +// ServerKeyEvaluationDomain::<_, DefaultSecureRng, +// NttBackendU64>::from( &seeded_server_key, +// ); - // check noise in RLWE x RGSW(X^{s_i}) where RGSW is accunulated RGSW ciphertext - if false { - let mut check = Stats { samples: vec![] }; +// // check noise in RLWE x RGSW(X^{s_i}) where RGSW is accunulated +// RGSW ciphertext if false { +// let mut check = Stats { samples: vec![] }; - izip!( - ideal_client_key.sk_lwe().values(), - server_key_eval_domain.rgsw_cts().iter() - ) - .for_each(|(s_i, rgsw_ct_i)| { - let mut m = vec![0u64; rlwe_n]; - RandomFillUniformInModulus::random_fill(&mut rng, rlwe_q, m.as_mut_slice()); - let mut rlwe_ct = vec![vec![0u64; rlwe_n]; 2]; - public_key_encrypt_rlwe::<_, _, _, _, i32, _>( - &mut rlwe_ct, - collective_pk.key(), - &m, - rlwe_modop, - rlwe_nttop, - &mut rng, - ); +// izip!( +// ideal_client_key.sk_lwe().values(), +// server_key_eval_domain.rgsw_cts().iter() +// ) +// .for_each(|(s_i, rgsw_ct_i)| { +// let mut m = vec![0u64; rlwe_n]; +// RandomFillUniformInModulus::random_fill(&mut rng, rlwe_q, +// m.as_mut_slice()); let mut rlwe_ct = vec![vec![0u64; +// rlwe_n]; 2]; public_key_encrypt_rlwe::<_, _, _, _, i32, +// _>( &mut rlwe_ct, +// collective_pk.key(), +// &m, +// rlwe_modop, +// rlwe_nttop, +// &mut rng, +// ); - // RLWE(m*X^{s[i]}) = RLWE(m) x RGSW(X^{s[i]}) - // let mut rlwe_after = RlweCiphertext::<_, DefaultSecureRng>::new_trivial(vec![ - // vec![0u64; rlwe_n], - // m.clone(), - // ]); - let mut rlwe_after = RlweCiphertext::<_, DefaultSecureRng> { - data: rlwe_ct.clone(), - is_trivial: false, - _phatom: PhantomData, - }; - let mut scratch = vec![ - vec![0u64; rlwe_n]; - std::cmp::max( - rlwe_rgsw_decomposer.0.decomposition_count(), - rlwe_rgsw_decomposer.1.decomposition_count() - ) + 2 - ]; - rlwe_by_rgsw( - &mut rlwe_after, - rgsw_ct_i, - &mut scratch, - rlwe_rgsw_decomposer, - rlwe_nttop, - rlwe_modop, - ); +// // RLWE(m*X^{s[i]}) = RLWE(m) x RGSW(X^{s[i]}) +// // let mut rlwe_after = RlweCiphertext::<_, +// DefaultSecureRng>::new_trivial(vec![ // vec![0u64; +// rlwe_n], // m.clone(), +// // ]); +// let mut rlwe_after = RlweCiphertext::<_, +// DefaultSecureRng> { data: rlwe_ct.clone(), +// is_trivial: false, +// _phatom: PhantomData, +// }; +// let mut scratch = vec![ +// vec![0u64; rlwe_n]; +// std::cmp::max( +// rlwe_rgsw_decomposer.0.decomposition_count(), +// rlwe_rgsw_decomposer.1.decomposition_count() +// ) + 2 +// ]; +// rlwe_by_rgsw( +// &mut rlwe_after, +// rgsw_ct_i, +// &mut scratch, +// rlwe_rgsw_decomposer, +// rlwe_nttop, +// rlwe_modop, +// ); - // m1 = X^{s[i]} - let mut m1 = vec![0u64; rlwe_n]; - let s_i = *s_i * (bool_evaluator.pbs_info.embedding_factor as i32); - if s_i < 0 { - m1[rlwe_n - (s_i.abs() as usize)] = rlwe_q.neg_one() - } else { - m1[s_i as usize] = 1; - } +// // m1 = X^{s[i]} +// let mut m1 = vec![0u64; rlwe_n]; +// let s_i = *s_i * +// (bool_evaluator.pbs_info.embedding_factor as i32); if s_i +// < 0 { m1[rlwe_n - (s_i.abs() as usize)] = +// rlwe_q.neg_one() } else { +// m1[s_i as usize] = 1; +// } - // (m+e) * m1 - let mut m_plus_e_times_m1 = vec![0u64; rlwe_n]; - decrypt_rlwe( - &rlwe_ct, - ideal_client_key.sk_rlwe().values(), - &mut m_plus_e_times_m1, - rlwe_nttop, - rlwe_modop, - ); - rlwe_nttop.forward(m_plus_e_times_m1.as_mut_slice()); - rlwe_nttop.forward(m1.as_mut_slice()); - rlwe_modop.elwise_mul_mut(m_plus_e_times_m1.as_mut_slice(), m1.as_slice()); - rlwe_nttop.backward(m_plus_e_times_m1.as_mut_slice()); +// // (m+e) * m1 +// let mut m_plus_e_times_m1 = vec![0u64; rlwe_n]; +// decrypt_rlwe( +// &rlwe_ct, +// ideal_client_key.sk_rlwe().values(), +// &mut m_plus_e_times_m1, +// rlwe_nttop, +// rlwe_modop, +// ); +// rlwe_nttop.forward(m_plus_e_times_m1.as_mut_slice()); +// rlwe_nttop.forward(m1.as_mut_slice()); +// +// rlwe_modop.elwise_mul_mut(m_plus_e_times_m1.as_mut_slice(), m1.as_slice()); +// rlwe_nttop.backward(m_plus_e_times_m1.as_mut_slice()); - // Resulting RLWE ciphertext will equal: (m0m1 + em1) + e_{rlsw x rgsw}. - // Hence, resulting rlwe ciphertext will have error em1 + e_{rlwe x rgsw}. - // Here we're only concerned with e_{rlwe x rgsw}, that is noise added by - // RLWExRGSW. Also note in practice m1 is a monomial, for ex, X^{s_{i}}, for - // some i and var(em1) = var(e). - let mut m_plus_e_times_m1_more_e = vec![0u64; rlwe_n]; - decrypt_rlwe( - &rlwe_after, - ideal_client_key.sk_rlwe().values(), - &mut m_plus_e_times_m1_more_e, - rlwe_nttop, - rlwe_modop, - ); +// // Resulting RLWE ciphertext will equal: (m0m1 + em1) + +// e_{rlsw x rgsw}. // Hence, resulting rlwe ciphertext will +// have error em1 + e_{rlwe x rgsw}. // Here we're only +// concerned with e_{rlwe x rgsw}, that is noise added by // +// RLWExRGSW. Also note in practice m1 is a monomial, for ex, X^{s_{i}}, for +// // some i and var(em1) = var(e). +// let mut m_plus_e_times_m1_more_e = vec![0u64; rlwe_n]; +// decrypt_rlwe( +// &rlwe_after, +// ideal_client_key.sk_rlwe().values(), +// &mut m_plus_e_times_m1_more_e, +// rlwe_nttop, +// rlwe_modop, +// ); - // diff - rlwe_modop.elwise_sub_mut( - m_plus_e_times_m1_more_e.as_mut_slice(), - m_plus_e_times_m1.as_slice(), - ); +// // diff +// rlwe_modop.elwise_sub_mut( +// m_plus_e_times_m1_more_e.as_mut_slice(), +// m_plus_e_times_m1.as_slice(), +// ); - // let noise = measure_noise( - // &rlwe_after, - // &m_plus_e_times_m1, - // rlwe_nttop, - // rlwe_modop, - // ideal_client_key.sk_rlwe.values(), - // ); - // print!("NOISE: {}", noise); +// // let noise = measure_noise( +// // &rlwe_after, +// // &m_plus_e_times_m1, +// // rlwe_nttop, +// // rlwe_modop, +// // ideal_client_key.sk_rlwe.values(), +// // ); +// // print!("NOISE: {}", noise); - check.add_more(&Vec::<i64>::try_convert_from( - &m_plus_e_times_m1_more_e, - rlwe_q, - )); - }); - println!( - "RLWE x RGSW, where RGSW has noise var_brk, std: {} {}", - check.std_dev(), - check.std_dev().abs().log2() - ) - } +// check.add_more(&Vec::<i64>::try_convert_from( +// &m_plus_e_times_m1_more_e, +// rlwe_q, +// )); +// }); +// println!( +// "RLWE x RGSW, where RGSW has noise var_brk, std: {} {}", +// check.std_dev(), +// check.std_dev().abs().log2() +// ) +// } - // check noise in Auto key - if false { - let mut check = Stats { samples: vec![] }; +// // check noise in Auto key +// if false { +// let mut check = Stats { samples: vec![] }; - let mut neg_s_poly = - Vec::<u64>::try_convert_from(ideal_client_key.sk_rlwe().values(), rlwe_q); - rlwe_modop.elwise_neg_mut(neg_s_poly.as_mut_slice()); +// let mut neg_s_poly = +// +// Vec::<u64>::try_convert_from(ideal_client_key.sk_rlwe().values(), rlwe_q); +// rlwe_modop.elwise_neg_mut(neg_s_poly.as_mut_slice()); - let g = bool_evaluator.pbs_info.g(); - let br_q = bool_evaluator.pbs_info.br_q(); - let auto_element_dlogs = bool_evaluator.pbs_info.parameters.auto_element_dlogs(); - for i in auto_element_dlogs.into_iter() { - let g_pow = if i == 0 { - -g - } else { - (((g as usize).pow(i as u32)) % br_q) as isize - }; +// let g = bool_evaluator.pbs_info.g(); +// let br_q = bool_evaluator.pbs_info.br_q(); +// let auto_element_dlogs = +// bool_evaluator.pbs_info.parameters.auto_element_dlogs(); for +// i in auto_element_dlogs.into_iter() { let g_pow = if i == +// 0 { -g +// } else { +// (((g as usize).pow(i as u32)) % br_q) as isize +// }; - // -s[X^k] - let (auto_indices, auto_sign) = generate_auto_map(rlwe_n, g_pow); - let mut neg_s_poly_auto_i = vec![0u64; rlwe_n]; - izip!(neg_s_poly.iter(), auto_indices.iter(), auto_sign.iter()).for_each( - |(v, to_i, to_sign)| { - if !to_sign { - neg_s_poly_auto_i[*to_i] = rlwe_modop.neg(v); - } else { - neg_s_poly_auto_i[*to_i] = *v; - } - }, - ); +// // -s[X^k] +// let (auto_indices, auto_sign) = generate_auto_map(rlwe_n, +// g_pow); let mut neg_s_poly_auto_i = vec![0u64; rlwe_n]; +// izip!(neg_s_poly.iter(), auto_indices.iter(), +// auto_sign.iter()).for_each( |(v, to_i, to_sign)| { +// if !to_sign { +// neg_s_poly_auto_i[*to_i] = rlwe_modop.neg(v); +// } else { +// neg_s_poly_auto_i[*to_i] = *v; +// } +// }, +// ); - let mut auto_key_i = server_key_eval_domain.galois_key_for_auto(i).clone(); - // send i^th auto key to coefficient domain - auto_key_i - .iter_mut() - .for_each(|r| rlwe_nttop.backward(r.as_mut_slice())); - auto_gadget.iter().enumerate().for_each(|(i, b_i)| { - // B^i * -s[X^k] - let mut m_ideal = neg_s_poly_auto_i.clone(); - rlwe_modop.elwise_scalar_mul_mut(m_ideal.as_mut_slice(), b_i); +// let mut auto_key_i = +// server_key_eval_domain.galois_key_for_auto(i).clone(); // +// send i^th auto key to coefficient domain auto_key_i +// .iter_mut() +// .for_each(|r| rlwe_nttop.backward(r.as_mut_slice())); +// auto_gadget.iter().enumerate().for_each(|(i, b_i)| { +// // B^i * -s[X^k] +// let mut m_ideal = neg_s_poly_auto_i.clone(); +// +// rlwe_modop.elwise_scalar_mul_mut(m_ideal.as_mut_slice(), b_i); - let mut m_out = vec![0u64; rlwe_n]; - let mut rlwe_ct = vec![vec![0u64; rlwe_n]; 2]; - rlwe_ct[0].copy_from_slice(&auto_key_i[i]); - rlwe_ct[1].copy_from_slice( - &auto_key_i[auto_decomposer.decomposition_count() + i], - ); - decrypt_rlwe( - &rlwe_ct, - ideal_client_key.sk_rlwe().values(), - &mut m_out, - rlwe_nttop, - rlwe_modop, - ); +// let mut m_out = vec![0u64; rlwe_n]; +// let mut rlwe_ct = vec![vec![0u64; rlwe_n]; 2]; +// rlwe_ct[0].copy_from_slice(&auto_key_i[i]); +// rlwe_ct[1].copy_from_slice( +// &auto_key_i[auto_decomposer.decomposition_count() +// + i], ); +// decrypt_rlwe( +// &rlwe_ct, +// ideal_client_key.sk_rlwe().values(), +// &mut m_out, +// rlwe_nttop, +// rlwe_modop, +// ); - // diff - rlwe_modop.elwise_sub_mut(m_out.as_mut_slice(), m_ideal.as_slice()); +// // diff +// rlwe_modop.elwise_sub_mut(m_out.as_mut_slice(), +// m_ideal.as_slice()); - check.add_more(&Vec::<i64>::try_convert_from(&m_out, rlwe_q)); - }); - } +// check.add_more(&Vec::<i64>::try_convert_from(&m_out, +// rlwe_q)); }); +// } - println!("Auto key noise std dev: {}", check.std_dev().abs().log2()); - } +// println!("Auto key noise std dev: {}", +// check.std_dev().abs().log2()); } - // check noise in RLWE(X^k) after sending RLWE(X) -> RLWE(X^k) using collective - // auto key - if true { - let mut check = Stats { samples: vec![] }; - let br_q = bool_evaluator.pbs_info.br_q(); - let g = bool_evaluator.pbs_info.g(); - let auto_element_dlogs = bool_evaluator.pbs_info.parameters.auto_element_dlogs(); - for i in auto_element_dlogs.into_iter() { - for _ in 0..10 { - let mut m = vec![0u64; rlwe_n]; - RandomFillUniformInModulus::random_fill(&mut rng, rlwe_q, m.as_mut_slice()); - let mut rlwe_ct = RlweCiphertext::<_, DefaultSecureRng> { - data: vec![vec![0u64; rlwe_n]; 2], - is_trivial: false, - _phatom: PhantomData, - }; - public_key_encrypt_rlwe::<_, _, _, _, i32, _>( - &mut rlwe_ct, - collective_pk.key(), - &m, - rlwe_modop, - rlwe_nttop, - &mut rng, - ); +// // check noise in RLWE(X^k) after sending RLWE(X) -> RLWE(X^k) +// using collective // auto key +// if true { +// let mut check = Stats { samples: vec![] }; +// let br_q = bool_evaluator.pbs_info.br_q(); +// let g = bool_evaluator.pbs_info.g(); +// let auto_element_dlogs = +// bool_evaluator.pbs_info.parameters.auto_element_dlogs(); for +// i in auto_element_dlogs.into_iter() { for _ in 0..10 { +// let mut m = vec![0u64; rlwe_n]; +// RandomFillUniformInModulus::random_fill(&mut rng, +// rlwe_q, m.as_mut_slice()); let mut rlwe_ct = +// RlweCiphertext::<_, DefaultSecureRng> { data: +// vec![vec![0u64; rlwe_n]; 2], is_trivial: false, +// _phatom: PhantomData, +// }; +// public_key_encrypt_rlwe::<_, _, _, _, i32, _>( +// &mut rlwe_ct, +// collective_pk.key(), +// &m, +// rlwe_modop, +// rlwe_nttop, +// &mut rng, +// ); - // We're only interested in noise increased as a result of automorphism. - // Hence, we take m+e as the bench. - let mut m_plus_e = vec![0u64; rlwe_n]; - decrypt_rlwe( - &rlwe_ct, - ideal_client_key.sk_rlwe().values(), - &mut m_plus_e, - rlwe_nttop, - rlwe_modop, - ); +// // We're only interested in noise increased as a +// result of automorphism. // Hence, we take m+e as the +// bench. let mut m_plus_e = vec![0u64; rlwe_n]; +// decrypt_rlwe( +// &rlwe_ct, +// ideal_client_key.sk_rlwe().values(), +// &mut m_plus_e, +// rlwe_nttop, +// rlwe_modop, +// ); - let auto_key = server_key_eval_domain.galois_key_for_auto(i); - let (auto_map_index, auto_map_sign) = - bool_evaluator.pbs_info.rlwe_auto_map(i); - let mut scratch = - vec![vec![0u64; rlwe_n]; auto_decomposer.decomposition_count() + 2]; - galois_auto( - &mut rlwe_ct, - auto_key, - &mut scratch, - &auto_map_index, - &auto_map_sign, - rlwe_modop, - rlwe_nttop, - auto_decomposer, - ); +// let auto_key = +// server_key_eval_domain.galois_key_for_auto(i); let +// (auto_map_index, auto_map_sign) = +// bool_evaluator.pbs_info.rlwe_auto_map(i); let mut +// scratch = vec![vec![0u64; rlwe_n]; +// auto_decomposer.decomposition_count() + 2]; +// galois_auto( &mut rlwe_ct, +// auto_key, +// &mut scratch, +// &auto_map_index, +// &auto_map_sign, +// rlwe_modop, +// rlwe_nttop, +// auto_decomposer, +// ); - // send m+e from X to X^k - let mut m_plus_e_auto = vec![0u64; rlwe_n]; - izip!(m_plus_e.iter(), auto_map_index.iter(), auto_map_sign.iter()) - .for_each(|(v, to_index, to_sign)| { - if !to_sign { - m_plus_e_auto[*to_index] = rlwe_modop.neg(v); - } else { - m_plus_e_auto[*to_index] = *v - } - }); +// // send m+e from X to X^k +// let mut m_plus_e_auto = vec![0u64; rlwe_n]; +// izip!(m_plus_e.iter(), auto_map_index.iter(), +// auto_map_sign.iter()) .for_each(|(v, to_index, +// to_sign)| { if !to_sign { +// m_plus_e_auto[*to_index] = +// rlwe_modop.neg(v); } else { +// m_plus_e_auto[*to_index] = *v +// } +// }); - let mut m_out = vec![0u64; rlwe_n]; - decrypt_rlwe( - &rlwe_ct, - ideal_client_key.sk_rlwe().values(), - &mut m_out, - rlwe_nttop, - rlwe_modop, - ); +// let mut m_out = vec![0u64; rlwe_n]; +// decrypt_rlwe( +// &rlwe_ct, +// ideal_client_key.sk_rlwe().values(), +// &mut m_out, +// rlwe_nttop, +// rlwe_modop, +// ); - // diff - rlwe_modop.elwise_sub_mut(m_out.as_mut_slice(), m_plus_e_auto.as_slice()); +// // diff +// rlwe_modop.elwise_sub_mut(m_out.as_mut_slice(), +// m_plus_e_auto.as_slice()); - check.add_more(&Vec::<i64>::try_convert_from(m_out.as_slice(), rlwe_q)); - } - } +// +// check.add_more(&Vec::<i64>::try_convert_from(m_out.as_slice(), rlwe_q)); +// } +// } - println!("Rlwe Auto Noise Std: {}", check.std_dev().abs().log2()); - } +// println!("Rlwe Auto Noise Std: {}", +// check.std_dev().abs().log2()); } - // Check noise growth in ksk - // TODO check in LWE key switching keys - if true { - // 1. encrypt LWE ciphertext - // 2. Key switching - // 3. - let mut check = Stats { samples: vec![] }; +// // Check noise growth in ksk +// // TODO check in LWE key switching keys +// if true { +// // 1. encrypt LWE ciphertext +// // 2. Key switching +// // 3. +// let mut check = Stats { samples: vec![] }; - for _ in 0..1024 { - // Encrypt m \in Q_{ks} using RLWE sk - let mut lwe_in_ct = vec![0u64; rlwe_n + 1]; - let m = RandomElementInModulus::random(&mut rng, &lwe_q.q().unwrap()); - encrypt_lwe( - &mut lwe_in_ct, - &m, - ideal_client_key.sk_rlwe().values(), - lwe_modop, - &mut rng, - ); +// for _ in 0..1024 { +// // Encrypt m \in Q_{ks} using RLWE sk +// let mut lwe_in_ct = vec![0u64; rlwe_n + 1]; +// let m = RandomElementInModulus::random(&mut rng, +// &lwe_q.q().unwrap()); encrypt_lwe( +// &mut lwe_in_ct, +// &m, +// ideal_client_key.sk_rlwe().values(), +// lwe_modop, +// &mut rng, +// ); - // Key switch - let mut lwe_out = vec![0u64; lwe_n + 1]; - lwe_key_switch( - &mut lwe_out, - &lwe_in_ct, - server_key_eval_domain.lwe_ksk(), - lwe_modop, - bool_evaluator.pbs_info.lwe_decomposer(), - ); +// // Key switch +// let mut lwe_out = vec![0u64; lwe_n + 1]; +// lwe_key_switch( +// &mut lwe_out, +// &lwe_in_ct, +// server_key_eval_domain.lwe_ksk(), +// lwe_modop, +// bool_evaluator.pbs_info.lwe_decomposer(), +// ); - // We only care about noise added by LWE key switch - // m+e - let m_plus_e = - decrypt_lwe(&lwe_in_ct, ideal_client_key.sk_rlwe().values(), lwe_modop); +// // We only care about noise added by LWE key switch +// // m+e +// let m_plus_e = +// decrypt_lwe(&lwe_in_ct, +// ideal_client_key.sk_rlwe().values(), lwe_modop); - let m_plus_e_plus_lwe_ksk_noise = - decrypt_lwe(&lwe_out, ideal_client_key.sk_lwe().values(), lwe_modop); +// let m_plus_e_plus_lwe_ksk_noise = +// decrypt_lwe(&lwe_out, +// ideal_client_key.sk_lwe().values(), lwe_modop); - let diff = lwe_modop.sub(&m_plus_e_plus_lwe_ksk_noise, &m_plus_e); +// let diff = lwe_modop.sub(&m_plus_e_plus_lwe_ksk_noise, +// &m_plus_e); - check.add_more(&vec![lwe_q.map_element_to_i64(&diff)]); - } +// check.add_more(&vec![lwe_q.map_element_to_i64(&diff)]); +// } - println!("Lwe ksk std dev: {}", check.std_dev().abs().log2()); - } - } +// println!("Lwe ksk std dev: {}", +// check.std_dev().abs().log2()); } +// } - // Check noise in fresh RGSW ciphertexts, ie X^{s_j[i]}, must equal noise in - // fresh RLWE ciphertext - if true {} - // test LWE ksk from RLWE -> LWE - // if false { - // let logp = 2; - // let mut rng = DefaultSecureRng::new(); +// // Check noise in fresh RGSW ciphertexts, ie X^{s_j[i]}, must equal +// noise in // fresh RLWE ciphertext +// if true {} +// // test LWE ksk from RLWE -> LWE +// // if false { +// // let logp = 2; +// // let mut rng = DefaultSecureRng::new(); - // let m = 1; - // let encoded_m = m << (lwe_logq - logp); +// // let m = 1; +// // let encoded_m = m << (lwe_logq - logp); - // // Encrypt - // let mut lwe_ct = vec![0u64; rlwe_n + 1]; - // encrypt_lwe( - // &mut lwe_ct, - // &encoded_m, - // ideal_client_key.sk_rlwe.values(), - // lwe_modop, - // &mut rng, - // ); +// // // Encrypt +// // let mut lwe_ct = vec![0u64; rlwe_n + 1]; +// // encrypt_lwe( +// // &mut lwe_ct, +// // &encoded_m, +// // ideal_client_key.sk_rlwe.values(), +// // lwe_modop, +// // &mut rng, +// // ); - // // key switch - // let lwe_decomposer = &bool_evaluator.decomposer_lwe; - // let mut lwe_out = vec![0u64; lwe_n + 1]; - // lwe_key_switch( - // &mut lwe_out, - // &lwe_ct, - // &server_key_eval.lwe_ksk, - // lwe_modop, - // lwe_decomposer, - // ); +// // // key switch +// // let lwe_decomposer = &bool_evaluator.decomposer_lwe; +// // let mut lwe_out = vec![0u64; lwe_n + 1]; +// // lwe_key_switch( +// // &mut lwe_out, +// // &lwe_ct, +// // &server_key_eval.lwe_ksk, +// // lwe_modop, +// // lwe_decomposer, +// // ); - // let encoded_m_back = decrypt_lwe(&lwe_out, - // ideal_client_key.sk_lwe.values(), lwe_modop); let m_back - // = ((encoded_m_back as f64 * (1 << logp) as f64) / - // (lwe_q as f64)).round() as u64; dbg!(m_back, m); +// // let encoded_m_back = decrypt_lwe(&lwe_out, +// // ideal_client_key.sk_lwe.values(), lwe_modop); let m_back +// // = ((encoded_m_back as f64 * (1 << logp) as f64) / +// // (lwe_q as f64)).round() as u64; dbg!(m_back, m); - // let noise = measure_noise_lwe( - // &lwe_out, - // ideal_client_key.sk_lwe.values(), - // lwe_modop, - // &encoded_m, - // ); +// // let noise = measure_noise_lwe( +// // &lwe_out, +// // ideal_client_key.sk_lwe.values(), +// // lwe_modop, +// // &encoded_m, +// // ); - // println!("Noise: {noise}"); - // } +// // println!("Noise: {noise}"); +// // } - // Measure noise in RGSW ciphertexts of ideal LWE secrets - // if true { - // let gadget_vec = gadget_vector( - // bool_evaluator.parameters.rlwe_logq, - // bool_evaluator.parameters.logb_rgsw, - // bool_evaluator.parameters.d_rgsw, - // ); +// // Measure noise in RGSW ciphertexts of ideal LWE secrets +// // if true { +// // let gadget_vec = gadget_vector( +// // bool_evaluator.parameters.rlwe_logq, +// // bool_evaluator.parameters.logb_rgsw, +// // bool_evaluator.parameters.d_rgsw, +// // ); - // for i in 0..20 { - // // measure noise in RGSW(s[i]) - // let si = - // ideal_client_key.sk_lwe.values[i] * - // (bool_evaluator.embedding_factor as i32); let mut - // si_poly = vec![0u64; rlwe_n]; if si < 0 { - // si_poly[rlwe_n - (si.abs() as usize)] = rlwe_q - 1; - // } else { - // si_poly[(si.abs() as usize)] = 1; - // } +// // for i in 0..20 { +// // // measure noise in RGSW(s[i]) +// // let si = +// // ideal_client_key.sk_lwe.values[i] * +// // (bool_evaluator.embedding_factor as i32); let mut +// // si_poly = vec![0u64; rlwe_n]; if si < 0 { +// // si_poly[rlwe_n - (si.abs() as usize)] = rlwe_q - 1; +// // } else { +// // si_poly[(si.abs() as usize)] = 1; +// // } - // let mut rgsw_si = server_key_eval.rgsw_cts[i].clone(); - // rgsw_si - // .iter_mut() - // .for_each(|ri| rlwe_nttop.backward(ri.as_mut())); +// // let mut rgsw_si = server_key_eval.rgsw_cts[i].clone(); +// // rgsw_si +// // .iter_mut() +// // .for_each(|ri| rlwe_nttop.backward(ri.as_mut())); - // println!("####### Noise in RGSW(X^s_{i}) #######"); - // _measure_noise_rgsw( - // &rgsw_si, - // &si_poly, - // ideal_client_key.sk_rlwe.values(), - // &gadget_vec, - // rlwe_q, - // ); - // println!("####### ##################### #######"); - // } - // } +// // println!("####### Noise in RGSW(X^s_{i}) #######"); +// // _measure_noise_rgsw( +// // &rgsw_si, +// // &si_poly, +// // ideal_client_key.sk_rlwe.values(), +// // &gadget_vec, +// // rlwe_q, +// // ); +// // println!("####### ##################### #######"); +// // } +// // } - // // measure noise grwoth in RLWExRGSW - // if true { - // let mut rng = DefaultSecureRng::new(); - // let mut carry_m = vec![0u64; rlwe_n]; - // RandomUniformDist1::random_fill(&mut rng, &rlwe_q, - // carry_m.as_mut_slice()); +// // // measure noise grwoth in RLWExRGSW +// // if true { +// // let mut rng = DefaultSecureRng::new(); +// // let mut carry_m = vec![0u64; rlwe_n]; +// // RandomUniformDist1::random_fill(&mut rng, &rlwe_q, +// // carry_m.as_mut_slice()); - // // RGSW(carrym) - // let trivial_rlwect = vec![vec![0u64; rlwe_n], carry_m.clone()]; - // let mut rlwe_ct = RlweCiphertext::<_, - // DefaultSecureRng>::from_raw(trivial_rlwect, true); +// // // RGSW(carrym) +// // let trivial_rlwect = vec![vec![0u64; rlwe_n], +// carry_m.clone()]; // let mut rlwe_ct = RlweCiphertext::<_, +// // DefaultSecureRng>::from_raw(trivial_rlwect, true); - // let mut scratch_matrix_dplus2_ring = vec![vec![0u64; rlwe_n]; - // d_rgsw + 2]; let mul_mod = - // |v0: &u64, v1: &u64| (((*v0 as u128 * *v1 as u128) % (rlwe_q as u128)) as u64); +// // let mut scratch_matrix_dplus2_ring = vec![vec![0u64; rlwe_n]; +// // d_rgsw + 2]; let mul_mod = +// // |v0: &u64, v1: &u64| (((*v0 as u128 * *v1 as u128) % +// (rlwe_q as u128)) as u64); - // for i in 0..bool_evaluator.parameters.lwe_n { - // rlwe_by_rgsw( - // &mut rlwe_ct, - // server_key_eval.rgsw_ct_lwe_si(i), - // &mut scratch_matrix_dplus2_ring, - // rlwe_decomposer, - // rlwe_nttop, - // rlwe_modop, - // ); +// // for i in 0..bool_evaluator.parameters.lwe_n { +// // rlwe_by_rgsw( +// // &mut rlwe_ct, +// // server_key_eval.rgsw_ct_lwe_si(i), +// // &mut scratch_matrix_dplus2_ring, +// // rlwe_decomposer, +// // rlwe_nttop, +// // rlwe_modop, +// // ); - // // carry_m[X] * s_i[X] - // let si = - // ideal_client_key.sk_lwe.values[i] * - // (bool_evaluator.embedding_factor as i32); let mut - // si_poly = vec![0u64; rlwe_n]; if si < 0 { - // si_poly[rlwe_n - (si.abs() as usize)] = rlwe_q - 1; - // } else { - // si_poly[(si.abs() as usize)] = 1; - // } - // carry_m = negacyclic_mul(&carry_m, &si_poly, mul_mod, - // rlwe_q); +// // // carry_m[X] * s_i[X] +// // let si = +// // ideal_client_key.sk_lwe.values[i] * +// // (bool_evaluator.embedding_factor as i32); let mut +// // si_poly = vec![0u64; rlwe_n]; if si < 0 { +// // si_poly[rlwe_n - (si.abs() as usize)] = rlwe_q - 1; +// // } else { +// // si_poly[(si.abs() as usize)] = 1; +// // } +// // carry_m = negacyclic_mul(&carry_m, &si_poly, mul_mod, +// // rlwe_q); - // let noise = measure_noise( - // &rlwe_ct, - // &carry_m, - // rlwe_nttop, - // rlwe_modop, - // ideal_client_key.sk_rlwe.values(), - // ); - // println!("Noise RLWE(carry_m) accumulating {i}^th secret - // monomial: {noise}"); } - // } +// // let noise = measure_noise( +// // &rlwe_ct, +// // &carry_m, +// // rlwe_nttop, +// // rlwe_modop, +// // ideal_client_key.sk_rlwe.values(), +// // ); +// // println!("Noise RLWE(carry_m) accumulating {i}^th secret +// // monomial: {noise}"); } +// // } - // // Check galois keys - // if false { - // let g = bool_evaluator.g() as isize; - // let mut rng = DefaultSecureRng::new(); - // let mut scratch_matrix_dplus2_ring = vec![vec![0u64; rlwe_n]; - // d_rgsw + 2]; for i in [g, -g] { - // let mut m = vec![0u64; rlwe_n]; - // RandomUniformDist1::random_fill(&mut rng, &rlwe_q, - // m.as_mut_slice()); let mut rlwe_ct = { - // let mut data = vec![vec![0u64; rlwe_n]; 2]; - // public_key_encrypt_rlwe( - // &mut data, - // &collective_pk.key, - // &m, - // rlwe_modop, - // rlwe_nttop, - // &mut rng, - // ); - // RlweCiphertext::<_, DefaultSecureRng>::from_raw(data, - // false) }; +// // // Check galois keys +// // if false { +// // let g = bool_evaluator.g() as isize; +// // let mut rng = DefaultSecureRng::new(); +// // let mut scratch_matrix_dplus2_ring = vec![vec![0u64; rlwe_n]; +// // d_rgsw + 2]; for i in [g, -g] { +// // let mut m = vec![0u64; rlwe_n]; +// // RandomUniformDist1::random_fill(&mut rng, &rlwe_q, +// // m.as_mut_slice()); let mut rlwe_ct = { +// // let mut data = vec![vec![0u64; rlwe_n]; 2]; +// // public_key_encrypt_rlwe( +// // &mut data, +// // &collective_pk.key, +// // &m, +// // rlwe_modop, +// // rlwe_nttop, +// // &mut rng, +// // ); +// // RlweCiphertext::<_, DefaultSecureRng>::from_raw(data, +// // false) }; - // let auto_key = server_key_eval.galois_key_for_auto(i); - // let (auto_map_index, auto_map_sign) = - // generate_auto_map(rlwe_n, i); galois_auto( - // &mut rlwe_ct, - // auto_key, - // &mut scratch_matrix_dplus2_ring, - // &auto_map_index, - // &auto_map_sign, - // rlwe_modop, - // rlwe_nttop, - // rlwe_decomposer, - // ); +// // let auto_key = server_key_eval.galois_key_for_auto(i); +// // let (auto_map_index, auto_map_sign) = +// // generate_auto_map(rlwe_n, i); galois_auto( +// // &mut rlwe_ct, +// // auto_key, +// // &mut scratch_matrix_dplus2_ring, +// // &auto_map_index, +// // &auto_map_sign, +// // rlwe_modop, +// // rlwe_nttop, +// // rlwe_decomposer, +// // ); - // // send m(X) -> m(X^i) - // let mut m_k = vec![0u64; rlwe_n]; - // izip!(m.iter(), auto_map_index.iter(), - // auto_map_sign.iter()).for_each( |(mi, to_index, to_sign)| - // { if !to_sign { - // m_k[*to_index] = rlwe_q - *mi; - // } else { - // m_k[*to_index] = *mi; - // } - // }, - // ); +// // // send m(X) -> m(X^i) +// // let mut m_k = vec![0u64; rlwe_n]; +// // izip!(m.iter(), auto_map_index.iter(), +// // auto_map_sign.iter()).for_each( |(mi, to_index, +// to_sign)| // { if !to_sign { +// // m_k[*to_index] = rlwe_q - *mi; +// // } else { +// // m_k[*to_index] = *mi; +// // } +// // }, +// // ); - // // measure noise - // let noise = measure_noise( - // &rlwe_ct, - // &m_k, - // rlwe_nttop, - // rlwe_modop, - // ideal_client_key.sk_rlwe.values(), - // ); +// // // measure noise +// // let noise = measure_noise( +// // &rlwe_ct, +// // &m_k, +// // rlwe_nttop, +// // rlwe_modop, +// // ideal_client_key.sk_rlwe.values(), +// // ); - // println!("Noise after auto k={i}: {noise}"); - // } - // } - } -} +// // println!("Noise after auto k={i}: {noise}"); +// // } +// // } +// } +// }
@@ -391,7 +391,7 @@ }
} /// Server key in evaluation domain -pub(crate) struct ServerKeyEvaluationDomain<M, R, N> { +pub(crate) struct ServerKeyEvaluationDomain<M, P, R, N> { /// Rgsw cts of LWE secret elements rgsw_cts: Vec<M>, /// Auto keys. Key corresponding to g^{k} is at index `k`. Key corresponding@@ -399,6 +399,7 @@ /// to -g is at 0
galois_keys: HashMap<usize, M>, /// LWE ksk to key switching LWE ciphertext from RLWE secret to LWE secret lwe_ksk: M, + parameters: P, _phanton: PhantomData<(R, N)>, }@@ -406,13 +407,14 @@ pub(super) mod impl_server_key_eval_domain {
use itertools::{izip, Itertools}; use crate::{ + backend::Modulus, ntt::{Ntt, NttInit}, pbs::PbsKey, }; use super::*; - impl<M, R, N> ServerKeyEvaluationDomain<M, R, N> { + impl<M, Mod, R, N> ServerKeyEvaluationDomain<M, Mod, R, N> { pub(in super::super) fn rgsw_cts(&self) -> &[M] { &self.rgsw_cts }@@ -424,7 +426,7 @@ R: RandomFillUniformInModulus<[M::MatElement], CiphertextModulus<M::MatElement>>
+ NewWithSeed, N: NttInit<CiphertextModulus<M::MatElement>> + Ntt<Element = M::MatElement>, > From<&SeededServerKey<M, BoolParameters<M::MatElement>, R::Seed>> - for ServerKeyEvaluationDomain<M, R, N> + for ServerKeyEvaluationDomain<M, BoolParameters<M::MatElement>, R, N> where <M as Matrix>::R: RowMut, M::MatElement: Copy,@@ -542,6 +544,7 @@ ServerKeyEvaluationDomain {
rgsw_cts, galois_keys: auto_keys, lwe_ksk, + parameters: parameters.clone(), _phanton: PhantomData, } }@@ -552,7 +555,7 @@ M: MatrixMut + MatrixEntity,
Rng: NewWithSeed, N: NttInit<CiphertextModulus<M::MatElement>> + Ntt<Element = M::MatElement>, > From<&SeededMultiPartyServerKey<M, Rng::Seed, BoolParameters<M::MatElement>>> - for ServerKeyEvaluationDomain<M, Rng, N> + for ServerKeyEvaluationDomain<M, BoolParameters<M::MatElement>, Rng, N> where <M as Matrix>::R: RowMut, Rng::Seed: Copy,@@ -640,21 +643,63 @@ ServerKeyEvaluationDomain {
rgsw_cts, galois_keys: auto_keys, lwe_ksk, + parameters: value.parameters.clone(), _phanton: PhantomData, } } } - impl<M: Matrix, R, N> PbsKey for ServerKeyEvaluationDomain<M, R, N> { - type M = M; - fn galois_key_for_auto(&self, k: usize) -> &Self::M { + impl<M: Matrix, P, R, N> PbsKey for ServerKeyEvaluationDomain<M, P, R, N> { + type AutoKey = M; + type LweKskKey = M; + type RgswCt = M; + + fn galois_key_for_auto(&self, k: usize) -> &Self::AutoKey { + self.galois_keys.get(&k).unwrap() + } + fn rgsw_ct_lwe_si(&self, si: usize) -> &Self::RgswCt { + &self.rgsw_cts[si] + } + + fn lwe_ksk(&self) -> &Self::LweKskKey { + &self.lwe_ksk + } + } +} + +/// Server key in evaluation domain +pub(crate) struct ShoupServerKeyEvaluationDomain<M, P, R, N> { + /// Rgsw cts of LWE secret elements + rgsw_cts: Vec<NormalAndShoup<M>>, + /// Auto keys. Key corresponding to g^{k} is at index `k`. Key corresponding + /// to -g is at 0 + galois_keys: HashMap<usize, NormalAndShoup<M>>, + /// LWE ksk to key switching LWE ciphertext from RLWE secret to LWE secret + lwe_ksk: M, + parameters: P, + _phanton: PhantomData<(R, N)>, +} + +pub(crate) struct NormalAndShoup<M>(M, M); + +mod shoup_server_key_eval_domain { + use crate::pbs::PbsKey; + + use super::*; + + impl<M: Matrix, P, R, N> PbsKey for ShoupServerKeyEvaluationDomain<M, P, R, N> { + type AutoKey = NormalAndShoup<M>; + type LweKskKey = M; + type RgswCt = NormalAndShoup<M>; + + fn galois_key_for_auto(&self, k: usize) -> &Self::AutoKey { self.galois_keys.get(&k).unwrap() } - fn rgsw_ct_lwe_si(&self, si: usize) -> &Self::M { + fn rgsw_ct_lwe_si(&self, si: usize) -> &Self::RgswCt { &self.rgsw_cts[si] } - fn lwe_ksk(&self) -> &Self::M { + fn lwe_ksk(&self) -> &Self::LweKskKey { &self.lwe_ksk } }
@@ -23,7 +23,7 @@ static BOOL_EVALUATOR: RefCell<Option<BoolEvaluator<Vec<Vec<u64>>, NttBackendU64, ModularOpsU64<CiphertextModulus<u64>>, ModularOpsU64<CiphertextModulus<u64>>>>> = RefCell::new(None);
} static BOOL_SERVER_KEY: OnceLock< - ServerKeyEvaluationDomain<Vec<Vec<u64>>, DefaultSecureRng, NttBackendU64>, + ServerKeyEvaluationDomain<Vec<Vec<u64>>, BoolParameters<u64>, DefaultSecureRng, NttBackendU64>, > = OnceLock::new(); static MULTI_PARTY_CRS: OnceLock<MultiPartyCrs<[u8; 32]>> = OnceLock::new();@@ -39,7 +39,14 @@ "Attempted to set MP SEED twice."
) } -fn set_server_key(key: ServerKeyEvaluationDomain<Vec<Vec<u64>>, DefaultSecureRng, NttBackendU64>) { +fn set_server_key( + key: ServerKeyEvaluationDomain< + Vec<Vec<u64>>, + BoolParameters<u64>, + DefaultSecureRng, + NttBackendU64, + >, +) { assert!( BOOL_SERVER_KEY.set(key).is_ok(), "Attempted to set server key twice."@@ -108,6 +115,7 @@ impl SeededServerKey<Vec<Vec<u64>>, BoolParameters<u64>, [u8; 32]> {
pub fn set_server_key(&self) { set_server_key(ServerKeyEvaluationDomain::< _, + _, DefaultSecureRng, NttBackendU64, >::from(self));@@ -123,14 +131,22 @@ >
{ pub fn set_server_key(&self) { set_server_key(ServerKeyEvaluationDomain::< - Vec<Vec<u64>>, + _, + _, DefaultSecureRng, NttBackendU64, >::from(self)) } } -impl Global for ServerKeyEvaluationDomain<Vec<Vec<u64>>, DefaultSecureRng, NttBackendU64> { +impl Global + for ServerKeyEvaluationDomain< + Vec<Vec<u64>>, + BoolParameters<u64>, + DefaultSecureRng, + NttBackendU64, + > +{ fn global() -> &'static Self { BOOL_SERVER_KEY.get().unwrap() }
@@ -8,18 +8,25 @@ decomposer::Decomposer,
lwe::lwe_key_switch, ntt::Ntt, random::DefaultSecureRng, - rgsw::{galois_auto, rlwe_by_rgsw, IsTrivial, RlweCiphertext}, + rgsw::{galois_auto, rlwe_by_rgsw, rlwe_by_rgsw_shoup, IsTrivial, RlweCiphertext}, Matrix, MatrixEntity, MatrixMut, RowMut, }; pub(crate) trait PbsKey { - type M: Matrix; + type RgswCt; + type AutoKey; + type LweKskKey; /// RGSW ciphertext of LWE secret elements - fn rgsw_ct_lwe_si(&self, si: usize) -> &Self::M; + fn rgsw_ct_lwe_si(&self, si: usize) -> &Self::RgswCt; /// Key for automorphism with g^k. For -g use k = 0 - fn galois_key_for_auto(&self, k: usize) -> &Self::M; + fn galois_key_for_auto(&self, k: usize) -> &Self::AutoKey; /// LWE ksk to key switch from RLWE secret to LWE secret - fn lwe_ksk(&self) -> &Self::M; + fn lwe_ksk(&self) -> &Self::LweKskKey; +} + +trait WithShoupRepr: AsRef<Self::M> { + type M; + fn shoup_repr(&self) -> Self::M; } pub(crate) trait PbsInfo {@@ -73,7 +80,7 @@ /// - blind rotate
pub(crate) fn pbs< M: MatrixMut + MatrixEntity, P: PbsInfo<Element = M::MatElement>, - K: PbsKey<M = M>, + K: PbsKey<RgswCt = M, AutoKey = M, LweKskKey = M>, >( pbs_info: &P, test_vec: &M::R,@@ -211,7 +218,8 @@ Mmut: MatrixMut<MatElement = MT::MatElement>,
D: Decomposer<Element = MT::MatElement>, NttOp: Ntt<Element = MT::MatElement>, ModOp: ArithmeticOps<Element = MT::MatElement> + VectorOps<Element = MT::MatElement>, - K: PbsKey<M = Mmut>, + MShoup: WithShoupRepr<M = Mmut>, + K: PbsKey<RgswCt = MShoup, AutoKey = MShoup>, P: PbsInfo<Element = MT::MatElement>, >( trivial_rlwe_test_poly: &mut MT,@@ -241,9 +249,19 @@ let s_indices = &gk_to_si[q_by_4 + i];
s_indices.iter().for_each(|s_index| { // let new = std::time::Instant::now(); - rlwe_by_rgsw( + // rlwe_by_rgsw( + // trivial_rlwe_test_poly, + // pbs_key.rgsw_ct_lwe_si(*s_index), + // scratch_matrix, + // rlwe_rgsw_decomposer, + // ntt_op, + // mod_op, + // ); + let ct = pbs_key.rgsw_ct_lwe_si(*s_index); + rlwe_by_rgsw_shoup( trivial_rlwe_test_poly, - pbs_key.rgsw_ct_lwe_si(*s_index), + ct.as_ref(), + &ct.shoup_repr(), scratch_matrix, rlwe_rgsw_decomposer, ntt_op,
@@ -244,4 +244,30 @@ }
} #[cfg(test)] -mod tests {} +mod tests { + + // #[test] + // fn gg() { + // let n = 1 << (11 + 1); + // let mut start = 1 << 55; + // while start < (1 << 56) { + // if start % n == 1 { + // break; + // } + // start += 1; + // } + + // let mut prime = None; + // while start < (1 << 56) { + // if is_probably_prime(start) { + // dbg!(start); + // prime = Some(start); + // break; + // } + // dbg!(start); + // start += (n); + // } + + // println!("{:?}", prime); + // } +}