arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/lwe/encryption.rs
core/src/lwe/encryption.rsRaw
 1use backend::hal::{
 2    api::{
 3        ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxAddNormal, VecZnxFillUniform, VecZnxNormalizeInplace, ZnxView, ZnxViewMut,
 4    },
 5    layouts::{Backend, DataMut, DataRef, Module, ScratchOwned, VecZnx},
 6    oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl},
 7};
 8use sampling::source::Source;
 9
10use crate::{Infos, LWECiphertext, LWESecret, SIX_SIGMA, lwe::LWEPlaintext};
11
12impl<DataSelf: DataMut> LWECiphertext<DataSelf> {
13    pub fn encrypt_sk<DataPt, DataSk, B: Backend>(
14        &mut self,
15        module: &Module<B>,
16        pt: &LWEPlaintext<DataPt>,
17        sk: &LWESecret<DataSk>,
18        source_xa: &mut Source,
19        source_xe: &mut Source,
20        sigma: f64,
21    ) where
22        DataPt: DataRef,
23        DataSk: DataRef,
24        Module<B>: VecZnxFillUniform + VecZnxAddNormal + VecZnxNormalizeInplace<B>,
25        B: ScratchOwnedAllocImpl<B> + ScratchOwnedBorrowImpl<B>,
26    {
27        #[cfg(debug_assertions)]
28        {
29            assert_eq!(self.n(), sk.n())
30        }
31
32        let basek: usize = self.basek();
33        let k: usize = self.k();
34
35        module.vec_znx_fill_uniform(basek, &mut self.data, 0, k, source_xa);
36
37        let mut tmp_znx: VecZnx<Vec<u8>> = VecZnx::<Vec<u8>>::new::<i64>(1, 1, self.size());
38
39        let min_size = self.size().min(pt.size());
40
41        (0..min_size).for_each(|i| {
42            tmp_znx.at_mut(0, i)[0] = pt.data.at(0, i)[0]
43                - 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        (min_size..self.size()).for_each(|i| {
51            tmp_znx.at_mut(0, i)[0] -= self.data.at(0, i)[1..]
52                .iter()
53                .zip(sk.data.at(0, 0))
54                .map(|(x, y)| x * y)
55                .sum::<i64>();
56        });
57
58        module.vec_znx_add_normal(
59            basek,
60            &mut self.data,
61            0,
62            k,
63            source_xe,
64            sigma,
65            sigma * SIX_SIGMA,
66        );
67
68        module.vec_znx_normalize_inplace(
69            basek,
70            &mut tmp_znx,
71            0,
72            ScratchOwned::alloc(size_of::<i64>()).borrow(),
73        );
74
75        (0..self.size()).for_each(|i| {
76            self.data.at_mut(0, i)[0] = tmp_znx.at(0, i)[0];
77        });
78    }
79}