poulpy/poulpy-core/src/encryption/lwe_ksk.rs
poulpy-core/src/encryption/lwe_ksk.rsRaw
1use poulpy_hal::{
2 api::{
3 SvpApplyDftToDftInplace, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace,
4 VecZnxAutomorphismInplace, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform,
5 VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace,
6 VecZnxSwitchRing,
7 },
8 layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxView, ZnxViewMut},
9 source::Source,
10};
11
12use crate::layouts::{
13 GGLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, LWESecret, LWESwitchingKey, Rank, RingDegree,
14 prepared::GLWESecretPrepared,
15};
16
17impl LWESwitchingKey<Vec<u8>> {
18 pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
19 where
20 A: GGLWEInfos,
21 Module<B>: SvpPPolBytesOf + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes,
22 {
23 debug_assert_eq!(
24 infos.dsize().0,
25 1,
26 "dsize > 1 is not supported for LWESwitchingKey"
27 );
28 debug_assert_eq!(
29 infos.rank_in().0,
30 1,
31 "rank_in > 1 is not supported for LWESwitchingKey"
32 );
33 debug_assert_eq!(
34 infos.rank_out().0,
35 1,
36 "rank_out > 1 is not supported for LWESwitchingKey"
37 );
38 GLWESecret::bytes_of(RingDegree(module.n() as u32), Rank(1))
39 + GLWESecretPrepared::bytes_of(module, Rank(1))
40 + GLWESwitchingKey::encrypt_sk_tmp_bytes(module, infos)
41 }
42}
43
44impl<D: DataMut> LWESwitchingKey<D> {
45 #[allow(clippy::too_many_arguments)]
46 pub fn encrypt_sk<DIn, DOut, B: Backend>(
47 &mut self,
48 module: &Module<B>,
49 sk_lwe_in: &LWESecret<DIn>,
50 sk_lwe_out: &LWESecret<DOut>,
51 source_xa: &mut Source,
52 source_xe: &mut Source,
53 scratch: &mut Scratch<B>,
54 ) where
55 DIn: DataRef,
56 DOut: DataRef,
57 Module<B>: VecZnxAutomorphismInplace<B>
58 + VecZnxAddScalarInplace
59 + VecZnxDftBytesOf
60 + VecZnxBigNormalize<B>
61 + VecZnxDftApply<B>
62 + SvpApplyDftToDftInplace<B>
63 + VecZnxIdftApplyConsume<B>
64 + VecZnxNormalizeTmpBytes
65 + VecZnxFillUniform
66 + VecZnxSubInplace
67 + VecZnxAddInplace
68 + VecZnxNormalizeInplace<B>
69 + VecZnxAddNormal
70 + VecZnxNormalize<B>
71 + VecZnxSub
72 + SvpPrepare<B>
73 + VecZnxSwitchRing
74 + SvpPPolBytesOf,
75 Scratch<B>:,
76 {
77 #[cfg(debug_assertions)]
78 {
79 assert!(sk_lwe_in.n().0 <= self.n().0);
80 assert!(sk_lwe_out.n().0 <= self.n().0);
81 assert!(self.n().0 <= module.n() as u32);
82 }
83
84 let (mut sk_in_glwe, scratch_1) = scratch.take_glwe_secret(self.n(), Rank(1));
85 let (mut sk_out_glwe, scratch_2) = scratch_1.take_glwe_secret(self.n(), Rank(1));
86
87 sk_out_glwe.data.at_mut(0, 0)[..sk_lwe_out.n().into()].copy_from_slice(sk_lwe_out.data.at(0, 0));
88 sk_out_glwe.data.at_mut(0, 0)[sk_lwe_out.n().into()..].fill(0);
89 module.vec_znx_automorphism_inplace(-1, &mut sk_out_glwe.data.as_vec_znx_mut(), 0, scratch_2);
90
91 sk_in_glwe.data.at_mut(0, 0)[..sk_lwe_in.n().into()].copy_from_slice(sk_lwe_in.data.at(0, 0));
92 sk_in_glwe.data.at_mut(0, 0)[sk_lwe_in.n().into()..].fill(0);
93 module.vec_znx_automorphism_inplace(-1, &mut sk_in_glwe.data.as_vec_znx_mut(), 0, scratch_2);
94
95 self.0.encrypt_sk(
96 module,
97 &sk_in_glwe,
98 &sk_out_glwe,
99 source_xa,
100 source_xe,
101 scratch_2,
102 );
103 }
104}