poulpy/poulpy-core/src/encryption/gglwe_ksk.rs
poulpy-core/src/encryption/gglwe_ksk.rsRaw
1use poulpy_hal::{
2 api::{
3 ModuleN, ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal,
4 VecZnxAddScalarInplace, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, VecZnxIdftApplyConsume,
5 VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
6 ScratchTakeBasic,
7 },
8 layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, Scratch},
9 source::Source,
10};
11
12use crate::{
13 ScratchTakeCore,
14 layouts::{
15 GGLWE, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, GLWESwitchingKeyToMut, LWEInfos, prepared::GLWESecretPrepared,
16 },
17 encryption::gglwe_ct::GGLWEEncryptSk,
18};
19
20impl GLWESwitchingKey<Vec<u8>> {
21 pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
22 where
23 A: GGLWEInfos,
24 M: GLWESwitchingKeyEncryptSk<BE>,
25 {
26 module.glwe_switching_key_encrypt_sk_tmp_bytes(infos)
27 }
28
29 pub fn encrypt_pk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
30 where
31 A: GGLWEInfos,
32 M: GLWESwitchingKeyEncryptPk<BE>,
33 {
34 module.glwe_switching_key_encrypt_pk_tmp_bytes(infos)
35 }
36}
37
38impl<DataSelf: DataMut> GLWESwitchingKey<DataSelf> {
39
40 pub fn encrypt_sk<M, DataSkIn: DataRef, DataSkOut: DataRef, BE: Backend>(
41 &mut self,
42 module: &M,
43 sk_in: &GLWESecret<DataSkIn>,
44 sk_out: &GLWESecret<DataSkOut>,
45 source_xa: &mut Source,
46 source_xe: &mut Source,
47 scratch: &mut Scratch<BE>,
48 ) where
49 M: GLWESwitchingKeyEncryptSk<BE>,
50 Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
51 {
52 module.glwe_switching_key_encrypt_sk(self, sk_in, sk_out, source_xa, source_xe, scratch);
53 }
54
55
56 // #[allow(clippy::too_many_arguments)]
57 // pub fn encrypt_sk<DataSkIn: DataRef, DataSkOut: DataRef, B: Backend>(
58 // &mut self,
59 // module: &Module<B>,
60 // sk_in: &GLWESecret<DataSkIn>,
61 // sk_out: &GLWESecret<DataSkOut>,
62 // source_xa: &mut Source,
63 // source_xe: &mut Source,
64 // scratch: &mut Scratch<B>,
65 // ) where
66 // Module<B>: ModuleN
67 // + VecZnxAddScalarInplace
68 // + VecZnxDftBytesOf
69 // + VecZnxBigNormalize<B>
70 // + VecZnxDftApply<B>
71 // + SvpApplyDftToDftInplace<B>
72 // + VecZnxIdftApplyConsume<B>
73 // + VecZnxNormalizeTmpBytes
74 // + VecZnxFillUniform
75 // + VecZnxSubInplace
76 // + VecZnxAddInplace
77 // + VecZnxNormalizeInplace<B>
78 // + VecZnxAddNormal
79 // + VecZnxNormalize<B>
80 // + VecZnxSub
81 // + SvpPrepare<B>
82 // + VecZnxSwitchRing
83 // + SvpPPolBytesOf
84 // + SvpPPolAlloc<B>,
85 // Scratch<B>: ScratchAvailable + ScratchTakeBasic + ScratchTakeCore<B>,
86 // {
87 // #[cfg(debug_assertions)]
88 // {
89 // assert!(sk_in.n().0 <= module.n() as u32);
90 // assert!(sk_out.n().0 <= module.n() as u32);
91 // assert!(
92 // scratch.available() >= GLWESwitchingKey::encrypt_sk_tmp_bytes(module, self),
93 // "scratch.available()={} < GLWESwitchingKey::encrypt_sk_tmp_bytes={}",
94 // scratch.available(),
95 // GLWESwitchingKey::encrypt_sk_tmp_bytes(module, self)
96 // )
97 // }
98
99 // // let n: usize = sk_in.n().max(sk_out.n()).into();
100
101 // let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(module, sk_in.rank().into());
102 // (0..sk_in.rank().into()).for_each(|i| {
103 // module.vec_znx_switch_ring(
104 // &mut sk_in_tmp.as_vec_znx_mut(),
105 // i,
106 // &sk_in.data.as_vec_znx(),
107 // i,
108 // );
109 // });
110
111 // let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(module, sk_out.rank());
112 // {
113 // let (mut tmp, _) = scratch_2.take_scalar_znx(module, 1);
114 // (0..sk_out.rank().into()).for_each(|i| {
115 // module.vec_znx_switch_ring(&mut tmp.as_vec_znx_mut(), 0, &sk_out.data.as_vec_znx(), i);
116 // module.svp_prepare(&mut sk_out_tmp.data, i, &tmp, 0);
117 // });
118 // }
119
120 // self.key.encrypt_sk(
121 // module,
122 // &sk_in_tmp,
123 // &sk_out_tmp,
124 // source_xa,
125 // source_xe,
126 // scratch_2,
127 // );
128 // self.sk_in_n = sk_in.n().into();
129 // self.sk_out_n = sk_out.n().into();
130 // }
131}
132
133
134pub trait GLWESwitchingKeyEncryptSk<BE: Backend>
135where
136 Self: Sized
137 + ModuleN
138 + SvpPPolBytesOf
139 + VecZnxDftBytesOf
140 + VecZnxNormalizeTmpBytes
141 + SvpPPolAlloc<BE>
142 + GGLWEEncryptSk<BE>,
143{
144 fn glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
145 where
146 A: GGLWEInfos;
147
148 fn glwe_switching_key_encrypt_sk<R, DataSkIn, DataSkOut>(
149 &self,
150 res: &mut R,
151 sk_in: &GLWESecret<DataSkIn>,
152 sk_out: &GLWESecret<DataSkOut>,
153 source_xa: &mut Source,
154 source_xe: &mut Source,
155 scratch: &mut Scratch<BE>,
156 )
157 where
158 R: GLWESwitchingKeyToMut,
159 DataSkIn: DataRef,
160 DataSkOut: DataRef,
161 Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>;
162
163}
164
165impl<BE: Backend> GLWESwitchingKeyEncryptSk<BE> for Module<BE> where
166 Self: ModuleN
167 + SvpPPolBytesOf
168 + VecZnxDftBytesOf
169 + VecZnxNormalizeTmpBytes
170 + SvpPPolAlloc<BE>
171 + GGLWEEncryptSk<BE>
172 + VecZnxSwitchRing
173 + SvpPrepare<BE>
174 + VecZnxIdftApplyConsume<BE>
175 + VecZnxNormalize<BE>
176 + VecZnxNormalizeInplace<BE>
177 + VecZnxAddInplace
178 + VecZnxAddNormal
179 + VecZnxSub
180{
181
182 fn glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
183 where
184 A: GGLWEInfos,
185 {
186 (GGLWE::encrypt_sk_tmp_bytes(self, infos) | ScalarZnx::bytes_of(self.n(), 1))
187 + ScalarZnx::bytes_of(self.n(), infos.rank_in().into())
188 + GLWESecretPrepared::bytes_of_from_infos(self, &infos.glwe_layout())
189 }
190
191 fn glwe_switching_key_encrypt_sk<R, DataSkIn, DataSkOut>(
192 &self,
193 res: &mut R,
194 sk_in: &GLWESecret<DataSkIn>,
195 sk_out: &GLWESecret<DataSkOut>,
196 source_xa: &mut Source,
197 source_xe: &mut Source,
198 scratch: &mut Scratch<BE>,
199 )
200 where
201 R: GLWESwitchingKeyToMut,
202 DataSkIn: DataRef,
203 DataSkOut: DataRef,
204 Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
205 {
206
207 let res: &mut GLWESwitchingKey<&mut [u8]> = &mut res.to_mut();
208 let sk_in: &GLWESecret<&[u8]> = &sk_in.to_ref();
209 let sk_out: &GLWESecret<&[u8]> = &sk_out.to_ref();
210
211 #[cfg(debug_assertions)]
212 {
213 assert!(sk_in.n().0 <= self.n() as u32);
214 assert!(sk_out.n().0 <= self.n() as u32);
215 assert!(
216 scratch.available() >= GLWESwitchingKey::encrypt_sk_tmp_bytes(self, res),
217 "scratch.available()={} < GLWESwitchingKey::encrypt_sk_tmp_bytes={}",
218 scratch.available(),
219 GLWESwitchingKey::encrypt_sk_tmp_bytes(self, res)
220 )
221 }
222
223 // let n: usize = sk_in.n().max(sk_out.n()).into();
224
225 let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(self, sk_in.rank().into());
226 (0..sk_in.rank().into()).for_each(|i| {
227 self.vec_znx_switch_ring(
228 &mut sk_in_tmp.as_vec_znx_mut(),
229 i,
230 &sk_in.data.as_vec_znx(),
231 i,
232 );
233 });
234
235 let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(self, sk_out.rank());
236 {
237 let (mut tmp, _) = scratch_2.take_scalar_znx(self, 1);
238 (0..sk_out.rank().into()).for_each(|i| {
239 self.vec_znx_switch_ring(&mut tmp.as_vec_znx_mut(), 0, &sk_out.data.as_vec_znx(), i);
240 self.svp_prepare(&mut sk_out_tmp.data, i, &tmp, 0);
241 });
242 }
243
244 res.key.encrypt_sk(
245 self,
246 &sk_in_tmp,
247 &sk_out_tmp,
248 source_xa,
249 source_xe,
250 scratch_2,
251 );
252 res.sk_in_n = sk_in.n().into();
253 res.sk_out_n = sk_out.n().into();
254 }
255
256}
257
258pub trait GLWESwitchingKeyEncryptPk<BE: Backend>
259where
260 Self: Sized
261 + ModuleN
262 + SvpPPolBytesOf
263 + VecZnxDftBytesOf
264 + VecZnxNormalizeTmpBytes
265 + SvpPPolAlloc<BE>
266 + GGLWEEncryptSk<BE>,
267{
268
269 fn glwe_switching_key_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize
270 where
271 A: GGLWEInfos;
272}
273
274impl<BE: Backend> GLWESwitchingKeyEncryptPk<BE> for Module<BE> where
275 Self: ModuleN
276 + SvpPPolBytesOf
277 + VecZnxDftBytesOf
278 + VecZnxNormalizeTmpBytes
279 + SvpPPolAlloc<BE>
280 + GGLWEEncryptSk<BE>,
281{
282
283 fn glwe_switching_key_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize
284 where
285 A: GGLWEInfos,
286 {
287 GGLWE::encrypt_pk_tmp_bytes(self, infos)
288 }
289}