Skip to main content

poulpy_core/default/noise/
gglwe.rs

1use poulpy_hal::{
2    api::{
3        ModuleN, SvpApplyDftToDftAssign, VecZnxAddScalarAssignBackend, VecZnxBigAddAssign, VecZnxBigBytesOf,
4        VecZnxBigFromSmallBackend, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxDftApply, VecZnxDftBytesOf,
5        VecZnxIdftApplyTmpA, VecZnxSubAssignBackend,
6    },
7    layouts::{
8        Backend, HostBackend, HostDataMut, HostDataRef, Module, ScalarZnx, ScalarZnxToBackendRef, ScratchArena, Stats, ZnxZero,
9    },
10};
11
12use crate::noise::glwe::glwe_noise_backend_inner;
13use crate::{
14    GLWENormalize,
15    api::{GGLWENoise, GLWENoise},
16    decryption::GLWEDecrypt,
17    layouts::{
18        GGLWE, GGLWEInfos, GGLWEToBackendRef, GLWEInfos, GLWEToBackendMut, GLWEToBackendRef, GLWEViewRef,
19        prepared::GLWESecretPreparedToBackendRef,
20    },
21};
22use crate::{ScratchArenaTakeCore, layouts::GLWEPlaintext};
23
24impl<D: HostDataRef> GGLWE<D> {
25    pub fn noise<M, S, BE>(
26        &self,
27        module: &M,
28        row: usize,
29        col: usize,
30        pt_want: &ScalarZnx<&[u8]>,
31        sk_prepared: &S,
32        scratch: &mut ScratchArena<'_, BE>,
33    ) -> Stats
34    where
35        GGLWE<D>: GGLWEToBackendRef<BE>,
36        S: GLWESecretPreparedToBackendRef<BE> + GLWEInfos,
37        M: GGLWENoise<BE>,
38        BE: HostBackend,
39        for<'a> BE::BufRef<'a>: HostDataRef,
40        for<'a> BE::BufMut<'a>: HostDataMut,
41    {
42        module.gglwe_noise(self, row, col, pt_want, sk_prepared, scratch)
43    }
44}
45
46impl<BE: Backend + HostBackend> GGLWENoise<BE> for Module<BE>
47where
48    Module<BE>:
49        VecZnxAddScalarAssignBackend<BE> + VecZnxSubAssignBackend<BE> + GLWENoise<BE> + GLWEDecrypt<BE> + GLWENormalize<BE>,
50    Module<BE>: ModuleN
51        + VecZnxDftBytesOf
52        + VecZnxBigBytesOf
53        + VecZnxBigFromSmallBackend<BE>
54        + VecZnxDftApply<BE>
55        + SvpApplyDftToDftAssign<BE>
56        + VecZnxIdftApplyTmpA<BE>
57        + VecZnxBigAddAssign<BE>
58        + VecZnxBigNormalize<BE>
59        + VecZnxBigNormalizeTmpBytes,
60    for<'a> BE::BufRef<'a>: HostDataRef,
61    for<'a> BE::BufMut<'a>: HostDataMut,
62{
63    fn gglwe_noise_tmp_bytes<A>(&self, infos: &A) -> usize
64    where
65        A: GGLWEInfos,
66    {
67        let lvl_0: usize = GLWEPlaintext::<Vec<u8>>::bytes_of_from_infos(infos);
68        let lvl_1: usize = self.glwe_noise_tmp_bytes(infos);
69
70        lvl_0 + lvl_1
71    }
72
73    fn gglwe_noise<R, S>(
74        &self,
75        res: &R,
76        res_row: usize,
77        res_col: usize,
78        pt_want: &ScalarZnx<&[u8]>,
79        sk_prepared: &S,
80        scratch: &mut ScratchArena<'_, BE>,
81    ) -> Stats
82    where
83        R: GGLWEToBackendRef<BE> + GGLWEInfos,
84        S: GLWESecretPreparedToBackendRef<BE> + GLWEInfos,
85        BE: HostBackend,
86        for<'a> BE::BufRef<'a>: HostDataRef,
87        for<'a> BE::BufMut<'a>: HostDataMut,
88    {
89        assert!(
90            scratch.available() >= self.gglwe_noise_tmp_bytes(res),
91            "scratch.available(): {} < GGLWENoise::gglwe_noise_tmp_bytes: {}",
92            scratch.available(),
93            self.gglwe_noise_tmp_bytes(res)
94        );
95
96        let res_backend = res.to_backend_ref();
97        let sk_backend = sk_prepared.to_backend_ref();
98        let dsize: usize = res_backend.dsize().into();
99        let (mut pt, mut scratch_1) = scratch.borrow().take_glwe_plaintext_scratch(&res_backend);
100        pt.data_mut().zero();
101        let pt_want_backend: ScalarZnx<BE::OwnedBuf> =
102            ScalarZnx::from_data(BE::from_host_bytes(pt_want.data), pt_want.n(), pt_want.cols());
103        {
104            let mut pt_backend = pt.to_backend_mut();
105            self.vec_znx_add_scalar_assign_backend(
106                &mut pt_backend.data,
107                0,
108                (dsize - 1) + res_row * dsize,
109                &<ScalarZnx<BE::OwnedBuf> as ScalarZnxToBackendRef<BE>>::to_backend_ref(&pt_want_backend),
110                res_col,
111            );
112        }
113        let res_at_backend: GLWEViewRef<'_, BE> = res_backend.at_view(res_row, res_col);
114        let pt_backend = pt.to_backend_ref();
115        glwe_noise_backend_inner(self, &res_at_backend, &pt_backend, &sk_backend, &mut scratch_1)
116    }
117}