poulpy/core/src/lwe/encryption.rs
core/src/lwe/encryption.rsRaw
1use backend::{AddNormal, FillUniform, VecZnx, ZnxView, ZnxViewMut, alloc_aligned};
2use sampling::source::Source;
3
4use crate::{Infos, LWECiphertext, LWESecret, SIX_SIGMA, lwe::LWEPlaintext};
5
6impl<DataSelf> LWECiphertext<DataSelf>
7where
8 DataSelf: AsMut<[u8]> + AsRef<[u8]>,
9{
10 pub fn encrypt_sk<DataPt, DataSk>(
11 &mut self,
12 pt: &LWEPlaintext<DataPt>,
13 sk: &LWESecret<DataSk>,
14 source_xa: &mut Source,
15 source_xe: &mut Source,
16 sigma: f64,
17 ) where
18 DataPt: AsRef<[u8]>,
19 DataSk: AsRef<[u8]>,
20 {
21 #[cfg(debug_assertions)]
22 {
23 assert_eq!(self.n(), sk.n())
24 }
25
26 let basek: usize = self.basek();
27
28 self.data.fill_uniform(basek, 0, self.size(), source_xa);
29 let mut tmp_znx: VecZnx<Vec<u8>> = VecZnx::<Vec<u8>>::new::<i64>(1, 1, self.size());
30
31 let min_size = self.size().min(pt.size());
32
33 (0..min_size).for_each(|i| {
34 tmp_znx.at_mut(0, i)[0] = pt.data.at(0, i)[0]
35 - self.data.at(0, i)[1..]
36 .iter()
37 .zip(sk.data.at(0, 0))
38 .map(|(x, y)| x * y)
39 .sum::<i64>();
40 });
41
42 (min_size..self.size()).for_each(|i| {
43 tmp_znx.at_mut(0, i)[0] -= self.data.at(0, i)[1..]
44 .iter()
45 .zip(sk.data.at(0, 0))
46 .map(|(x, y)| x * y)
47 .sum::<i64>();
48 });
49
50 tmp_znx.add_normal(basek, 0, self.k(), source_xe, sigma, sigma * SIX_SIGMA);
51
52 let mut tmp_bytes: Vec<u8> = alloc_aligned(size_of::<i64>());
53
54 tmp_znx.normalize(basek, 0, &mut tmp_bytes);
55
56 (0..self.size()).for_each(|i| {
57 self.data.at_mut(0, i)[0] = tmp_znx.at(0, i)[0];
58 });
59 }
60}