diff --git a/src/bool.rs b/src/bool.rs index bede5a4..f00979e 100644 --- a/src/bool.rs +++ b/src/bool.rs @@ -15,7 +15,7 @@ use crate::{ decomposer::{gadget_vector, Decomposer, DefaultDecomposer, NumInfo}, lwe::{decrypt_lwe, encrypt_lwe, lwe_key_switch, lwe_ksk_keygen, measure_noise_lwe, LweSecret}, ntt::{Ntt, NttBackendU64, NttInit}, - random::{DefaultSecureRng, RandomGaussianDist, RandomUniformDist}, + random::{DefaultSecureRng, NewWithSeed, RandomGaussianDist, RandomUniformDist}, rgsw::{ decrypt_rlwe, galois_auto, galois_key_gen, generate_auto_map, rlwe_by_rgsw, secret_key_encrypt_rgsw, IsTrivial, RlweCiphertext, RlweSecret, @@ -97,19 +97,172 @@ impl ClientKey { // ClientKey::with_local_mut(|k| *k = key.clone()) // } -struct ServerKey { +struct SeededServerKey { + /// Rgsw cts of LWE secret elements + rgsw_cts: Vec, + /// Auto keys + auto_keys: HashMap, + /// LWE ksk to key switching LWE ciphertext from RLWE secret to LWE secret + lwe_ksk: M::R, + /// Parameters + parameters: P, + /// Main seed + seed: S, +} + +impl SeededServerKey, S> { + pub(crate) fn from_raw( + auto_keys: HashMap, + rgsw_cts: Vec, + lwe_ksk: M::R, + parameters: BoolParameters, + seed: S, + ) -> Self { + // sanity checks + auto_keys + .iter() + .for_each(|v| assert!(v.1.dimension() == (parameters.d_rgsw, parameters.rlwe_n))); + rgsw_cts + .iter() + .for_each(|v| assert!(v.dimension() == (parameters.d_rgsw * 3, parameters.rlwe_n))); + assert!(lwe_ksk.as_ref().len() == (parameters.d_lwe * parameters.rlwe_n)); + + SeededServerKey { + rgsw_cts, + auto_keys, + lwe_ksk, + parameters, + seed, + } + } +} + +struct ServerKeyEvaluationDomain { /// Rgsw cts of LWE secret elements rgsw_cts: Vec, /// Galois keys galois_keys: HashMap, /// LWE ksk to key switching LWE ciphertext from RLWE secret to LWE secret lwe_ksk: M, + _phanton: PhantomData<(R, N)>, +} + +impl< + M: MatrixMut + MatrixEntity, + R: RandomUniformDist<[M::MatElement], Parameters = M::MatElement> + NewWithSeed, + N: NttInit + Ntt, + > From<&SeededServerKey, R::Seed>> + for ServerKeyEvaluationDomain +where + ::R: RowMut, + M::MatElement: Copy, + R::Seed: Clone, +{ + fn from(value: &SeededServerKey, R::Seed>) -> Self { + let mut main_prng = R::new_with_seed(value.seed.clone()); + + let g = value.parameters.g as isize; + let ring_size = value.parameters.rlwe_n; + let lwe_n = value.parameters.lwe_n; + let d_rgsw = value.parameters.d_rgsw; + let d_lwe = value.parameters.d_lwe; + let rlwe_q = value.parameters.rlwe_q; + let lwq_q = value.parameters.lwe_q; + + let nttop = N::new(rlwe_q, ring_size); + + // galois keys + let mut auto_keys = HashMap::new(); + for i in [g, -g] { + let seeded_auto_key = value.auto_keys.get(&i).unwrap(); + assert!(seeded_auto_key.dimension() == (d_rgsw, ring_size)); + + let mut data = M::zeros(d_rgsw * 2, ring_size); + + // sample RLWE'_A(-s(X^k)) + data.iter_rows_mut().take(d_rgsw).for_each(|ri| { + RandomUniformDist::random_fill(&mut main_prng, &rlwe_q, ri.as_mut()) + }); + + // copy over RLWE'B_(-s(X^k)) + izip!( + data.iter_rows_mut().skip(d_rgsw), + seeded_auto_key.iter_rows() + ) + .for_each(|(to_ri, from_ri)| to_ri.as_mut().copy_from_slice(from_ri.as_ref())); + + // Send to Evaluation domain + data.iter_rows_mut() + .for_each(|ri| nttop.forward(ri.as_mut())); + + auto_keys.insert(i, data); + } + + // RGSW ciphertexts + let rgsw_cts = value + .rgsw_cts + .iter() + .map(|seeded_rgsw_si| { + assert!(seeded_rgsw_si.dimension() == (3 * d_rgsw, ring_size)); + + let mut data = M::zeros(d_rgsw * 4, ring_size); + + // copy over RLWE'(-sm) + izip!( + data.iter_rows_mut().take(d_rgsw * 2), + seeded_rgsw_si.iter_rows().take(d_rgsw * 2) + ) + .for_each(|(to_ri, from_ri)| to_ri.as_mut().copy_from_slice(from_ri.as_ref())); + + // sample RLWE'_A(m) + data.iter_rows_mut() + .skip(2 * d_rgsw) + .take(d_rgsw) + .for_each(|ri| { + RandomUniformDist::random_fill(&mut main_prng, &rlwe_q, ri.as_mut()) + }); + + // copy over RLWE'_B(m) + izip!( + data.iter_rows_mut().skip(d_rgsw * 3), + seeded_rgsw_si.iter_rows().skip(d_rgsw * 2) + ) + .for_each(|(to_ri, from_ri)| to_ri.as_mut().copy_from_slice(from_ri.as_ref())); + + // send polynomials to evaluation domain + data.iter_rows_mut() + .for_each(|ri| nttop.forward(ri.as_mut())); + + data + }) + .collect_vec(); + + // LWE ksk + let lwe_ksk = { + assert!(value.lwe_ksk.as_ref().len() == d_lwe * ring_size); + + let mut data = M::zeros(d_lwe * ring_size, lwe_n + 1); + izip!(data.iter_rows_mut(), value.lwe_ksk.as_ref().iter()).for_each(|(lwe_i, bi)| { + RandomUniformDist::random_fill(&mut main_prng, &lwq_q, &mut lwe_i.as_mut()[1..]); + lwe_i.as_mut()[0] = *bi; + }); + + data + }; + + ServerKeyEvaluationDomain { + rgsw_cts, + galois_keys: auto_keys, + lwe_ksk, + _phanton: PhantomData, + } + } } //FIXME(Jay): Figure out a way for BoolEvaluator to have access to ServerKey // via a pointer and implement PbsKey for BoolEvaluator instead of ServerKey // directly -impl PbsKey for ServerKey { +impl PbsKey for ServerKeyEvaluationDomain { type M = M; fn galois_key_for_auto(&self, k: isize) -> &Self::M { self.galois_keys.get(&k).unwrap() @@ -123,6 +276,7 @@ impl PbsKey for ServerKey { } } +#[derive(Clone)] struct BoolParameters { rlwe_q: El, rlwe_logq: usize, @@ -170,7 +324,8 @@ where ::R: RowMut, DefaultSecureRng: RandomGaussianDist<[M::MatElement], Parameters = M::MatElement> + RandomGaussianDist - + RandomUniformDist<[M::MatElement], Parameters = M::MatElement>, + + RandomUniformDist<[M::MatElement], Parameters = M::MatElement> + + NewWithSeed, { fn new(parameters: BoolParameters) -> Self { //TODO(Jay): Run sanity checks for modulus values in parameters @@ -285,104 +440,104 @@ where ClientKey { sk_rlwe, sk_lwe } } - fn server_key(&self, client_key: &ClientKey) -> ServerKey { - // let sk_rlwe = &client_key.sk_rlwe; - // let sk_lwe = &client_key.sk_lwe; - - // let d_rgsw_gadget_vec = gadget_vector( - // self.parameters.rlwe_logq, - // self.parameters.logb_rgsw, - // self.parameters.d_rgsw, - // ); - - // // generate galois key -g, g - // let mut galois_keys = HashMap::new(); - // let g = self.parameters.g as isize; - // for i in [g, -g] { - // let gk = DefaultSecureRng::with_local_mut(|rng| { - // let mut ksk_out = M::zeros(self.parameters.d_rgsw * 2, - // self.parameters.rlwe_n); galois_key_gen( - // &mut ksk_out, - // sk_rlwe, - // i, - // &d_rgsw_gadget_vec, - // &self.rlwe_modop, - // &self.rlwe_nttop, - // rng, - // ); - // ksk_out - // }); - - // galois_keys.insert(i, gk); - // } - - // // generate rgsw ciphertexts RGSW(si) where si is i^th LWE secret element - // let ring_size = self.parameters.rlwe_n; - // let rlwe_q = self.parameters.rlwe_q; - // let rgsw_cts = sk_lwe - // .values() - // .iter() - // .map(|si| { - // // X^{si}; assume |emebedding_factor * si| < N - // let mut m = M::zeros(1, ring_size); - // let si = (self.embedding_factor as i32) * si; - // // dbg!(si); - // if si < 0 { - // // X^{-i} = X^{2N - i} = -X^{N-i} - // m.set( - // 0, - // ring_size - (si.abs() as usize), - // rlwe_q - M::MatElement::one(), - // ); - // } else { - // // X^{i} - // m.set(0, (si.abs() as usize), M::MatElement::one()); - // } - // self.rlwe_nttop.forward(m.get_row_mut(0)); - - // let rgsw_si = DefaultSecureRng::with_local_mut(|rng| { - // let mut rgsw_si = M::zeros(self.parameters.d_rgsw * 4, - // ring_size); secret_key_encrypt_rgsw( - // &mut rgsw_si, - // &m, - // &d_rgsw_gadget_vec, - // sk_rlwe, - // &self.rlwe_modop, - // &self.rlwe_nttop, - // rng, - // ); - // rgsw_si - // }); - // rgsw_si - // }) - // .collect_vec(); - - // // LWE KSK from RLWE secret s -> LWE secret z - // let d_lwe_gadget = gadget_vector( - // self.parameters.lwe_logq, - // self.parameters.logb_lwe, - // self.parameters.d_lwe, - // ); - // let mut lwe_ksk = DefaultSecureRng::with_local_mut(|rng| { - // let mut out = M::zeros(self.parameters.d_lwe * ring_size, - // self.parameters.lwe_n + 1); lwe_ksk_keygen( - // &sk_rlwe.values(), - // &sk_lwe.values(), - // &mut out, - // &d_lwe_gadget, - // &self.lwe_modop, - // rng, - // ); - // out - // }); + fn server_key( + &self, + client_key: &ClientKey, + ) -> SeededServerKey, [u8; 32]> { + DefaultSecureRng::with_local_mut(|rng| { + let mut main_seed = [0u8; 32]; + rng.fill_bytes(&mut main_seed); + + let mut main_prng = DefaultSecureRng::new_seeded(main_seed); - // ServerKey { - // rgsw_cts, - // galois_keys, - // lwe_ksk, - // } + let sk_rlwe = &client_key.sk_rlwe; + let sk_lwe = &client_key.sk_lwe; - todo!() + let d_rgsw_gadget_vec = gadget_vector( + self.parameters.rlwe_logq, + self.parameters.logb_rgsw, + self.parameters.d_rgsw, + ); + + // generate auto keys -g, g + let mut auto_keys = HashMap::new(); + let g = self.parameters.g as isize; + for i in [g, -g] { + let mut gk = M::zeros(self.parameters.d_rgsw, self.parameters.rlwe_n); + galois_key_gen( + &mut gk, + sk_rlwe.values(), + i, + &d_rgsw_gadget_vec, + &self.rlwe_modop, + &self.rlwe_nttop, + &mut main_prng, + rng, + ); + auto_keys.insert(i, gk); + } + + // generate rgsw ciphertexts RGSW(si) where si is i^th LWE secret element + let ring_size = self.parameters.rlwe_n; + let rlwe_q = self.parameters.rlwe_q; + let rgsw_cts = sk_lwe + .values() + .iter() + .map(|si| { + // X^{si}; assume |emebedding_factor * si| < N + let mut m = M::R::zeros(ring_size); + let si = (self.embedding_factor as i32) * si; + // dbg!(si); + if si < 0 { + // X^{-i} = X^{2N - i} = -X^{N-i} + m.as_mut()[ring_size - (si.abs() as usize)] = rlwe_q - M::MatElement::one(); + } else { + // X^{i} + m.as_mut()[si.abs() as usize] = M::MatElement::one(); + } + + let mut rgsw_si = M::zeros(self.parameters.d_rgsw * 3, ring_size); + secret_key_encrypt_rgsw( + &mut rgsw_si, + &m, + &d_rgsw_gadget_vec, + sk_rlwe.values(), + &self.rlwe_modop, + &self.rlwe_nttop, + &mut main_prng, + rng, + ); + + rgsw_si + }) + .collect_vec(); + + // LWE KSK from RLWE secret s -> LWE secret z + let d_lwe_gadget = gadget_vector( + self.parameters.lwe_logq, + self.parameters.logb_lwe, + self.parameters.d_lwe, + ); + + let mut lwe_ksk = M::R::zeros(self.parameters.d_lwe * ring_size); + lwe_ksk_keygen( + &sk_rlwe.values(), + &sk_lwe.values(), + &mut lwe_ksk, + &d_lwe_gadget, + &self.lwe_modop, + &mut main_prng, + rng, + ); + + SeededServerKey::from_raw( + auto_keys, + rgsw_cts, + lwe_ksk, + self.parameters.clone(), + main_seed, + ) + }) } /// TODO(Jay): Fetch client key from thread local @@ -434,7 +589,7 @@ where &self, c0: &M::R, c1: &M::R, - server_key: &ServerKey, + server_key: &ServerKeyEvaluationDomain, scratch_lwen_plus1: &mut M::R, scratch_matrix_dplus2_ring: &mut M, ) -> M::R { @@ -984,7 +1139,7 @@ mod tests { lwe_n: 493, d_rgsw: 3, logb_rgsw: 8, - d_lwe: 2, + d_lwe: 3, logb_lwe: 4, g: 5, w: 1, @@ -996,7 +1151,7 @@ mod tests { // } #[test] - fn encrypt_decrypt_works() { + fn bool_encrypt_decrypt_works() { // let prime = generate_prime(32, 2 * 1024, 1 << 32); // dbg!(prime); let bool_evaluator = @@ -1014,18 +1169,22 @@ mod tests { } #[test] - fn trial12() { - // DefaultSecureRng::with_local_mut(|r| { - // let rng = DefaultSecureRng::new_seeded([19u8; 32]); - // *r = rng; - // }); + fn bool_nand() { + DefaultSecureRng::with_local_mut(|r| { + let rng = DefaultSecureRng::new_seeded([19u8; 32]); + *r = rng; + }); let bool_evaluator = BoolEvaluator::>, u64, NttBackendU64, ModularOpsU64>::new(SP_BOOL_PARAMS); // println!("{:?}", bool_evaluator.nand_test_vec); let client_key = bool_evaluator.client_key(); - let server_key = bool_evaluator.server_key(&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 scratch_lwen_plus1 = vec![0u64; bool_evaluator.parameters.lwe_n + 1]; let mut scratch_matrix_dplus2_ring = vec![ @@ -1037,11 +1196,11 @@ mod tests { let mut m1 = true; let mut ct0 = bool_evaluator.encrypt(m0, &client_key); let mut ct1 = bool_evaluator.encrypt(m1, &client_key); - for _ in 0..100 { + for _ in 0..1000 { let ct_back = bool_evaluator.nand( &ct0, &ct1, - &server_key, + &server_key_eval_domain, &mut scratch_lwen_plus1, &mut scratch_matrix_dplus2_ring, ); diff --git a/src/lwe.rs b/src/lwe.rs index 5406708..2d3b288 100644 --- a/src/lwe.rs +++ b/src/lwe.rs @@ -131,16 +131,15 @@ pub fn lwe_ksk_keygen< Ro: Row + RowMut + RowEntity, S, Op: VectorOps + ArithmeticOps, - R: RandomGaussianDist - + RandomUniformDist<[Ro::Element], Parameters = Ro::Element> - + NewWithSeed, + R: RandomGaussianDist, + PR: RandomUniformDist<[Ro::Element], Parameters = Ro::Element>, >( from_lwe_sk: &[S], to_lwe_sk: &[S], ksk_out: &mut Ro, gadget: &[Ro::Element], - seed: R::Seed, operator: &Op, + p_rng: &mut PR, rng: &mut R, ) where Ro: TryConvertFrom<[S], Parameters = Ro::Element>, @@ -156,13 +155,12 @@ pub fn lwe_ksk_keygen< let sk_out_m = Ro::try_convert_from(to_lwe_sk, &modulus); let mut scratch = Ro::zeros(to_lwe_sk.len()); - let mut p_rng = R::new_with_seed(seed); izip!(neg_sk_in_m.as_ref(), ksk_out.as_mut().chunks_mut(d)).for_each( |(neg_sk_in_si, d_lwes_partb)| { izip!(gadget.iter(), d_lwes_partb.into_iter()).for_each(|(f, lwe_b)| { // sample `a` - RandomUniformDist::random_fill(&mut p_rng, &modulus, scratch.as_mut()); + RandomUniformDist::random_fill(p_rng, &modulus, scratch.as_mut()); // a * z let mut az = Ro::Element::zero(); @@ -345,14 +343,15 @@ mod tests { rng.fill_bytes(&mut ksk_seed); let mut seeded_ksk = SeededLweKeySwitchingKey::empty(lwe_in_n, lwe_out_n, d_ks, ksk_seed, q); + let mut p_rng = DefaultSecureRng::new_seeded(ksk_seed); let gadget = gadget_vector(logq, logb, d_ks); lwe_ksk_keygen( &lwe_sk_in.values(), &lwe_sk_out.values(), &mut seeded_ksk.data, &gadget, - seeded_ksk.seed, &modq_op, + &mut p_rng, &mut rng, ); // println!("{:?}", ksk); diff --git a/src/rgsw.rs b/src/rgsw.rs index cd6758c..53b9817 100644 --- a/src/rgsw.rs +++ b/src/rgsw.rs @@ -383,9 +383,8 @@ pub(crate) fn rlwe_ksk_gen< Mmut: MatrixMut + MatrixEntity, ModOp: ArithmeticOps + VectorOps, NttOp: Ntt, - R: RandomGaussianDist<[Mmut::MatElement], Parameters = Mmut::MatElement> - + RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement> - + NewWithSeed, + R: RandomGaussianDist<[Mmut::MatElement], Parameters = Mmut::MatElement>, + PR: RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement>, >( ksk_out: &mut Mmut, neg_from_s: Mmut::R, @@ -393,7 +392,7 @@ pub(crate) fn rlwe_ksk_gen< gadget_vector: &[Mmut::MatElement], mod_op: &ModOp, ntt_op: &NttOp, - seed: R::Seed, + p_rng: &mut PR, rng: &mut R, ) where ::R: RowMut, @@ -409,9 +408,8 @@ pub(crate) fn rlwe_ksk_gen< // RLWE'_{to_s}(-from_s) let mut part_a = { let mut a = Mmut::zeros(d, ring_size); - let mut p_rng = R::new_with_seed(seed); a.iter_rows_mut() - .for_each(|ai| RandomUniformDist::random_fill(&mut p_rng, &q, ai.as_mut())); + .for_each(|ai| RandomUniformDist::random_fill(p_rng, &q, ai.as_mut())); a }; izip!( @@ -443,9 +441,8 @@ pub(crate) fn galois_key_gen< ModOp: ArithmeticOps + VectorOps, NttOp: Ntt, S, - R: RandomGaussianDist<[Mmut::MatElement], Parameters = Mmut::MatElement> - + RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement> - + NewWithSeed, + R: RandomGaussianDist<[Mmut::MatElement], Parameters = Mmut::MatElement>, + PR: RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement>, >( ksk_out: &mut Mmut, s: &[S], @@ -453,7 +450,7 @@ pub(crate) fn galois_key_gen< gadget_vector: &[Mmut::MatElement], mod_op: &ModOp, ntt_op: &NttOp, - seed: R::Seed, + p_rng: &mut PR, rng: &mut R, ) where ::R: RowMut, @@ -488,7 +485,7 @@ pub(crate) fn galois_key_gen< gadget_vector, mod_op, ntt_op, - seed, + p_rng, rng, ); } @@ -731,8 +728,8 @@ pub(crate) fn secret_key_encrypt_rgsw< Mmut: MatrixMut + MatrixEntity, S, R: RandomGaussianDist<[Mmut::MatElement], Parameters = Mmut::MatElement> - + RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement> - + NewWithSeed, + + RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement>, + PR: RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement>, ModOp: VectorOps, NttOp: Ntt, >( @@ -742,13 +739,11 @@ pub(crate) fn secret_key_encrypt_rgsw< s: &[S], mod_op: &ModOp, ntt_op: &NttOp, - seed: R::Seed, + p_rng: &mut PR, rng: &mut R, ) where - ::R: - RowMut + RowEntity + TryConvertFrom<[S], Parameters = Mmut::MatElement> + Debug, - Mmut::MatElement: Copy + Debug, - Mmut: Debug, + ::R: RowMut + RowEntity + TryConvertFrom<[S], Parameters = Mmut::MatElement>, + Mmut::MatElement: Copy, { let d = gadget_vector.len(); let q = mod_op.modulus(); @@ -793,10 +788,9 @@ pub(crate) fn secret_key_encrypt_rgsw< // RLWE(m) let mut a_rlwe_dash_m = { // polynomials of part A of RLWE'(m) are sampled from seed - let mut p_rng = R::new_with_seed(seed); let mut a = Mmut::zeros(d, ring_size); a.iter_rows_mut() - .for_each(|ai| RandomUniformDist::random_fill(&mut p_rng, &q, ai.as_mut())); + .for_each(|ai| RandomUniformDist::random_fill(p_rng, &q, ai.as_mut())); a }; @@ -832,16 +826,15 @@ pub(crate) fn secret_key_encrypt_rlwe< ModOp: VectorOps, NttOp: Ntt, S, - R: RandomUniformDist<[Ro::Element], Parameters = Ro::Element> - + RandomGaussianDist<[Ro::Element], Parameters = Ro::Element> - + NewWithSeed, + R: RandomGaussianDist<[Ro::Element], Parameters = Ro::Element>, + PR: RandomUniformDist<[Ro::Element], Parameters = Ro::Element>, >( m: &Ro, b_rlwe_out: &mut Ro, s: &[S], mod_op: &ModOp, ntt_op: &NttOp, - seed: R::Seed, + p_rng: &mut PR, rng: &mut R, ) where Ro: TryConvertFrom<[S], Parameters = Ro::Element> + Debug, @@ -855,8 +848,7 @@ pub(crate) fn secret_key_encrypt_rlwe< // sample a let mut a = { let mut a = Ro::zeros(ring_size); - let mut p_rng = R::new_with_seed(seed); - RandomUniformDist::random_fill(&mut p_rng, &q, a.as_mut()); + RandomUniformDist::random_fill(p_rng, &q, a.as_mut()); a }; @@ -982,7 +974,7 @@ mod tests { backend::{ModInit, ModularOpsU64}, decomposer::{gadget_vector, DefaultDecomposer}, ntt::{self, Ntt, NttBackendU64, NttInit}, - random::{DefaultSecureRng, RandomUniformDist}, + random::{DefaultSecureRng, NewWithSeed, RandomUniformDist}, rgsw::{ measure_noise, AutoKeyEvaluationDomain, RgswCiphertextEvaluationDomain, RlweCiphertext, SeededAutoKey, SeededRgswCiphertext, SeededRlweCiphertext, @@ -1020,6 +1012,7 @@ mod tests { rng.fill_bytes(&mut rlwe_seed); let mut seeded_rlwe_in_ct = SeededRlweCiphertext::<_, [u8; 32]>::empty(ring_size as usize, rlwe_seed, q); + let mut p_rng = DefaultSecureRng::new_with_seed(rlwe_seed); let encoded_m = m0 .iter() .map(|v| (((*v as f64) * q as f64) / (p as f64)).round() as u64) @@ -1030,7 +1023,7 @@ mod tests { s.values(), &mod_op, &ntt_op, - seeded_rlwe_in_ct.seed, + &mut p_rng, &mut rng, ); let rlwe_in_ct = @@ -1046,7 +1039,7 @@ mod tests { ); let m_back = encoded_m_back .iter() - .map(|v| ((*v as f64 * p as f64) / q as f64).round() as u64) + .map(|v| (((*v as f64 * p as f64) / q as f64).round() as u64) % p) .collect_vec(); assert_eq!(m0, m_back); } @@ -1082,6 +1075,7 @@ mod tests { rgsw_seed, q, ); + let mut p_rng = DefaultSecureRng::new_seeded(rgsw_seed); let gadget_vector = gadget_vector(logq, logb, d_rgsw); secret_key_encrypt_rgsw( &mut seeded_rgsw_ct.data, @@ -1090,7 +1084,7 @@ mod tests { s.values(), &mod_op, &ntt_op, - seeded_rgsw_ct.seed, + &mut p_rng, &mut rng, ); let rgsw_ct = RgswCiphertextEvaluationDomain::<_, DefaultSecureRng, NttBackendU64>::from( @@ -1102,6 +1096,7 @@ mod tests { rng.fill_bytes(&mut rlwe_seed); let mut seeded_rlwe_in_ct = SeededRlweCiphertext::<_, [u8; 32]>::empty(ring_size as usize, rlwe_seed, q); + let mut p_rng = DefaultSecureRng::new_seeded(rlwe_seed); let encoded_m = m0 .iter() .map(|v| (((*v as f64) * q as f64) / (p as f64)).round() as u64) @@ -1112,7 +1107,7 @@ mod tests { s.values(), &mod_op, &ntt_op, - seeded_rlwe_in_ct.seed, + &mut p_rng, &mut rng, ); let mut rlwe_in_ct = @@ -1181,13 +1176,14 @@ mod tests { let mut seed_rlwe = [0u8; 32]; rng.fill_bytes(&mut seed_rlwe); let mut seeded_rlwe_m = SeededRlweCiphertext::empty(ring_size as usize, seed_rlwe, q); + let mut p_rng = DefaultSecureRng::new_seeded(seed_rlwe); secret_key_encrypt_rlwe( &encoded_m, &mut seeded_rlwe_m.data, s.values(), &mod_op, &ntt_op, - seeded_rlwe_m.seed, + &mut p_rng, &mut rng, ); let mut rlwe_m = RlweCiphertext::>, DefaultSecureRng>::from(&seeded_rlwe_m); @@ -1198,6 +1194,7 @@ mod tests { let mut seed_auto = [0u8; 32]; rng.fill_bytes(&mut seed_auto); let mut seeded_auto_key = SeededAutoKey::empty(ring_size as usize, d_rgsw, seed_auto, q); + let mut p_rng = DefaultSecureRng::new_seeded(seed_auto); let gadget_vector = gadget_vector(logq, logb, d_rgsw); galois_key_gen( &mut seeded_auto_key.data, @@ -1206,7 +1203,7 @@ mod tests { &gadget_vector, &mod_op, &ntt_op, - seeded_auto_key.seed, + &mut p_rng, &mut rng, ); let auto_key =