poulpy/poulpy-core/src/conversion/glwe_to_lwe.rs
poulpy-core/src/conversion/glwe_to_lwe.rsRaw
1use 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::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}