poulpy/poulpy-core/src/encryption/lwe_ksk.rs
poulpy-core/src/encryption/lwe_ksk.rsRaw
1use poulpy_hal::{
2 api::{
3 ModuleN, SvpApplyDftToDftInplace, SvpPPolAlloc, 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::{
13 layouts::{
14 GLWESecretAlloc,
15 GGLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, LWESecret, LWESwitchingKey, Rank,
16 prepared::{GLWESecretPrepared, GLWESecretPreparedAlloc},
17 },
18 ScratchTakeCore,
19};
20
21impl LWESwitchingKey<Vec<u8>> {
22 pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
23 where
24 A: GGLWEInfos,
25 M: LWESwitchingKeyEncrypt<BE>,
26 {
27 module.lwe_switching_key_encrypt_sk_tmp_bytes(infos)
28 }
29
30 // pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
31 // where
32 // A: GGLWEInfos,
33 // Module<B>: ModuleN + SvpPPolBytesOf + SvpPPolAlloc<B> + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes,
34 // {
35 // debug_assert_eq!(
36 // infos.dsize().0,
37 // 1,
38 // "dsize > 1 is not supported for LWESwitchingKey"
39 // );
40 // debug_assert_eq!(
41 // infos.rank_in().0,
42 // 1,
43 // "rank_in > 1 is not supported for LWESwitchingKey"
44 // );
45 // debug_assert_eq!(
46 // infos.rank_out().0,
47 // 1,
48 // "rank_out > 1 is not supported for LWESwitchingKey"
49 // );
50 // GLWESecret::bytes_of(module, Rank(1))
51 // + GLWESecretPrepared::bytes_of(module, Rank(1))
52 // + GLWESwitchingKey::encrypt_sk_tmp_bytes(module, infos)
53 // }
54}
55
56impl<D: DataMut> LWESwitchingKey<D> {
57 #[allow(clippy::too_many_arguments)]
58 pub fn encrypt_sk<DIn, DOut, B: Backend>(
59 &mut self,
60 module: &Module<B>,
61 sk_lwe_in: &LWESecret<DIn>,
62 sk_lwe_out: &LWESecret<DOut>,
63 source_xa: &mut Source,
64 source_xe: &mut Source,
65 scratch: &mut Scratch<B>,
66 ) where
67 DIn: DataRef,
68 DOut: DataRef,
69 Module<B>: ModuleN
70 + VecZnxAutomorphismInplace<B>
71 + VecZnxAddScalarInplace
72 + VecZnxDftBytesOf
73 + VecZnxBigNormalize<B>
74 + VecZnxDftApply<B>
75 + SvpApplyDftToDftInplace<B>
76 + VecZnxIdftApplyConsume<B>
77 + VecZnxNormalizeTmpBytes
78 + VecZnxFillUniform
79 + VecZnxSubInplace
80 + VecZnxAddInplace
81 + VecZnxNormalizeInplace<B>
82 + VecZnxAddNormal
83 + VecZnxNormalize<B>
84 + VecZnxSub
85 + SvpPrepare<B>
86 + VecZnxSwitchRing
87 + SvpPPolBytesOf
88 + SvpPPolAlloc<B>,
89 Scratch<B>: ScratchTakeCore<B>,
90 {
91 #[cfg(debug_assertions)]
92 {
93 assert!(sk_lwe_in.n().0 <= self.n().0);
94 assert!(sk_lwe_out.n().0 <= self.n().0);
95 assert!(self.n().0 <= module.n() as u32);
96 }
97
98 let (mut sk_in_glwe, scratch_1) = scratch.take_glwe_secret(module, Rank(1));
99 let (mut sk_out_glwe, scratch_2) = scratch_1.take_glwe_secret(module, Rank(1));
100
101 sk_out_glwe.data.at_mut(0, 0)[..sk_lwe_out.n().into()].copy_from_slice(sk_lwe_out.data.at(0, 0));
102 sk_out_glwe.data.at_mut(0, 0)[sk_lwe_out.n().into()..].fill(0);
103 module.vec_znx_automorphism_inplace(-1, &mut sk_out_glwe.data.as_vec_znx_mut(), 0, scratch_2);
104
105 sk_in_glwe.data.at_mut(0, 0)[..sk_lwe_in.n().into()].copy_from_slice(sk_lwe_in.data.at(0, 0));
106 sk_in_glwe.data.at_mut(0, 0)[sk_lwe_in.n().into()..].fill(0);
107 module.vec_znx_automorphism_inplace(-1, &mut sk_in_glwe.data.as_vec_znx_mut(), 0, scratch_2);
108
109 self.0.encrypt_sk(
110 module,
111 &sk_in_glwe,
112 &sk_out_glwe,
113 source_xa,
114 source_xe,
115 scratch_2,
116 );
117 }
118}
119
120pub trait LWESwitchingKeyEncrypt<BE: Backend>
121where
122 Self: Sized
123 + ModuleN
124 + SvpPPolBytesOf
125 + SvpPPolAlloc<BE>
126 + VecZnxNormalizeTmpBytes
127 + VecZnxDftBytesOf
128 + VecZnxAutomorphismInplace<BE>
129 + VecZnxAddScalarInplace
130 + VecZnxBigNormalize<BE>
131 + VecZnxDftApply<BE>
132 + SvpApplyDftToDftInplace<BE>
133 + VecZnxIdftApplyConsume<BE>
134 + VecZnxFillUniform
135 + VecZnxSubInplace
136 + VecZnxAddInplace
137 + VecZnxNormalizeInplace<BE>
138 + VecZnxAddNormal
139 + VecZnxNormalize<BE>
140 + VecZnxSub
141 + SvpPrepare<BE>
142 + VecZnxSwitchRing
143 + GLWESecretAlloc
144 + GLWESecretPreparedAlloc<BE>
145{
146 fn lwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
147 where
148 A: GGLWEInfos;
149}
150
151impl<BE:Backend> LWESwitchingKeyEncrypt<BE> for Module<BE> where
152 Self: ModuleN
153 + SvpPPolBytesOf
154 + SvpPPolAlloc<BE>
155 + VecZnxNormalizeTmpBytes
156 + VecZnxDftBytesOf
157 + VecZnxAutomorphismInplace<BE>
158 + VecZnxAddScalarInplace
159 + VecZnxBigNormalize<BE>
160 + VecZnxDftApply<BE>
161 + SvpApplyDftToDftInplace<BE>
162 + VecZnxIdftApplyConsume<BE>
163 + VecZnxFillUniform
164 + VecZnxSubInplace
165 + VecZnxAddInplace
166 + VecZnxNormalizeInplace<BE>
167 + VecZnxAddNormal
168 + VecZnxNormalize<BE>
169 + VecZnxSub
170 + SvpPrepare<BE>
171 + VecZnxSwitchRing
172 + GLWESecretAlloc
173 + GLWESecretPreparedAlloc<BE>
174{
175 fn lwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
176 where
177 A: GGLWEInfos
178 {
179 debug_assert_eq!(
180 infos.dsize().0,
181 1,
182 "dsize > 1 is not supported for LWESwitchingKey"
183 );
184 debug_assert_eq!(
185 infos.rank_in().0,
186 1,
187 "rank_in > 1 is not supported for LWESwitchingKey"
188 );
189 debug_assert_eq!(
190 infos.rank_out().0,
191 1,
192 "rank_out > 1 is not supported for LWESwitchingKey"
193 );
194 GLWESecret::bytes_of(self, Rank(1))
195 + GLWESecretPrepared::bytes_of(self, Rank(1))
196 + GLWESwitchingKey::encrypt_sk_tmp_bytes(self, infos)
197 }
198}