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