arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/glwe/decryption.rs
core/src/glwe/decryption.rsRaw
 1use backend::{FFT64, Module, ScalarZnxDftOps, Scratch, VecZnxBigOps, VecZnxDftOps, ZnxZero};
 2
 3use crate::{GLWECiphertext, GLWEPlaintext, GLWESecret, Infos};
 4
 5impl<DataSelf: AsRef<[u8]>> GLWECiphertext<DataSelf> {
 6    pub fn clone(&self) -> GLWECiphertext<Vec<u8>> {
 7        GLWECiphertext {
 8            data: self.data.clone(),
 9            basek: self.basek(),
10            k: self.k(),
11        }
12    }
13
14    pub fn decrypt<DataPt: AsMut<[u8]> + AsRef<[u8]>, DataSk: AsRef<[u8]>>(
15        &self,
16        module: &Module<FFT64>,
17        pt: &mut GLWEPlaintext<DataPt>,
18        sk: &GLWESecret<DataSk, FFT64>,
19        scratch: &mut Scratch,
20    ) {
21        #[cfg(debug_assertions)]
22        {
23            assert_eq!(self.rank(), sk.rank());
24            assert_eq!(self.n(), module.n());
25            assert_eq!(pt.n(), module.n());
26            assert_eq!(sk.n(), module.n());
27        }
28
29        let cols: usize = self.rank() + 1;
30
31        let (mut c0_big, scratch_1) = scratch.tmp_vec_znx_big(module, 1, self.size()); // TODO optimize size when pt << ct
32        c0_big.zero();
33
34        {
35            (1..cols).for_each(|i| {
36                // ci_dft = DFT(a[i]) * DFT(s[i])
37                let (mut ci_dft, _) = scratch_1.tmp_vec_znx_dft(module, 1, self.size()); // TODO optimize size when pt << ct
38                module.vec_znx_dft(1, 0, &mut ci_dft, 0, &self.data, i);
39                module.svp_apply_inplace(&mut ci_dft, 0, &sk.data_fourier, i - 1);
40                let ci_big = module.vec_znx_idft_consume(ci_dft);
41
42                // c0_big += a[i] * s[i]
43                module.vec_znx_big_add_inplace(&mut c0_big, 0, &ci_big, 0);
44            });
45        }
46
47        // c0_big = (a * s) + (-a * s + m + e) = BIG(m + e)
48        module.vec_znx_big_add_small_inplace(&mut c0_big, 0, &self.data, 0);
49
50        // pt = norm(BIG(m + e))
51        module.vec_znx_big_normalize(self.basek(), &mut pt.data, 0, &mut c0_big, 0, scratch_1);
52
53        pt.basek = self.basek();
54        pt.k = pt.k().min(self.k());
55    }
56}