Skip to main content

poulpy_core/delegates/
operations.rs

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);