arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/ggsw/encryption.rs
core/src/ggsw/encryption.rsRaw
 1use backend::hal::{
 2    api::{
 3        ScratchAvailable, TakeVecZnx, TakeVecZnxDft, VecZnxAddScalarInplace, VecZnxAllocBytes, VecZnxNormalizeInplace, ZnxZero,
 4    },
 5    layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, Scratch},
 6};
 7use sampling::source::Source;
 8
 9use crate::{GGSWCiphertext, GLWECiphertext, GLWEEncryptSkFamily, GLWESecretExec, Infos, TakeGLWEPt};
10
11pub trait GGSWEncryptSkFamily<B: Backend> = GLWEEncryptSkFamily<B>;
12
13impl GGSWCiphertext<Vec<u8>> {
14    pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize, rank: usize) -> usize
15    where
16        Module<B>: GGSWEncryptSkFamily<B> + VecZnxAllocBytes,
17    {
18        let size = k.div_ceil(basek);
19        GLWECiphertext::encrypt_sk_scratch_space(module, basek, k)
20            + module.vec_znx_alloc_bytes(rank + 1, size)
21            + module.vec_znx_alloc_bytes(1, size)
22            + module.vec_znx_dft_alloc_bytes(rank + 1, size)
23    }
24}
25
26impl<DataSelf: DataMut> GGSWCiphertext<DataSelf> {
27    pub fn encrypt_sk<DataPt: DataRef, DataSk: DataRef, B: Backend>(
28        &mut self,
29        module: &Module<B>,
30        pt: &ScalarZnx<DataPt>,
31        sk: &GLWESecretExec<DataSk, B>,
32        source_xa: &mut Source,
33        source_xe: &mut Source,
34        sigma: f64,
35        scratch: &mut Scratch<B>,
36    ) where
37        Module<B>: GGSWEncryptSkFamily<B> + VecZnxAddScalarInplace,
38        Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx<B>,
39    {
40        #[cfg(debug_assertions)]
41        {
42            use backend::hal::api::ZnxInfos;
43
44            assert_eq!(self.rank(), sk.rank());
45            assert_eq!(self.n(), module.n());
46            assert_eq!(pt.n(), module.n());
47            assert_eq!(sk.n(), module.n());
48        }
49
50        let basek: usize = self.basek();
51        let k: usize = self.k();
52        let rank: usize = self.rank();
53        let digits: usize = self.digits();
54
55        let (mut tmp_pt, scratch1) = scratch.take_glwe_pt(module, basek, k);
56
57        (0..self.rows()).for_each(|row_i| {
58            tmp_pt.data.zero();
59
60            // Adds the scalar_znx_pt to the i-th limb of the vec_znx_pt
61            module.vec_znx_add_scalar_inplace(&mut tmp_pt.data, 0, (digits - 1) + row_i * digits, pt, 0);
62            module.vec_znx_normalize_inplace(basek, &mut tmp_pt.data, 0, scratch1);
63
64            (0..rank + 1).for_each(|col_j| {
65                // rlwe encrypt of vec_znx_pt into vec_znx_ct
66
67                self.at_mut(row_i, col_j).encrypt_sk_internal(
68                    module,
69                    Some((&tmp_pt, col_j)),
70                    sk,
71                    source_xa,
72                    source_xe,
73                    sigma,
74                    scratch1,
75                );
76            });
77        });
78    }
79}