1use std::collections::HashMap;
2
3use poulpy_hal::layouts::{Backend, Module, ScratchArena};
4
5use crate::{
6 api::{
7 GGSWRotate, GLWEAdd, GLWECopy, GLWEMulConst, GLWEMulPlain, GLWEMulXpMinusOne, GLWENegate, GLWENormalize, GLWEPacking,
8 GLWERotate, GLWEShift, GLWESub, GLWETensoring, GLWETrace, GLWEZero,
9 },
10 default::{glwe_packing::GLWEPackingDefault, glwe_trace::GLWETraceDefault},
11 layouts::{
12 GGLWEInfos, GGSWAtViewMut, GGSWAtViewRef, GGSWInfos, GGSWToBackendMut, GGSWToBackendRef, GLWEAutomorphismKeyHelper,
13 GLWEInfos, GLWEToBackendMut, GLWEToBackendRef, GetGaloisElement,
14 prepared::{GGLWEPreparedToBackendRef, GLWETensorKeyPreparedToBackendRef},
15 },
16 oep::{
17 GGSWRotateImpl, GLWEAddImpl, GLWECopyImpl, GLWEMulConstImpl, GLWEMulPlainImpl, GLWEMulXpMinusOneImpl, GLWENegateImpl,
18 GLWENormalizeImpl, GLWEPackImpl, GLWERotateImpl, GLWEShiftImpl, GLWESubImpl, GLWETensoringImpl, GLWETraceImpl,
19 GLWEZeroImpl,
20 },
21 operations::{
22 GGSWRotateDefault, GLWEAddDefault, GLWECopyDefault, GLWEMulConstDefault, GLWEMulPlainDefault, GLWEMulXpMinusOneDefault,
23 GLWENegateDefault, GLWENormalizeDefault, GLWERotateDefault, GLWEShiftDefault, GLWESubDefault, GLWETensoringDefault,
24 GLWEZeroDefault,
25 },
26};
27
28macro_rules! impl_operations_delegate {
29 ($trait:ty, $impl_trait:path, $default:path, $($body:item),+ $(,)?) => {
30 impl<BE> $trait for Module<BE>
31 where
32 BE: Backend + $impl_trait,
33 Module<BE>: $default,
34 {
35 $($body)+
36 }
37 };
38}
39
40impl_operations_delegate!(
41 GLWEAdd<BE>,
42 GLWEAddImpl<BE>,
43 GLWEAddDefault<BE>,
44 fn glwe_add_into<R, A, B>(&self, res: &mut R, a: &A, b: &B)
45 where
46 R: GLWEToBackendMut<BE>,
47 A: GLWEToBackendRef<BE>,
48 B: GLWEToBackendRef<BE>,
49 {
50 BE::glwe_add_into(self, res, a, b)
51 },
52 fn glwe_add_assign<R, A>(&self, res: &mut R, a: &A)
53 where
54 R: GLWEToBackendMut<BE>,
55 A: GLWEToBackendRef<BE>,
56 {
57 BE::glwe_add_assign(self, res, a)
58 }
59);
60
61impl_operations_delegate!(
62 GLWENegate<BE>,
63 GLWENegateImpl<BE>,
64 GLWENegateDefault<BE>,
65 fn glwe_negate<R, A>(&self, res: &mut R, a: &A)
66 where
67 R: GLWEToBackendMut<BE>,
68 A: GLWEToBackendRef<BE>,
69 {
70 BE::glwe_negate(self, res, a)
71 },
72 fn glwe_negate_assign<R>(&self, res: &mut R)
73 where
74 R: GLWEToBackendMut<BE>,
75 {
76 BE::glwe_negate_assign(self, res)
77 }
78);
79
80impl_operations_delegate!(
81 GLWESub<BE>,
82 GLWESubImpl<BE>,
83 GLWESubDefault<BE>,
84 fn glwe_sub<R, A, B>(&self, res: &mut R, a: &A, b: &B)
85 where
86 R: GLWEToBackendMut<BE>,
87 A: GLWEToBackendRef<BE>,
88 B: GLWEToBackendRef<BE>,
89 {
90 BE::glwe_sub(self, res, a, b)
91 },
92 fn glwe_sub_assign<R, A>(&self, res: &mut R, a: &A)
93 where
94 R: GLWEToBackendMut<BE>,
95 A: GLWEToBackendRef<BE>,
96 {
97 BE::glwe_sub_assign(self, res, a)
98 },
99 fn glwe_sub_negate_assign<R, A>(&self, res: &mut R, a: &A)
100 where
101 R: GLWEToBackendMut<BE>,
102 A: GLWEToBackendRef<BE>,
103 {
104 BE::glwe_sub_negate_assign(self, res, a)
105 }
106);
107
108impl_operations_delegate!(
109 GLWEZero<BE>,
110 GLWEZeroImpl<BE>,
111 GLWEZeroDefault<BE>,
112 fn glwe_zero<R>(&self, res: &mut R)
113 where
114 R: GLWEToBackendMut<BE>,
115 {
116 BE::glwe_zero(self, res)
117 }
118);
119
120impl_operations_delegate!(
121 GLWECopy<BE>,
122 GLWECopyImpl<BE>,
123 GLWECopyDefault<BE>,
124 fn glwe_copy<R, A>(&self, res: &mut R, a: &A)
125 where
126 R: GLWEToBackendMut<BE>,
127 A: GLWEToBackendRef<BE>,
128 {
129 BE::glwe_copy(self, res, a)
130 }
131);
132
133impl_operations_delegate!(
134 GLWEMulConst<BE>,
135 GLWEMulConstImpl<BE>,
136 GLWEMulConstDefault<BE>,
137 fn glwe_mul_const_tmp_bytes<R, A, B>(&self, res: &R, a: &A, b: &B) -> usize
138 where
139 R: GLWEInfos,
140 A: GLWEInfos,
141 B: GLWEInfos,
142 {
143 BE::glwe_mul_const_tmp_bytes(self, res, a, b)
144 },
145 fn glwe_mul_const<R, A, B>(
146 &self,
147 cnv_offset: usize,
148 res: &mut R,
149 a: &A,
150 b: &B,
151 b_coeff: usize,
152 scratch: &mut ScratchArena<'_, BE>,
153 ) where
154 R: GLWEToBackendMut<BE> + GLWEInfos,
155 A: GLWEToBackendRef<BE> + GLWEInfos,
156 B: GLWEToBackendRef<BE> + GLWEInfos,
157 {
158 BE::glwe_mul_const(self, cnv_offset, res, a, b, b_coeff, scratch)
159 },
160 fn glwe_mul_const_assign<R, B>(
161 &self,
162 cnv_offset: usize,
163 res: &mut R,
164 b: &B,
165 b_coeff: usize,
166 scratch: &mut ScratchArena<'_, BE>,
167 ) where
168 R: GLWEToBackendMut<BE> + GLWEInfos,
169 B: GLWEToBackendRef<BE> + GLWEInfos,
170 {
171 BE::glwe_mul_const_assign(self, cnv_offset, res, b, b_coeff, scratch)
172 }
173);
174
175impl_operations_delegate!(
176 GLWEMulPlain<BE>,
177 GLWEMulPlainImpl<BE>,
178 GLWEMulPlainDefault<BE>,
179 fn glwe_mul_plain_tmp_bytes<R, A, B>(&self, res: &R, a: &A, b: &B) -> usize
180 where
181 R: GLWEInfos,
182 A: GLWEInfos,
183 B: GLWEInfos,
184 {
185 BE::glwe_mul_plain_tmp_bytes(self, res, a, b)
186 },
187 fn glwe_mul_plain<R, A, B>(
188 &self,
189 cnv_offset: usize,
190 res: &mut R,
191 a: &A,
192 a_effective_k: usize,
193 b: &B,
194 b_effective_k: usize,
195 scratch: &mut ScratchArena<'_, BE>,
196 ) where
197 R: GLWEToBackendMut<BE> + GLWEInfos,
198 A: GLWEToBackendRef<BE> + GLWEInfos,
199 B: GLWEToBackendRef<BE> + GLWEInfos,
200 {
201 BE::glwe_mul_plain(self, cnv_offset, res, a, a_effective_k, b, b_effective_k, scratch)
202 },
203 fn glwe_mul_plain_assign<R, A>(
204 &self,
205 cnv_offset: usize,
206 res: &mut R,
207 res_effective_k: usize,
208 a: &A,
209 a_effective_k: usize,
210 scratch: &mut ScratchArena<'_, BE>,
211 ) where
212 R: GLWEToBackendMut<BE> + GLWEInfos,
213 A: GLWEToBackendRef<BE> + GLWEInfos,
214 {
215 BE::glwe_mul_plain_assign(self, cnv_offset, res, res_effective_k, a, a_effective_k, scratch)
216 }
217);
218
219impl_operations_delegate!(
220 GLWETensoring<BE>,
221 GLWETensoringImpl<BE>,
222 GLWETensoringDefault<BE>,
223 fn glwe_tensor_apply_tmp_bytes<R, A, B>(&self, res: &R, a: &A, b: &B) -> usize
224 where
225 R: GLWEInfos,
226 A: GLWEInfos,
227 B: GLWEInfos,
228 {
229 BE::glwe_tensor_apply_tmp_bytes(self, res, a, b)
230 },
231 fn glwe_tensor_square_apply_tmp_bytes<R, A>(&self, res: &R, a: &A) -> usize
232 where
233 R: GLWEInfos,
234 A: GLWEInfos,
235 {
236 BE::glwe_tensor_square_apply_tmp_bytes(self, res, a)
237 },
238 fn glwe_tensor_apply<R, A, B>(
239 &self,
240 cnv_offset: usize,
241 res: &mut R,
242 a: &A,
243 a_effective_k: usize,
244 b: &B,
245 b_effective_k: usize,
246 scratch: &mut ScratchArena<'_, BE>,
247 ) where
248 R: GLWEToBackendMut<BE> + GLWEInfos,
249 A: GLWEToBackendRef<BE> + GLWEInfos,
250 B: GLWEToBackendRef<BE> + GLWEInfos,
251 {
252 BE::glwe_tensor_apply(self, cnv_offset, res, a, a_effective_k, b, b_effective_k, scratch)
253 },
254 fn glwe_tensor_square_apply<R, A>(
255 &self,
256 cnv_offset: usize,
257 res: &mut R,
258 a: &A,
259 a_effective_k: usize,
260 scratch: &mut ScratchArena<'_, BE>,
261 ) where
262 R: GLWEToBackendMut<BE> + GLWEInfos,
263 A: GLWEToBackendRef<BE> + GLWEInfos,
264 {
265 BE::glwe_tensor_square_apply(self, cnv_offset, res, a, a_effective_k, scratch)
266 },
267 fn glwe_tensor_relinearize<R, A, T>(&self, res: &mut R, a: &A, tsk: &T, tsk_size: usize, scratch: &mut ScratchArena<'_, BE>)
268 where
269 R: GLWEToBackendMut<BE> + GLWEInfos,
270 A: GLWEToBackendRef<BE> + GLWEInfos,
271 T: GGLWEInfos + GLWETensorKeyPreparedToBackendRef<BE>,
272 {
273 BE::glwe_tensor_relinearize(self, res, a, tsk, tsk_size, scratch)
274 },
275 fn glwe_tensor_relinearize_tmp_bytes<R, A, B>(&self, res: &R, a: &A, tsk: &B) -> usize
276 where
277 R: GLWEInfos,
278 A: GLWEInfos,
279 B: GGLWEInfos,
280 {
281 BE::glwe_tensor_relinearize_tmp_bytes(self, res, a, tsk)
282 }
283);
284
285impl_operations_delegate!(
286 GLWERotate<BE>,
287 GLWERotateImpl<BE>,
288 GLWERotateDefault<BE>,
289 fn glwe_rotate_tmp_bytes(&self) -> usize {
290 BE::glwe_rotate_tmp_bytes(self)
291 },
292 fn glwe_rotate<R, A>(&self, k: i64, res: &mut R, a: &A)
293 where
294 R: GLWEToBackendMut<BE>,
295 A: GLWEToBackendRef<BE>,
296 {
297 BE::glwe_rotate(self, k, res, a)
298 },
299 fn glwe_rotate_assign<R>(&self, k: i64, res: &mut R, scratch: &mut ScratchArena<'_, BE>)
300 where
301 R: GLWEToBackendMut<BE>,
302 {
303 BE::glwe_rotate_assign(self, k, res, scratch);
304 }
305);
306
307impl_operations_delegate!(
308 GGSWRotate<BE>,
309 GGSWRotateImpl<BE>,
310 GGSWRotateDefault<BE>,
311 fn ggsw_rotate_tmp_bytes(&self) -> usize {
312 BE::ggsw_rotate_tmp_bytes(self)
313 },
314 fn ggsw_rotate<R, A>(&self, k: i64, res: &mut R, a: &A)
315 where
316 R: GGSWToBackendMut<BE> + GGSWAtViewMut<BE> + GGSWInfos,
317 A: GGSWToBackendRef<BE> + GGSWAtViewRef<BE> + GGSWInfos,
318 {
319 BE::ggsw_rotate(self, k, res, a)
320 },
321 fn ggsw_rotate_assign<R>(&self, k: i64, res: &mut R, scratch: &mut ScratchArena<'_, BE>)
322 where
323 R: GGSWToBackendMut<BE> + GGSWInfos,
324 {
325 BE::ggsw_rotate_assign(self, k, res, scratch)
326 }
327);
328
329impl_operations_delegate!(
330 GLWEMulXpMinusOne<BE>,
331 GLWEMulXpMinusOneImpl<BE>,
332 GLWEMulXpMinusOneDefault<BE>,
333 fn glwe_mul_xp_minus_one<R, A>(&self, k: i64, res: &mut R, a: &A)
334 where
335 R: GLWEToBackendMut<BE>,
336 A: GLWEToBackendRef<BE>,
337 {
338 BE::glwe_mul_xp_minus_one(self, k, res, a)
339 },
340 fn glwe_mul_xp_minus_one_assign<R>(&self, k: i64, res: &mut R, scratch: &mut ScratchArena<'_, BE>)
341 where
342 R: GLWEToBackendMut<BE>,
343 {
344 BE::glwe_mul_xp_minus_one_assign(self, k, res, scratch)
345 }
346);
347
348impl_operations_delegate!(
349 GLWEShift<BE>,
350 GLWEShiftImpl<BE>,
351 GLWEShiftDefault<BE>,
352 fn glwe_shift_tmp_bytes(&self) -> usize {
353 BE::glwe_shift_tmp_bytes(self)
354 },
355 fn glwe_rsh<R>(&self, k: usize, res: &mut R, scratch: &mut ScratchArena<'_, BE>)
356 where
357 R: GLWEToBackendMut<BE>,
358 {
359 BE::glwe_rsh(self, k, res, scratch)
360 },
361 fn glwe_lsh_assign<R>(&self, res: &mut R, k: usize, scratch: &mut ScratchArena<'_, BE>)
362 where
363 R: GLWEToBackendMut<BE>,
364 {
365 BE::glwe_lsh_assign(self, res, k, scratch)
366 },
367 fn glwe_lsh<R, A>(&self, res: &mut R, a: &A, k: usize, scratch: &mut ScratchArena<'_, BE>)
368 where
369 R: GLWEToBackendMut<BE>,
370 A: GLWEToBackendRef<BE>,
371 {
372 BE::glwe_lsh(self, res, a, k, scratch)
373 },
374 fn glwe_lsh_add<R, A>(&self, res: &mut R, a: &A, k: usize, scratch: &mut ScratchArena<'_, BE>)
375 where
376 R: GLWEToBackendMut<BE>,
377 A: GLWEToBackendRef<BE>,
378 {
379 BE::glwe_lsh_add(self, res, a, k, scratch)
380 },
381 fn glwe_lsh_sub<R, A>(&self, res: &mut R, a: &A, k: usize, scratch: &mut ScratchArena<'_, BE>)
382 where
383 R: GLWEToBackendMut<BE>,
384 A: GLWEToBackendRef<BE>,
385 {
386 BE::glwe_lsh_sub(self, res, a, k, scratch)
387 }
388);
389
390impl_operations_delegate!(
391 GLWENormalize<BE>,
392 GLWENormalizeImpl<BE>,
393 GLWENormalizeDefault<BE>,
394 fn glwe_normalize_tmp_bytes(&self) -> usize {
395 BE::glwe_normalize_tmp_bytes(self)
396 },
397 fn glwe_normalize<R, A>(&self, res: &mut R, a: &A, scratch: &mut ScratchArena<'_, BE>)
398 where
399 R: GLWEToBackendMut<BE>,
400 A: GLWEToBackendRef<BE>,
401 {
402 BE::glwe_normalize(self, res, a, scratch)
403 },
404 fn glwe_normalize_assign<R>(&self, res: &mut R, scratch: &mut ScratchArena<'_, BE>)
405 where
406 R: GLWEToBackendMut<BE>,
407 {
408 BE::glwe_normalize_assign(self, res, scratch)
409 }
410);
411
412impl_operations_delegate!(
413 GLWETrace<BE>,
414 GLWETraceImpl<BE>,
415 GLWETraceDefault<BE>,
416 fn glwe_trace_galois_elements(&self) -> Vec<i64> {
417 BE::glwe_trace_galois_elements(self)
418 },
419 fn glwe_trace_tmp_bytes<R, A, K>(&self, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
420 where
421 R: GLWEInfos,
422 A: GLWEInfos,
423 K: GGLWEInfos,
424 {
425 BE::glwe_trace_tmp_bytes(self, res_infos, a_infos, key_infos)
426 },
427 fn glwe_trace<R, A, K, H>(
428 &self,
429 res: &mut R,
430 skip: usize,
431 a: &A,
432 keys: &H,
433 key_size: usize,
434 scratch: &mut ScratchArena<'_, BE>,
435 ) where
436 R: GLWEToBackendMut<BE> + GLWEInfos,
437 A: GLWEToBackendRef<BE> + GLWEInfos,
438 K: GGLWEPreparedToBackendRef<BE> + GetGaloisElement + GGLWEInfos,
439 H: GLWEAutomorphismKeyHelper<K, BE>,
440 {
441 BE::glwe_trace(self, res, skip, a, keys, key_size, scratch)
442 },
443 fn glwe_trace_assign<R, K, H>(&self, res: &mut R, skip: usize, keys: &H, key_size: usize, scratch: &mut ScratchArena<'_, BE>)
444 where
445 R: GLWEToBackendMut<BE> + GLWEInfos,
446 K: GGLWEPreparedToBackendRef<BE> + GetGaloisElement + GGLWEInfos,
447 H: GLWEAutomorphismKeyHelper<K, BE>,
448 {
449 BE::glwe_trace_assign(self, res, skip, keys, key_size, scratch)
450 }
451);
452
453impl_operations_delegate!(
454 GLWEPacking<BE>,
455 GLWEPackImpl<BE>,
456 GLWEPackingDefault<BE>,
457 fn glwe_pack_galois_elements(&self) -> Vec<i64> {
458 BE::glwe_pack_galois_elements(self)
459 },
460 fn glwe_pack_tmp_bytes<R, K>(&self, res: &R, key: &K) -> usize
461 where
462 R: GLWEInfos,
463 K: GGLWEInfos,
464 {
465 BE::glwe_pack_tmp_bytes(self, res, key)
466 },
467 fn glwe_pack<R, A, K, H>(
468 &self,
469 res: &mut R,
470 a: HashMap<usize, &mut A>,
471 log_gap_out: usize,
472 keys: &H,
473 key_size: usize,
474 scratch: &mut ScratchArena<'_, BE>,
475 ) where
476 R: GLWEToBackendMut<BE> + GLWEInfos,
477 A: GLWEToBackendMut<BE> + GLWEInfos,
478 K: GGLWEPreparedToBackendRef<BE> + GetGaloisElement + GGLWEInfos,
479 H: GLWEAutomorphismKeyHelper<K, BE>,
480 {
481 BE::glwe_pack(self, res, a, log_gap_out, keys, key_size, scratch)
482 }
483);