arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/conversion/glwe_to_lwe.rs
core/src/conversion/glwe_to_lwe.rsRaw
 1use backend::hal::{
 2    api::{
 3        ScratchAvailable, TakeVecZnxDft, VecZnxBigAddSmallInplace, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes,
 4        VecZnxDftAllocBytes, VecZnxDftFromVecZnx, VecZnxDftToVecZnxBigConsume, VmpApply, VmpApplyAdd, VmpApplyTmpBytes, ZnxView,
 5        ZnxViewMut, ZnxZero,
 6    },
 7    layouts::{Backend, DataMut, DataRef, Module, Scratch},
 8};
 9
10use crate::{
11    TakeGLWECt,
12    layouts::{GLWECiphertext, Infos, LWECiphertext, prepared::GLWEToLWESwitchingKeyPrepared},
13};
14
15impl LWECiphertext<Vec<u8>> {
16    pub fn from_glwe_scratch_space<B: Backend>(
17        module: &Module<B>,
18        n: usize,
19        basek: usize,
20        k_lwe: usize,
21        k_glwe: usize,
22        k_ksk: usize,
23        rank: usize,
24    ) -> usize
25    where
26        Module<B>: VecZnxDftAllocBytes + VmpApplyTmpBytes + VecZnxBigNormalizeTmpBytes,
27    {
28        GLWECiphertext::bytes_of(n, basek, k_lwe, 1)
29            + GLWECiphertext::keyswitch_scratch_space(module, n, basek, k_lwe, k_glwe, k_ksk, 1, rank, 1)
30    }
31}
32
33impl<DLwe: DataMut> LWECiphertext<DLwe> {
34    pub fn sample_extract<DGlwe: DataRef>(&mut self, a: &GLWECiphertext<DGlwe>) {
35        #[cfg(debug_assertions)]
36        {
37            assert!(self.n() <= a.n());
38        }
39
40        let min_size: usize = self.size().min(a.size());
41        let n: usize = self.n();
42
43        self.data.zero();
44        (0..min_size).for_each(|i| {
45            let data_lwe: &mut [i64] = self.data.at_mut(0, i);
46            data_lwe[0] = a.data.at(0, i)[0];
47            data_lwe[1..].copy_from_slice(&a.data.at(1, i)[..n]);
48        });
49    }
50
51    pub fn from_glwe<DGlwe, DKs, B: Backend>(
52        &mut self,
53        module: &Module<B>,
54        a: &GLWECiphertext<DGlwe>,
55        ks: &GLWEToLWESwitchingKeyPrepared<DKs, B>,
56        scratch: &mut Scratch<B>,
57    ) where
58        DGlwe: DataRef,
59        DKs: DataRef,
60        Module<B>: VecZnxDftAllocBytes
61            + VmpApplyTmpBytes
62            + VecZnxBigNormalizeTmpBytes
63            + VmpApply<B>
64            + VmpApplyAdd<B>
65            + VecZnxDftFromVecZnx<B>
66            + VecZnxDftToVecZnxBigConsume<B>
67            + VecZnxBigAddSmallInplace<B>
68            + VecZnxBigNormalize<B>,
69        Scratch<B>: ScratchAvailable + TakeVecZnxDft<B> + TakeGLWECt,
70    {
71        #[cfg(debug_assertions)]
72        {
73            assert_eq!(self.basek(), a.basek());
74            assert_eq!(a.n(), ks.n());
75        }
76        let (mut tmp_glwe, scratch1) = scratch.take_glwe_ct(a.n(), a.basek(), self.k(), 1);
77        tmp_glwe.keyswitch(module, a, &ks.0, scratch1);
78        self.sample_extract(&tmp_glwe);
79    }
80}