poulpy_core/conversion/
lwe_to_glwe.rs1use poulpy_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::LWEToGLWESwitchingKeyPrepared},
13};
14
15impl GLWECiphertext<Vec<u8>> {
16 pub fn from_lwe_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::keyswitch_scratch_space(module, n, basek, k_glwe, k_lwe, k_ksk, 1, 1, rank)
29 + GLWECiphertext::bytes_of(n, basek, k_lwe, 1)
30 }
31}
32
33impl<D: DataMut> GLWECiphertext<D> {
34 pub fn from_lwe<DLwe, DKsk, B: Backend>(
35 &mut self,
36 module: &Module<B>,
37 lwe: &LWECiphertext<DLwe>,
38 ksk: &LWEToGLWESwitchingKeyPrepared<DKsk, B>,
39 scratch: &mut Scratch<B>,
40 ) where
41 DLwe: DataRef,
42 DKsk: DataRef,
43 Module<B>: VecZnxDftAllocBytes
44 + VmpApplyTmpBytes
45 + VecZnxBigNormalizeTmpBytes
46 + VmpApply<B>
47 + VmpApplyAdd<B>
48 + VecZnxDftFromVecZnx<B>
49 + VecZnxDftToVecZnxBigConsume<B>
50 + VecZnxBigAddSmallInplace<B>
51 + VecZnxBigNormalize<B>,
52 Scratch<B>: ScratchAvailable + TakeVecZnxDft<B> + TakeGLWECt,
53 {
54 #[cfg(debug_assertions)]
55 {
56 assert!(lwe.n() <= self.n());
57 assert_eq!(self.basek(), self.basek());
58 }
59
60 let (mut glwe, scratch1) = scratch.take_glwe_ct(ksk.n(), lwe.basek(), lwe.k(), 1);
61 glwe.data.zero();
62
63 let n_lwe: usize = lwe.n();
64
65 (0..lwe.size()).for_each(|i| {
66 let data_lwe: &[i64] = lwe.data.at(0, i);
67 glwe.data.at_mut(0, i)[0] = data_lwe[0];
68 glwe.data.at_mut(1, i)[..n_lwe].copy_from_slice(&data_lwe[1..]);
69 });
70
71 self.keyswitch(module, &glwe, &ksk.0, scratch1);
72 }
73}