diff --git a/backend/src/lib.rs b/backend/src/lib.rs index 09e5556..d55ba8a 100644 --- a/backend/src/lib.rs +++ b/backend/src/lib.rs @@ -103,7 +103,7 @@ fn alloc_aligned_custom_u8(size: usize, align: usize) -> Vec { /// Size of T * size msut be a multiple of [DEFAULTALIGN]. pub fn alloc_aligned_custom(size: usize, align: usize) -> Vec { assert_eq!( - (size * size_of::()) % (align/ size_of::()), + (size * size_of::()) % (align / size_of::()), 0, "size={} must be a multiple of align={}", size, diff --git a/backend/src/scalar_znx.rs b/backend/src/scalar_znx.rs index 0a5bb64..2cc1797 100644 --- a/backend/src/scalar_znx.rs +++ b/backend/src/scalar_znx.rs @@ -93,7 +93,7 @@ impl + AsRef<[u8]>> ScalarZnx { pub fn fill_binary_block(&mut self, col: usize, block_size: usize, source: &mut Source) { assert!(self.n() % block_size == 0); let max_idx: u64 = (block_size + 1) as u64; - let mask_idx: u64 = (1<<((u64::BITS - max_idx.leading_zeros())as u64)) - 1 ; + let mask_idx: u64 = (1 << ((u64::BITS - max_idx.leading_zeros()) as u64)) - 1; for block in self.at_mut(col, 0).chunks_mut(block_size) { let idx: usize = source.next_u64n(max_idx, mask_idx) as usize; if idx != block_size { diff --git a/backend/src/vec_znx.rs b/backend/src/vec_znx.rs index 8213d5e..6189bad 100644 --- a/backend/src/vec_znx.rs +++ b/backend/src/vec_znx.rs @@ -243,13 +243,12 @@ fn normalize_tmp_bytes(n: usize) -> usize { n * std::mem::size_of::() } -impl + AsMut<[u8]>> VecZnx{ - pub fn normalize(&mut self, basek: usize, a_col: usize, tmp_bytes: &mut [u8]){ +impl + AsMut<[u8]>> VecZnx { + pub fn normalize(&mut self, basek: usize, a_col: usize, tmp_bytes: &mut [u8]) { normalize(basek, self, a_col, tmp_bytes); } } - fn normalize + AsRef<[u8]>>(basek: usize, a: &mut VecZnx, a_col: usize, tmp_bytes: &mut [u8]) { let n: usize = a.n(); diff --git a/core/src/blind_rotation/ccgi.rs b/core/src/blind_rotation/ccgi.rs index 769ebb5..f560d09 100644 --- a/core/src/blind_rotation/ccgi.rs +++ b/core/src/blind_rotation/ccgi.rs @@ -1,10 +1,15 @@ use std::time::Instant; -use backend::{MatZnxDftOps, MatZnxDftScratch, Module, ScalarZnxDftOps, Scratch, VecZnxDftOps, VecZnxOps, ZnxView, ZnxViewMut, ZnxZero, FFT64}; +use backend::{ + FFT64, MatZnxDftOps, MatZnxDftScratch, Module, ScalarZnxDftOps, Scratch, VecZnxDftOps, VecZnxOps, ZnxView, ZnxViewMut, + ZnxZero, +}; use itertools::izip; use crate::{ - blind_rotation::key::BlindRotationKeyCGGI, lwe::ciphertext::LWECiphertextToRef, FourierGLWESecret, GGSWCiphertext, GLWECiphertext, GLWECiphertextToMut, GLWECiphertextToRef, GLWEPlaintext, GLWESecret, Infos, LWECiphertext, LWESecret, ScratchCore + GGSWCiphertext, GLWECiphertext, GLWECiphertextToMut, Infos, LWECiphertext, ScratchCore, + blind_rotation::{key::BlindRotationKeyCGGI, lut::LookUpTable}, + lwe::ciphertext::LWECiphertextToRef, }; pub fn cggi_blind_rotate_scratch_space( @@ -21,26 +26,24 @@ pub fn cggi_blind_rotate_scratch_space( | GLWECiphertext::external_product_inplace_scratch_space(module, basek, k_lut, k_brk, 1, rank)) } -pub fn cggi_blind_rotate( +pub fn cggi_blind_rotate( module: &Module, res: &mut GLWECiphertext, lwe: &LWECiphertext, - lut: &GLWEPlaintext, + lut: &LookUpTable, brk: &BlindRotationKeyCGGI, scratch: &mut Scratch, ) where DataRes: AsRef<[u8]> + AsMut<[u8]>, DataIn: AsRef<[u8]>, - DataLUT: AsRef<[u8]>, { let basek = res.basek(); let mut lwe_2n: Vec = vec![0i64; lwe.n() + 1]; // TODO: from scratch space let mut out_mut: GLWECiphertext<&mut [u8]> = res.to_mut(); let lwe_ref: LWECiphertext<&[u8]> = lwe.to_ref(); - let lut_ref: GLWECiphertext<&[u8]> = lut.to_ref(); - let cols = out_mut.rank()+1; + let cols: usize = out_mut.rank() + 1; mod_switch_2n(module, &mut lwe_2n, &lwe_ref); @@ -50,7 +53,7 @@ pub fn cggi_blind_rotate( out_mut.data.zero(); // Initialize out to X^{b} * LUT(X) - module.vec_znx_rotate(b, &mut out_mut.data, 0, &lut_ref.data, 0); + module.vec_znx_rotate(b, &mut out_mut.data, 0, &lut.data[0], 0); let block_size: usize = brk.block_size(); @@ -68,37 +71,32 @@ pub fn cggi_blind_rotate( brk.data.chunks_exact(block_size) ) .for_each(|(ai, ski)| { - out_mut.dft(module, &mut acc_dft); acc_add_dft.data.zero(); - izip!(ai.iter(), ski.iter()) - .enumerate() - .for_each(|(i, (aii, skii))| { + izip!(ai.iter(), ski.iter()).for_each(|(aii, skii)| { + // vmp_res = DFT(acc) * BRK[i] + module.vmp_apply(&mut vmp_res.data, &acc_dft.data, &skii.data, scratch5); - // vmp_res = DFT(acc) * BRK[i] - module.vmp_apply(&mut vmp_res.data, &acc_dft.data, &skii.data, scratch5); + // DFT(X^ai -1) + xai_minus_one.zero(); + xai_minus_one.at_mut(0, 0)[0] = 1; + module.vec_znx_rotate_inplace(*aii, &mut xai_minus_one, 0); + xai_minus_one.at_mut(0, 0)[0] -= 1; + module.svp_prepare(&mut xai_minus_one_dft, 0, &xai_minus_one, 0); - // DFT(X^ai -1) - xai_minus_one.zero(); - xai_minus_one.at_mut(0, 0)[0] = 1; - module.vec_znx_rotate_inplace(*aii, &mut xai_minus_one, 0); - xai_minus_one.at_mut(0, 0)[0] -= 1; - module.svp_prepare(&mut xai_minus_one_dft, 0, &xai_minus_one, 0); - - // DFT(X^ai -1) * (DFT(acc) * BRK[i]) - (0..cols).for_each(|i|{ - module.svp_apply_inplace(&mut vmp_res.data, i, &xai_minus_one_dft, 0); - module.vec_znx_dft_add_inplace(&mut acc_add_dft.data, i, &vmp_res.data, i); - }); + // DFT(X^ai -1) * (DFT(acc) * BRK[i]) + (0..cols).for_each(|i| { + module.svp_apply_inplace(&mut vmp_res.data, i, &xai_minus_one_dft, 0); + module.vec_znx_dft_add_inplace(&mut acc_add_dft.data, i, &vmp_res.data, i); }); - - (0..cols).for_each(|i|{ + }); + + (0..cols).for_each(|i| { module.vec_znx_dft_add_inplace(&mut acc_dft.data, i, &acc_add_dft.data, i); }); - - acc_dft.idft(module, &mut out_mut, scratch5); + acc_dft.idft(module, &mut out_mut, scratch5); }); let duration: std::time::Duration = start.elapsed(); println!("external products: {} us", duration.as_micros()); diff --git a/core/src/blind_rotation/key.rs b/core/src/blind_rotation/key.rs index 9f23c61..8cb24cb 100644 --- a/core/src/blind_rotation/key.rs +++ b/core/src/blind_rotation/key.rs @@ -69,14 +69,17 @@ impl BlindRotationKeyCGGI { } } + #[allow(dead_code)] pub(crate) fn rows(&self) -> usize { self.data[0].rows() } + #[allow(dead_code)] pub(crate) fn k(&self) -> usize { self.data[0].k() } + #[allow(dead_code)] pub(crate) fn rank(&self) -> usize { self.data[0].rank() } diff --git a/core/src/blind_rotation/lut.rs b/core/src/blind_rotation/lut.rs new file mode 100644 index 0000000..56b65a0 --- /dev/null +++ b/core/src/blind_rotation/lut.rs @@ -0,0 +1,84 @@ +use backend::{FFT64, Module, ScratchOwned, VecZnx, VecZnxAlloc, VecZnxOps, ZnxInfos, ZnxViewMut, alloc_aligned}; + +pub struct LookUpTable { + pub(crate) data: Vec>>, + pub(crate) basek: usize, + pub(crate) k: usize, +} + +impl LookUpTable { + pub fn alloc(module: &Module, basek: usize, k: usize, extend_factor: usize) -> Self { + let size: usize = k.div_ceil(basek); + let mut data: Vec>> = Vec::with_capacity(extend_factor); + (0..extend_factor).for_each(|_| { + data.push(module.new_vec_znx(1, size)); + }); + Self { data, basek, k } + } + + pub fn set(&mut self, module: &Module, f: fn(i64) -> i64, message_modulus: usize) { + let basek: usize = self.basek; + + // Get the number minimum limb to store the message modulus + let limbs: usize = message_modulus.div_ceil(1 << basek); + + // Scaling factor + let scale: i64 = (1 << (basek * limbs - 1)).div_round(message_modulus) as i64; + + // Updates function + let f_scaled = |x: i64| (f(x) % message_modulus as i64) * scale; + + // If LUT size > module.n() + let domain_size: usize = self.data[0].n() * self.data.len(); + + let size: usize = self.k.div_ceil(self.basek); + + // Equivalent to AUTO([f(0), f(1), ..., f(n-1)], -1) + let mut lut_full: VecZnx> = VecZnx::new::(domain_size, 1, size); + { + let lut_at: &mut [i64] = lut_full.at_mut(0, limbs - 1); + + let start: usize = 0; + let end: usize = (domain_size).div_round(message_modulus); + + let y: i64 = f_scaled(0); + (start..end).for_each(|i| { + lut_at[i] = y; + }); + + (1..message_modulus).for_each(|x| { + let start: usize = (x * domain_size).div_round(message_modulus); + let end: usize = ((x + 1) * domain_size).div_round(message_modulus); + let y: i64 = f_scaled(x as i64); + (start..end).for_each(|i| { + lut_at[domain_size - i] = -y; + }) + }); + } + + // Rotates half the step to the left + let half_step: usize = domain_size.div_round(message_modulus << 1); + module.vec_znx_rotate_inplace(-(half_step as i64), &mut lut_full, 0); + + let mut tmp_bytes: Vec = alloc_aligned(lut_full.n() * size_of::()); + lut_full.normalize(self.basek, 0, &mut tmp_bytes); + + if self.data.len() > 1 { + let mut scratch: ScratchOwned = ScratchOwned::new(module.bytes_of_vec_znx(1, size)); + module.vec_znx_split(&mut self.data, 0, &lut_full, 0, scratch.borrow()); + } else { + module.vec_znx_copy(&mut self.data[0], 0, &lut_full, 0); + } + } +} + +pub trait DivRound { + fn div_round(self, rhs: Self) -> Self; +} + +impl DivRound for usize { + #[inline] + fn div_round(self, rhs: Self) -> Self { + (self + rhs / 2) / rhs + } +} diff --git a/core/src/blind_rotation/mod.rs b/core/src/blind_rotation/mod.rs index 63fb3fd..1b3d5ff 100644 --- a/core/src/blind_rotation/mod.rs +++ b/core/src/blind_rotation/mod.rs @@ -1,6 +1,7 @@ // pub mod cggi; pub mod ccgi; pub mod key; +pub mod lut; #[cfg(test)] pub mod test_fft64; diff --git a/core/src/blind_rotation/test_fft64/cggi.rs b/core/src/blind_rotation/test_fft64/cggi.rs index 746ec1e..bb98cea 100644 --- a/core/src/blind_rotation/test_fft64/cggi.rs +++ b/core/src/blind_rotation/test_fft64/cggi.rs @@ -1,10 +1,16 @@ use std::time::Instant; -use backend::{Encoding, Module, ScratchOwned, Stats, ZnxView, ZnxViewMut, FFT64}; +use backend::{Encoding, FFT64, Module, ScratchOwned, Stats, VecZnxOps, ZnxView}; use sampling::source::Source; use crate::{ - blind_rotation::{ccgi::{cggi_blind_rotate, cggi_blind_rotate_scratch_space, mod_switch_2n}, key::BlindRotationKeyCGGI}, lwe::{ciphertext::{LWECiphertextToMut, LWECiphertextToRef}, LWEPlaintext}, FourierGLWESecret, GLWECiphertext, GLWEOps, GLWEPlaintext, GLWESecret, Infos, LWECiphertext, LWESecret + FourierGLWESecret, GLWECiphertext, GLWEPlaintext, GLWESecret, Infos, LWECiphertext, LWESecret, + blind_rotation::{ + ccgi::{cggi_blind_rotate, cggi_blind_rotate_scratch_space, mod_switch_2n}, + key::BlindRotationKeyCGGI, + lut::LookUpTable, + }, + lwe::{LWEPlaintext, ciphertext::LWECiphertextToRef}, }; #[test] @@ -21,6 +27,8 @@ fn blind_rotation() { let rank: usize = 1; let block_size: usize = 7; + let message_modulus: usize = 64; + let mut source_xs: Source = Source::new([0u8; 32]); let mut source_xe: Source = Source::new([0u8; 32]); let mut source_xa: Source = Source::new([0u8; 32]); @@ -32,12 +40,14 @@ fn blind_rotation() { let mut sk_lwe: LWESecret> = LWESecret::alloc(n_lwe); sk_lwe.fill_binary_block(block_size, &mut source_xs); - let mut scratch: ScratchOwned = ScratchOwned::new(BlindRotationKeyCGGI::generate_from_sk_scratch_space( - &module, basek, k_brk, rank, - ) | cggi_blind_rotate_scratch_space(&module, basek, k_lut, k_brk, rows_brk, rank)); + let mut scratch: ScratchOwned = ScratchOwned::new( + BlindRotationKeyCGGI::generate_from_sk_scratch_space(&module, basek, k_brk, rank) + | cggi_blind_rotate_scratch_space(&module, basek, k_lut, k_brk, rows_brk, rank), + ); let start: Instant = Instant::now(); let mut brk: BlindRotationKeyCGGI = BlindRotationKeyCGGI::allocate(&module, n_lwe, basek, k_brk, rows_brk, rank); + brk.generate_from_sk( &module, &sk_glwe_dft, @@ -47,6 +57,7 @@ fn blind_rotation() { 3.2, scratch.borrow(), ); + let duration: std::time::Duration = start.elapsed(); println!("brk-gen: {} ms", duration.as_millis()); @@ -67,44 +78,48 @@ fn blind_rotation() { println!("{}", pt_lwe.data); - let mut lut: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_lut); - - - lut.data.at_mut(0, 0)[0] = 0; - (1..module.n()).for_each(|i|{ - lut.data.at_mut(0, 0)[i] = - ((module.n() as i64 - i as i64 - 1)<<(basek - module.log_n() - 1)); - }); - - + fn lut_fn(x: i64) -> i64 { + 2 * x + 1 + } + let mut lut: LookUpTable = LookUpTable::alloc(&module, basek, k_lut, 1); + lut.set(&module, lut_fn, message_modulus); let mut res: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_lut, rank); let start: Instant = Instant::now(); - (0..1).for_each(|i|{ + (0..1).for_each(|_| { cggi_blind_rotate(&module, &mut res, &lwe, &lut, &brk, scratch.borrow()); }); - + let duration: std::time::Duration = start.elapsed(); println!("blind-rotate: {} ms", duration.as_millis()); let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_lut); - res.decrypt(&module , &mut pt_have, &sk_glwe_dft, scratch.borrow()); + res.decrypt(&module, &mut pt_have, &sk_glwe_dft, scratch.borrow()); + + println!("pt_have: {}", pt_have.data); let mut lwe_2n: Vec = vec![0i64; lwe.n() + 1]; // TODO: from scratch space mod_switch_2n(&module, &mut lwe_2n, &lwe.to_ref()); - let pt_want: i64 = (lwe_2n[0] + lwe_2n[1..].iter().zip(sk_lwe.data.at(0, 0)).map(|(x, y)| x * y).sum::()) % (module.n() as i64 * 2); + let pt_want: i64 = (lwe_2n[0] + + lwe_2n[1..] + .iter() + .zip(sk_lwe.data.at(0, 0)) + .map(|(x, y)| x * y) + .sum::()) + % (module.n() as i64 * 2); - lut.rotate_inplace(&module, pt_want); + module.vec_znx_rotate_inplace(pt_want, &mut lut.data[0], 0); - lut.sub_inplace_ab(&module, &pt_have); + println!("pt_want: {}", lut.data[0]); - let noise: f64 = lut.data.std(0, basek); + module.vec_znx_sub_ab_inplace(&mut lut.data[0], 0, &pt_have.data, 0); + + let noise: f64 = lut.data[0].std(0, basek); println!("noise: {}", noise); - - } diff --git a/core/src/glwe/test_fft64/automorphism.rs b/core/src/glwe/test_fft64/automorphism.rs index 1b46e63..ba739c6 100644 --- a/core/src/glwe/test_fft64/automorphism.rs +++ b/core/src/glwe/test_fft64/automorphism.rs @@ -3,8 +3,7 @@ use backend::{FFT64, FillUniform, Module, ScratchOwned, Stats, VecZnxOps}; use sampling::source::Source; use crate::{ - FourierGLWESecret, GLWEAutomorphismKey, GLWECiphertext, GLWEPlaintext, GLWESecret, Infos, - noise::log2_std_noise_gglwe_product, + FourierGLWESecret, GLWEAutomorphismKey, GLWECiphertext, GLWEPlaintext, GLWESecret, Infos, noise::log2_std_noise_gglwe_product, }; #[test] diff --git a/core/src/glwe/test_fft64/external_product.rs b/core/src/glwe/test_fft64/external_product.rs index aec23b6..e1f6b19 100644 --- a/core/src/glwe/test_fft64/external_product.rs +++ b/core/src/glwe/test_fft64/external_product.rs @@ -1,9 +1,7 @@ use backend::{FFT64, FillUniform, Module, ScalarZnx, ScalarZnxAlloc, ScratchOwned, Stats, VecZnxOps, ZnxViewMut}; use sampling::source::Source; -use crate::{ - FourierGLWESecret, GGSWCiphertext, GLWECiphertext, GLWEPlaintext, GLWESecret, Infos, noise::noise_ggsw_product, -}; +use crate::{FourierGLWESecret, GGSWCiphertext, GLWECiphertext, GLWEPlaintext, GLWESecret, Infos, noise::noise_ggsw_product}; #[test] fn apply() { diff --git a/core/src/glwe/test_fft64/keyswitch.rs b/core/src/glwe/test_fft64/keyswitch.rs index 732ef03..fb54204 100644 --- a/core/src/glwe/test_fft64/keyswitch.rs +++ b/core/src/glwe/test_fft64/keyswitch.rs @@ -2,8 +2,7 @@ use backend::{FFT64, FillUniform, Module, ScratchOwned, Stats, VecZnxOps}; use sampling::source::Source; use crate::{ - FourierGLWESecret, GLWECiphertext, GLWEPlaintext, GLWESecret, GLWESwitchingKey, Infos, - noise::log2_std_noise_gglwe_product, + FourierGLWESecret, GLWECiphertext, GLWEPlaintext, GLWESecret, GLWESwitchingKey, Infos, noise::log2_std_noise_gglwe_product, }; #[test] diff --git a/core/src/glwe/test_fft64/trace.rs b/core/src/glwe/test_fft64/trace.rs index 24b0a75..fe4e1eb 100644 --- a/core/src/glwe/test_fft64/trace.rs +++ b/core/src/glwe/test_fft64/trace.rs @@ -4,8 +4,7 @@ use backend::{FFT64, FillUniform, Module, ScratchOwned, Stats, VecZnxOps, ZnxVie use sampling::source::Source; use crate::{ - FourierGLWESecret, GLWEAutomorphismKey, GLWECiphertext, GLWEPlaintext, GLWESecret, Infos, - noise::var_noise_gglwe_product, + FourierGLWESecret, GLWEAutomorphismKey, GLWECiphertext, GLWEPlaintext, GLWESecret, Infos, noise::var_noise_gglwe_product, }; #[test] diff --git a/core/src/lwe/ciphertext.rs b/core/src/lwe/ciphertext.rs index 4b8c85d..1e97eb4 100644 --- a/core/src/lwe/ciphertext.rs +++ b/core/src/lwe/ciphertext.rs @@ -11,7 +11,7 @@ pub struct LWECiphertext { impl LWECiphertext> { pub fn alloc(n: usize, basek: usize, k: usize) -> Self { Self { - data: VecZnx::new::(n+1, 1, k.div_ceil(basek)), + data: VecZnx::new::(n + 1, 1, k.div_ceil(basek)), k: k, basek: basek, } @@ -21,8 +21,8 @@ impl LWECiphertext> { impl Infos for LWECiphertext { type Inner = VecZnx; - fn n(&self) -> usize{ - &self.inner().n-1 + fn n(&self) -> usize { + &self.inner().n - 1 } fn inner(&self) -> &Self::Inner { diff --git a/core/src/lwe/decryption.rs b/core/src/lwe/decryption.rs index 5f7c201..3ed9d2b 100644 --- a/core/src/lwe/decryption.rs +++ b/core/src/lwe/decryption.rs @@ -1,15 +1,28 @@ -use backend::{alloc_aligned, ZnxView, ZnxViewMut}; +use backend::{ZnxView, ZnxViewMut, alloc_aligned}; -use crate::{lwe::{LWEPlaintext}, Infos, LWECiphertext, LWESecret, SetMetaData}; +use crate::{Infos, LWECiphertext, LWESecret, SetMetaData, lwe::LWEPlaintext}; -impl LWECiphertext where DataSelf: AsRef<[u8]>{ - pub fn decrypt(&self, pt: &mut LWEPlaintext, sk: &LWESecret) where DataPt: AsRef<[u8]> + AsMut<[u8]>, DataSk: AsRef<[u8]>{ - #[cfg(debug_assertions)]{ +impl LWECiphertext +where + DataSelf: AsRef<[u8]>, +{ + pub fn decrypt(&self, pt: &mut LWEPlaintext, sk: &LWESecret) + where + DataPt: AsRef<[u8]> + AsMut<[u8]>, + DataSk: AsRef<[u8]>, + { + #[cfg(debug_assertions)] + { assert_eq!(self.n(), sk.n()); } - (0..pt.size().min(self.size())).for_each(|i|{ - pt.data.at_mut(0, i)[0] = self.data.at(0, i)[0] + self.data.at(0, i)[1..].iter().zip(sk.data.at(0, 0)).map(|(x, y)| x * y).sum::(); + (0..pt.size().min(self.size())).for_each(|i| { + pt.data.at_mut(0, i)[0] = self.data.at(0, i)[0] + + self.data.at(0, i)[1..] + .iter() + .zip(sk.data.at(0, 0)) + .map(|(x, y)| x * y) + .sum::(); }); let mut tmp_bytes: Vec = alloc_aligned(size_of::()); @@ -18,4 +31,4 @@ impl LWECiphertext where DataSelf: AsRef<[u8]>{ pt.set_basek(self.basek()); pt.set_k(self.k().min(pt.size() * self.basek())); } -} \ No newline at end of file +} diff --git a/core/src/lwe/encryption.rs b/core/src/lwe/encryption.rs index 5e993d9..148e5c4 100644 --- a/core/src/lwe/encryption.rs +++ b/core/src/lwe/encryption.rs @@ -1,14 +1,25 @@ -use backend::{alloc_aligned, AddNormal, FillUniform, VecZnx, ZnxView, ZnxViewMut}; +use backend::{AddNormal, FillUniform, VecZnx, ZnxView, ZnxViewMut, alloc_aligned}; use sampling::source::Source; -use crate::{lwe::LWEPlaintext, Infos, LWECiphertext, LWESecret, SIX_SIGMA}; +use crate::{Infos, LWECiphertext, LWESecret, SIX_SIGMA, lwe::LWEPlaintext}; - - -impl LWECiphertext where DataSelf: AsMut<[u8]> + AsRef<[u8]>{ - pub fn encrypt_sk(&mut self, pt: &LWEPlaintext, sk: &LWESecret, source_xa: &mut Source, source_xe: &mut Source, sigma: f64) where DataPt: AsRef<[u8]>, DataSk: AsRef<[u8]>{ - - #[cfg(debug_assertions)]{ +impl LWECiphertext +where + DataSelf: AsMut<[u8]> + AsRef<[u8]>, +{ + pub fn encrypt_sk( + &mut self, + pt: &LWEPlaintext, + sk: &LWESecret, + source_xa: &mut Source, + source_xe: &mut Source, + sigma: f64, + ) where + DataPt: AsRef<[u8]>, + DataSk: AsRef<[u8]>, + { + #[cfg(debug_assertions)] + { assert_eq!(self.n(), sk.n()) } @@ -17,19 +28,23 @@ impl LWECiphertext where DataSelf: AsMut<[u8]> + AsRef<[u8]> self.data.fill_uniform(basek, 0, self.size(), source_xa); let mut tmp_znx: VecZnx> = VecZnx::>::new::(1, 1, self.size()); - (0..self.size()).for_each(|i|{ - tmp_znx.at_mut(0, i)[0] = pt.data.at(0, i)[0] - self.data.at(0, i)[1..].iter().zip(sk.data.at(0, 0)).map(|(x, y)| x * y).sum::(); + (0..self.size()).for_each(|i| { + tmp_znx.at_mut(0, i)[0] = pt.data.at(0, i)[0] + - self.data.at(0, i)[1..] + .iter() + .zip(sk.data.at(0, 0)) + .map(|(x, y)| x * y) + .sum::(); }); - tmp_znx.add_normal(basek, 0, self.k(), source_xe, sigma, sigma*SIX_SIGMA); + tmp_znx.add_normal(basek, 0, self.k(), source_xe, sigma, sigma * SIX_SIGMA); let mut tmp_bytes: Vec = alloc_aligned(size_of::()); tmp_znx.normalize(basek, 0, &mut tmp_bytes); - (0..self.size()).for_each(|i|{ + (0..self.size()).for_each(|i| { self.data.at_mut(0, i)[0] = tmp_znx.at(0, i)[0]; }); - } } diff --git a/core/src/lwe/mod.rs b/core/src/lwe/mod.rs index 19a8362..b7bb7ed 100644 --- a/core/src/lwe/mod.rs +++ b/core/src/lwe/mod.rs @@ -1,9 +1,9 @@ pub mod ciphertext; -pub mod secret; -pub mod encryption; pub mod decryption; +pub mod encryption; pub mod plaintext; +pub mod secret; pub use ciphertext::LWECiphertext; -pub use secret::LWESecret; pub use plaintext::LWEPlaintext; +pub use secret::LWESecret; diff --git a/core/src/lwe/plaintext.rs b/core/src/lwe/plaintext.rs index a1c0482..7c73351 100644 --- a/core/src/lwe/plaintext.rs +++ b/core/src/lwe/plaintext.rs @@ -2,7 +2,7 @@ use backend::{VecZnx, VecZnxToMut, VecZnxToRef}; use crate::{Infos, SetMetaData}; -pub struct LWEPlaintext{ +pub struct LWEPlaintext { pub(crate) data: VecZnx, pub(crate) k: usize, pub(crate) basek: usize, @@ -70,4 +70,4 @@ impl + AsRef<[u8]>> LWEPlaintextToMut for LWEPlaintext { k: self.k, } } -} \ No newline at end of file +}