arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/conversion/lwe_to_glwe.rs
core/src/conversion/lwe_to_glwe.rsRaw
 1use backend::hal::{
 2    api::{ScratchAvailable, TakeVecZnx, TakeVecZnxDft, ZnxView, ZnxViewMut, ZnxZero},
 3    layouts::{Backend, DataMut, DataRef, Module, Scratch},
 4};
 5
 6use crate::{
 7    TakeGLWECt,
 8    layouts::{GLWECiphertext, Infos, LWECiphertext, prepared::LWEToGLWESwitchingKeyPrepared},
 9};
10
11use crate::trait_families::GLWEKeyswitchFamily;
12
13impl GLWECiphertext<Vec<u8>> {
14    pub fn from_lwe_scratch_space<B: Backend>(
15        module: &Module<B>,
16        n: usize,
17        basek: usize,
18        k_lwe: usize,
19        k_glwe: usize,
20        k_ksk: usize,
21        rank: usize,
22    ) -> usize
23    where
24        Module<B>: GLWEKeyswitchFamily<B>,
25    {
26        GLWECiphertext::keyswitch_scratch_space(module, n, basek, k_glwe, k_lwe, k_ksk, 1, 1, rank)
27            + GLWECiphertext::bytes_of(n, basek, k_lwe, 1)
28    }
29}
30
31impl<D: DataMut> GLWECiphertext<D> {
32    pub fn from_lwe<DLwe, DKsk, B: Backend>(
33        &mut self,
34        module: &Module<B>,
35        lwe: &LWECiphertext<DLwe>,
36        ksk: &LWEToGLWESwitchingKeyPrepared<DKsk, B>,
37        scratch: &mut Scratch<B>,
38    ) where
39        DLwe: DataRef,
40        DKsk: DataRef,
41        Module<B>: GLWEKeyswitchFamily<B>,
42        Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx,
43    {
44        #[cfg(debug_assertions)]
45        {
46            assert!(lwe.n() <= self.n());
47            assert_eq!(self.basek(), self.basek());
48        }
49
50        let (mut glwe, scratch1) = scratch.take_glwe_ct(ksk.n(), lwe.basek(), lwe.k(), 1);
51        glwe.data.zero();
52
53        let n_lwe: usize = lwe.n();
54
55        (0..lwe.size()).for_each(|i| {
56            let data_lwe: &[i64] = lwe.data.at(0, i);
57            glwe.data.at_mut(0, i)[0] = data_lwe[0];
58            glwe.data.at_mut(1, i)[..n_lwe].copy_from_slice(&data_lwe[1..]);
59        });
60
61        self.keyswitch(module, &glwe, &ksk.0, scratch1);
62    }
63}