poulpy/core/src/scratch.rs
core/src/scratch.rsRaw
1use backend::hal::{
2 api::{TakeMatZnx, TakeScalarZnx, TakeSvpPPol, TakeVecZnx, TakeVecZnxDft, TakeVmpPMat},
3 layouts::{Backend, DataRef, Scratch},
4 oep::{TakeMatZnxImpl, TakeScalarZnxImpl, TakeSvpPPolImpl, TakeVecZnxDftImpl, TakeVecZnxImpl, TakeVmpPMatImpl},
5};
6
7use crate::{
8 dist::Distribution,
9 layouts::{
10 GGLWEAutomorphismKey, GGLWECiphertext, GGLWETensorKey, GGSWCiphertext, GLWECiphertext, GLWEPlaintext, GLWEPublicKey,
11 GLWESecret, GGLWESwitchingKey, Infos,
12 prepared::{
13 GGLWEAutomorphismKeyExec, GGLWECiphertextExec, GGSWCiphertextExec, GLWEPublicKeyExec, GLWESecretExec,
14 GGLWESwitchingKeyExec, GGLWETensorKeyExec,
15 },
16 },
17};
18
19pub trait TakeLike<'a, B: Backend, T> {
20 type Output;
21 fn take_like(&'a mut self, template: &T) -> (Self::Output, &'a mut Self);
22}
23
24pub trait TakeGLWECt<B: Backend> {
25 fn take_glwe_ct(&mut self, n: usize, basek: usize, k: usize, rank: usize) -> (GLWECiphertext<&mut [u8]>, &mut Self);
26}
27
28pub trait TakeGLWECtSlice<B: Backend> {
29 fn take_glwe_ct_slice(
30 &mut self,
31 size: usize,
32 n: usize,
33 basek: usize,
34 k: usize,
35 rank: usize,
36 ) -> (Vec<GLWECiphertext<&mut [u8]>>, &mut Self);
37}
38
39pub trait TakeGLWEPt<B: Backend> {
40 fn take_glwe_pt(&mut self, n: usize, basek: usize, k: usize) -> (GLWEPlaintext<&mut [u8]>, &mut Self);
41}
42
43pub trait TakeGGLWE<B: Backend> {
44 fn take_gglwe(
45 &mut self,
46 n: usize,
47 basek: usize,
48 k: usize,
49 rows: usize,
50 digits: usize,
51 rank_in: usize,
52 rank_out: usize,
53 ) -> (GGLWECiphertext<&mut [u8]>, &mut Self);
54}
55
56pub trait TakeGGLWEExec<B: Backend> {
57 fn take_gglwe_exec(
58 &mut self,
59 n: usize,
60 basek: usize,
61 k: usize,
62 rows: usize,
63 digits: usize,
64 rank_in: usize,
65 rank_out: usize,
66 ) -> (GGLWECiphertextExec<&mut [u8], B>, &mut Self);
67}
68
69pub trait TakeGGSW<B: Backend> {
70 fn take_ggsw(
71 &mut self,
72 n: usize,
73 basek: usize,
74 k: usize,
75 rows: usize,
76 digits: usize,
77 rank: usize,
78 ) -> (GGSWCiphertext<&mut [u8]>, &mut Self);
79}
80
81pub trait TakeGGSWExec<B: Backend> {
82 fn take_ggsw_exec(
83 &mut self,
84 n: usize,
85 basek: usize,
86 k: usize,
87 rows: usize,
88 digits: usize,
89 rank: usize,
90 ) -> (GGSWCiphertextExec<&mut [u8], B>, &mut Self);
91}
92
93pub trait TakeGLWESecret<B: Backend> {
94 fn take_glwe_secret(&mut self, n: usize, rank: usize) -> (GLWESecret<&mut [u8]>, &mut Self);
95}
96
97pub trait TakeGLWESecretExec<B: Backend> {
98 fn take_glwe_secret_exec(&mut self, n: usize, rank: usize) -> (GLWESecretExec<&mut [u8], B>, &mut Self);
99}
100
101pub trait TakeGLWEPk<B: Backend> {
102 fn take_glwe_pk(&mut self, n: usize, basek: usize, k: usize, rank: usize) -> (GLWEPublicKey<&mut [u8]>, &mut Self);
103}
104
105pub trait TakeGLWEPkExec<B: Backend> {
106 fn take_glwe_pk_exec(
107 &mut self,
108 n: usize,
109 basek: usize,
110 k: usize,
111 rank: usize,
112 ) -> (GLWEPublicKeyExec<&mut [u8], B>, &mut Self);
113}
114
115pub trait TakeGLWESwitchingKey<B: Backend> {
116 fn take_glwe_switching_key(
117 &mut self,
118 n: usize,
119 basek: usize,
120 k: usize,
121 rows: usize,
122 digits: usize,
123 rank_in: usize,
124 rank_out: usize,
125 ) -> (GGLWESwitchingKey<&mut [u8]>, &mut Self);
126}
127
128pub trait TakeGLWESwitchingKeyExec<B: Backend> {
129 fn take_glwe_switching_key_exec(
130 &mut self,
131 n: usize,
132 basek: usize,
133 k: usize,
134 rows: usize,
135 digits: usize,
136 rank_in: usize,
137 rank_out: usize,
138 ) -> (GGLWESwitchingKeyExec<&mut [u8], B>, &mut Self);
139}
140
141pub trait TakeTensorKey<B: Backend> {
142 fn take_tensor_key(
143 &mut self,
144 n: usize,
145 basek: usize,
146 k: usize,
147 rows: usize,
148 digits: usize,
149 rank: usize,
150 ) -> (GGLWETensorKey<&mut [u8]>, &mut Self);
151}
152
153pub trait TakeTensorKeyExec<B: Backend> {
154 fn take_tensor_key_exec(
155 &mut self,
156 n: usize,
157 basek: usize,
158 k: usize,
159 rows: usize,
160 digits: usize,
161 rank: usize,
162 ) -> (GGLWETensorKeyExec<&mut [u8], B>, &mut Self);
163}
164
165pub trait TakeAutomorphismKey<B: Backend> {
166 fn take_automorphism_key(
167 &mut self,
168 n: usize,
169 basek: usize,
170 k: usize,
171 rows: usize,
172 digits: usize,
173 rank: usize,
174 ) -> (GGLWEAutomorphismKey<&mut [u8]>, &mut Self);
175}
176
177pub trait TakeAutomorphismKeyExec<B: Backend> {
178 fn take_automorphism_key_exec(
179 &mut self,
180 n: usize,
181 basek: usize,
182 k: usize,
183 rows: usize,
184 digits: usize,
185 rank: usize,
186 ) -> (GGLWEAutomorphismKeyExec<&mut [u8], B>, &mut Self);
187}
188
189impl<B: Backend> TakeGLWECt<B> for Scratch<B>
190where
191 Scratch<B>: TakeVecZnx,
192{
193 fn take_glwe_ct(&mut self, n: usize, basek: usize, k: usize, rank: usize) -> (GLWECiphertext<&mut [u8]>, &mut Self) {
194 let (data, scratch) = self.take_vec_znx(n, rank + 1, k.div_ceil(basek));
195 (GLWECiphertext { data, basek, k }, scratch)
196 }
197}
198
199impl<'a, B, D> TakeLike<'a, B, GLWECiphertext<D>> for Scratch<B>
200where
201 B: Backend + TakeVecZnxImpl<B>,
202 D: DataRef,
203{
204 type Output = GLWECiphertext<&'a mut [u8]>;
205
206 fn take_like(&'a mut self, template: &GLWECiphertext<D>) -> (Self::Output, &'a mut Self) {
207 let (data, scratch) = B::take_vec_znx_impl(self, template.n(), template.cols(), template.size());
208 (
209 GLWECiphertext {
210 data,
211 basek: template.basek(),
212 k: template.k(),
213 },
214 scratch,
215 )
216 }
217}
218
219impl<B: Backend> TakeGLWECtSlice<B> for Scratch<B>
220where
221 Scratch<B>: TakeVecZnx,
222{
223 fn take_glwe_ct_slice(
224 &mut self,
225 size: usize,
226 n: usize,
227 basek: usize,
228 k: usize,
229 rank: usize,
230 ) -> (Vec<GLWECiphertext<&mut [u8]>>, &mut Self) {
231 let mut scratch: &mut Scratch<B> = self;
232 let mut cts: Vec<GLWECiphertext<&mut [u8]>> = Vec::with_capacity(size);
233 for _ in 0..size {
234 let (ct, new_scratch) = scratch.take_glwe_ct(n, basek, k, rank);
235 scratch = new_scratch;
236 cts.push(ct);
237 }
238 (cts, scratch)
239 }
240}
241
242impl<B: Backend> TakeGLWEPt<B> for Scratch<B>
243where
244 Scratch<B>: TakeVecZnx,
245{
246 fn take_glwe_pt(&mut self, n: usize, basek: usize, k: usize) -> (GLWEPlaintext<&mut [u8]>, &mut Self) {
247 let (data, scratch) = self.take_vec_znx(n, 1, k.div_ceil(basek));
248 (GLWEPlaintext { data, basek, k }, scratch)
249 }
250}
251
252impl<'a, B, D> TakeLike<'a, B, GLWEPlaintext<D>> for Scratch<B>
253where
254 B: Backend + TakeVecZnxImpl<B>,
255 D: DataRef,
256{
257 type Output = GLWEPlaintext<&'a mut [u8]>;
258
259 fn take_like(&'a mut self, template: &GLWEPlaintext<D>) -> (Self::Output, &'a mut Self) {
260 let (data, scratch) = B::take_vec_znx_impl(self, template.n(), template.cols(), template.size());
261 (
262 GLWEPlaintext {
263 data,
264 basek: template.basek(),
265 k: template.k(),
266 },
267 scratch,
268 )
269 }
270}
271
272impl<B: Backend> TakeGGLWE<B> for Scratch<B>
273where
274 Scratch<B>: TakeMatZnx,
275{
276 fn take_gglwe(
277 &mut self,
278 n: usize,
279 basek: usize,
280 k: usize,
281 rows: usize,
282 digits: usize,
283 rank_in: usize,
284 rank_out: usize,
285 ) -> (GGLWECiphertext<&mut [u8]>, &mut Self) {
286 let (data, scratch) = self.take_mat_znx(
287 n,
288 rows.div_ceil(digits),
289 rank_in,
290 rank_out + 1,
291 k.div_ceil(basek),
292 );
293 (
294 GGLWECiphertext {
295 data: data,
296 basek: basek,
297 k,
298 digits,
299 },
300 scratch,
301 )
302 }
303}
304
305impl<'a, B, D> TakeLike<'a, B, GGLWECiphertext<D>> for Scratch<B>
306where
307 B: Backend + TakeMatZnxImpl<B>,
308 D: DataRef,
309{
310 type Output = GGLWECiphertext<&'a mut [u8]>;
311
312 fn take_like(&'a mut self, template: &GGLWECiphertext<D>) -> (Self::Output, &'a mut Self) {
313 let (data, scratch) = B::take_mat_znx_impl(
314 self,
315 template.n(),
316 template.rows(),
317 template.data.cols_in(),
318 template.data.cols_out(),
319 template.size(),
320 );
321 (
322 GGLWECiphertext {
323 data,
324 basek: template.basek(),
325 k: template.k(),
326 digits: template.digits(),
327 },
328 scratch,
329 )
330 }
331}
332
333impl<B: Backend> TakeGGLWEExec<B> for Scratch<B>
334where
335 Scratch<B>: TakeVmpPMat<B>,
336{
337 fn take_gglwe_exec(
338 &mut self,
339 n: usize,
340 basek: usize,
341 k: usize,
342 rows: usize,
343 digits: usize,
344 rank_in: usize,
345 rank_out: usize,
346 ) -> (GGLWECiphertextExec<&mut [u8], B>, &mut Self) {
347 let (data, scratch) = self.take_vmp_pmat(
348 n,
349 rows.div_ceil(digits),
350 rank_in,
351 rank_out + 1,
352 k.div_ceil(basek),
353 );
354 (
355 GGLWECiphertextExec {
356 data: data,
357 basek: basek,
358 k,
359 digits,
360 },
361 scratch,
362 )
363 }
364}
365
366impl<'a, B, D> TakeLike<'a, B, GGLWECiphertextExec<D, B>> for Scratch<B>
367where
368 B: Backend + TakeVmpPMatImpl<B>,
369 D: DataRef,
370{
371 type Output = GGLWECiphertextExec<&'a mut [u8], B>;
372
373 fn take_like(&'a mut self, template: &GGLWECiphertextExec<D, B>) -> (Self::Output, &'a mut Self) {
374 let (data, scratch) = B::take_vmp_pmat_impl(
375 self,
376 template.n(),
377 template.rows(),
378 template.data.cols_in(),
379 template.data.cols_out(),
380 template.size(),
381 );
382 (
383 GGLWECiphertextExec {
384 data,
385 basek: template.basek(),
386 k: template.k(),
387 digits: template.digits(),
388 },
389 scratch,
390 )
391 }
392}
393
394impl<B: Backend> TakeGGSW<B> for Scratch<B>
395where
396 Scratch<B>: TakeMatZnx,
397{
398 fn take_ggsw(
399 &mut self,
400 n: usize,
401 basek: usize,
402 k: usize,
403 rows: usize,
404 digits: usize,
405 rank: usize,
406 ) -> (GGSWCiphertext<&mut [u8]>, &mut Self) {
407 let (data, scratch) = self.take_mat_znx(
408 n,
409 rows.div_ceil(digits),
410 rank + 1,
411 rank + 1,
412 k.div_ceil(basek),
413 );
414 (
415 GGSWCiphertext {
416 data,
417 basek,
418 k,
419 digits,
420 },
421 scratch,
422 )
423 }
424}
425
426impl<'a, B, D> TakeLike<'a, B, GGSWCiphertext<D>> for Scratch<B>
427where
428 B: Backend + TakeMatZnxImpl<B>,
429 D: DataRef,
430{
431 type Output = GGSWCiphertext<&'a mut [u8]>;
432
433 fn take_like(&'a mut self, template: &GGSWCiphertext<D>) -> (Self::Output, &'a mut Self) {
434 let (data, scratch) = B::take_mat_znx_impl(
435 self,
436 template.n(),
437 template.rows(),
438 template.data.cols_in(),
439 template.data.cols_out(),
440 template.size(),
441 );
442 (
443 GGSWCiphertext {
444 data,
445 basek: template.basek(),
446 k: template.k(),
447 digits: template.digits(),
448 },
449 scratch,
450 )
451 }
452}
453
454impl<B: Backend> TakeGGSWExec<B> for Scratch<B>
455where
456 Scratch<B>: TakeVmpPMat<B>,
457{
458 fn take_ggsw_exec(
459 &mut self,
460 n: usize,
461 basek: usize,
462 k: usize,
463 rows: usize,
464 digits: usize,
465 rank: usize,
466 ) -> (GGSWCiphertextExec<&mut [u8], B>, &mut Self) {
467 let (data, scratch) = self.take_vmp_pmat(
468 n,
469 rows.div_ceil(digits),
470 rank + 1,
471 rank + 1,
472 k.div_ceil(basek),
473 );
474 (
475 GGSWCiphertextExec {
476 data,
477 basek,
478 k,
479 digits,
480 },
481 scratch,
482 )
483 }
484}
485
486impl<'a, B, D> TakeLike<'a, B, GGSWCiphertextExec<D, B>> for Scratch<B>
487where
488 B: Backend + TakeVmpPMatImpl<B>,
489 D: DataRef,
490{
491 type Output = GGSWCiphertextExec<&'a mut [u8], B>;
492
493 fn take_like(&'a mut self, template: &GGSWCiphertextExec<D, B>) -> (Self::Output, &'a mut Self) {
494 let (data, scratch) = B::take_vmp_pmat_impl(
495 self,
496 template.n(),
497 template.rows(),
498 template.data.cols_in(),
499 template.data.cols_out(),
500 template.size(),
501 );
502 (
503 GGSWCiphertextExec {
504 data,
505 basek: template.basek(),
506 k: template.k(),
507 digits: template.digits(),
508 },
509 scratch,
510 )
511 }
512}
513
514impl<B: Backend> TakeGLWEPk<B> for Scratch<B>
515where
516 Scratch<B>: TakeVecZnx,
517{
518 fn take_glwe_pk(&mut self, n: usize, basek: usize, k: usize, rank: usize) -> (GLWEPublicKey<&mut [u8]>, &mut Self) {
519 let (data, scratch) = self.take_vec_znx(n, rank + 1, k.div_ceil(basek));
520 (
521 GLWEPublicKey {
522 data,
523 k,
524 basek,
525 dist: Distribution::NONE,
526 },
527 scratch,
528 )
529 }
530}
531
532impl<'a, B, D> TakeLike<'a, B, GLWEPublicKey<D>> for Scratch<B>
533where
534 B: Backend + TakeVecZnxImpl<B>,
535 D: DataRef,
536{
537 type Output = GLWEPublicKey<&'a mut [u8]>;
538
539 fn take_like(&'a mut self, template: &GLWEPublicKey<D>) -> (Self::Output, &'a mut Self) {
540 let (data, scratch) = B::take_vec_znx_impl(self, template.n(), template.cols(), template.size());
541 (
542 GLWEPublicKey {
543 data,
544 basek: template.basek(),
545 k: template.k(),
546 dist: template.dist,
547 },
548 scratch,
549 )
550 }
551}
552
553impl<B: Backend> TakeGLWEPkExec<B> for Scratch<B>
554where
555 Scratch<B>: TakeVecZnxDft<B>,
556{
557 fn take_glwe_pk_exec(
558 &mut self,
559 n: usize,
560 basek: usize,
561 k: usize,
562 rank: usize,
563 ) -> (GLWEPublicKeyExec<&mut [u8], B>, &mut Self) {
564 let (data, scratch) = self.take_vec_znx_dft(n, rank + 1, k.div_ceil(basek));
565 (
566 GLWEPublicKeyExec {
567 data,
568 k,
569 basek,
570 dist: Distribution::NONE,
571 },
572 scratch,
573 )
574 }
575}
576
577impl<'a, B, D> TakeLike<'a, B, GLWEPublicKeyExec<D, B>> for Scratch<B>
578where
579 B: Backend + TakeVecZnxDftImpl<B>,
580 D: DataRef,
581{
582 type Output = GLWEPublicKeyExec<&'a mut [u8], B>;
583
584 fn take_like(&'a mut self, template: &GLWEPublicKeyExec<D, B>) -> (Self::Output, &'a mut Self) {
585 let (data, scratch) = B::take_vec_znx_dft_impl(self, template.n(), template.cols(), template.size());
586 (
587 GLWEPublicKeyExec {
588 data,
589 basek: template.basek(),
590 k: template.k(),
591 dist: template.dist,
592 },
593 scratch,
594 )
595 }
596}
597
598impl<B: Backend> TakeGLWESecret<B> for Scratch<B>
599where
600 Scratch<B>: TakeScalarZnx,
601{
602 fn take_glwe_secret(&mut self, n: usize, rank: usize) -> (GLWESecret<&mut [u8]>, &mut Self) {
603 let (data, scratch) = self.take_scalar_znx(n, rank);
604 (
605 GLWESecret {
606 data,
607 dist: Distribution::NONE,
608 },
609 scratch,
610 )
611 }
612}
613
614impl<'a, B, D> TakeLike<'a, B, GLWESecret<D>> for Scratch<B>
615where
616 B: Backend + TakeScalarZnxImpl<B>,
617 D: DataRef,
618{
619 type Output = GLWESecret<&'a mut [u8]>;
620
621 fn take_like(&'a mut self, template: &GLWESecret<D>) -> (Self::Output, &'a mut Self) {
622 let (data, scratch) = B::take_scalar_znx_impl(self, template.n(), template.rank());
623 (
624 GLWESecret {
625 data,
626 dist: template.dist,
627 },
628 scratch,
629 )
630 }
631}
632
633impl<B: Backend> TakeGLWESecretExec<B> for Scratch<B>
634where
635 Scratch<B>: TakeSvpPPol<B>,
636{
637 fn take_glwe_secret_exec(&mut self, n: usize, rank: usize) -> (GLWESecretExec<&mut [u8], B>, &mut Self) {
638 let (data, scratch) = self.take_svp_ppol(n, rank);
639 (
640 GLWESecretExec {
641 data,
642 dist: Distribution::NONE,
643 },
644 scratch,
645 )
646 }
647}
648
649impl<'a, B, D> TakeLike<'a, B, GLWESecretExec<D, B>> for Scratch<B>
650where
651 B: Backend + TakeSvpPPolImpl<B>,
652 D: DataRef,
653{
654 type Output = GLWESecretExec<&'a mut [u8], B>;
655
656 fn take_like(&'a mut self, template: &GLWESecretExec<D, B>) -> (Self::Output, &'a mut Self) {
657 let (data, scratch) = B::take_svp_ppol_impl(self, template.n(), template.rank());
658 (
659 GLWESecretExec {
660 data,
661 dist: template.dist,
662 },
663 scratch,
664 )
665 }
666}
667
668impl<B: Backend> TakeGLWESwitchingKey<B> for Scratch<B>
669where
670 Scratch<B>: TakeMatZnx,
671{
672 fn take_glwe_switching_key(
673 &mut self,
674 n: usize,
675 basek: usize,
676 k: usize,
677 rows: usize,
678 digits: usize,
679 rank_in: usize,
680 rank_out: usize,
681 ) -> (GGLWESwitchingKey<&mut [u8]>, &mut Self) {
682 let (data, scratch) = self.take_gglwe(n, basek, k, rows, digits, rank_in, rank_out);
683 (
684 GGLWESwitchingKey {
685 key: data,
686 sk_in_n: 0,
687 sk_out_n: 0,
688 },
689 scratch,
690 )
691 }
692}
693
694impl<'a, B, D> TakeLike<'a, B, GGLWESwitchingKey<D>> for Scratch<B>
695where
696 Scratch<B>: TakeLike<'a, B, GGLWECiphertext<D>, Output = GGLWECiphertext<&'a mut [u8]>>,
697 B: Backend + TakeMatZnxImpl<B>,
698 D: DataRef,
699{
700 type Output = GGLWESwitchingKey<&'a mut [u8]>;
701
702 fn take_like(&'a mut self, template: &GGLWESwitchingKey<D>) -> (Self::Output, &'a mut Self) {
703 let (key, scratch) = self.take_like(&template.key);
704 (
705 GGLWESwitchingKey {
706 key,
707 sk_in_n: template.sk_in_n,
708 sk_out_n: template.sk_out_n,
709 },
710 scratch,
711 )
712 }
713}
714
715impl<B: Backend> TakeGLWESwitchingKeyExec<B> for Scratch<B>
716where
717 Scratch<B>: TakeGGLWEExec<B>,
718{
719 fn take_glwe_switching_key_exec(
720 &mut self,
721 n: usize,
722 basek: usize,
723 k: usize,
724 rows: usize,
725 digits: usize,
726 rank_in: usize,
727 rank_out: usize,
728 ) -> (GGLWESwitchingKeyExec<&mut [u8], B>, &mut Self) {
729 let (data, scratch) = self.take_gglwe_exec(n, basek, k, rows, digits, rank_in, rank_out);
730 (
731 GGLWESwitchingKeyExec {
732 key: data,
733 sk_in_n: 0,
734 sk_out_n: 0,
735 },
736 scratch,
737 )
738 }
739}
740
741impl<'a, B, D> TakeLike<'a, B, GGLWESwitchingKeyExec<D, B>> for Scratch<B>
742where
743 Scratch<B>: TakeLike<'a, B, GGLWECiphertextExec<D, B>, Output = GGLWECiphertextExec<&'a mut [u8], B>>,
744 B: Backend + TakeMatZnxImpl<B>,
745 D: DataRef,
746{
747 type Output = GGLWESwitchingKeyExec<&'a mut [u8], B>;
748
749 fn take_like(&'a mut self, template: &GGLWESwitchingKeyExec<D, B>) -> (Self::Output, &'a mut Self) {
750 let (key, scratch) = self.take_like(&template.key);
751 (
752 GGLWESwitchingKeyExec {
753 key,
754 sk_in_n: template.sk_in_n,
755 sk_out_n: template.sk_out_n,
756 },
757 scratch,
758 )
759 }
760}
761
762impl<B: Backend> TakeAutomorphismKey<B> for Scratch<B>
763where
764 Scratch<B>: TakeMatZnx,
765{
766 fn take_automorphism_key(
767 &mut self,
768 n: usize,
769 basek: usize,
770 k: usize,
771 rows: usize,
772 digits: usize,
773 rank: usize,
774 ) -> (GGLWEAutomorphismKey<&mut [u8]>, &mut Self) {
775 let (data, scratch) = self.take_glwe_switching_key(n, basek, k, rows, digits, rank, rank);
776 (GGLWEAutomorphismKey { key: data, p: 0 }, scratch)
777 }
778}
779
780impl<'a, B, D> TakeLike<'a, B, GGLWEAutomorphismKey<D>> for Scratch<B>
781where
782 Scratch<B>: TakeLike<'a, B, GGLWESwitchingKey<D>, Output = GGLWESwitchingKey<&'a mut [u8]>>,
783 B: Backend + TakeMatZnxImpl<B>,
784 D: DataRef,
785{
786 type Output = GGLWEAutomorphismKey<&'a mut [u8]>;
787
788 fn take_like(&'a mut self, template: &GGLWEAutomorphismKey<D>) -> (Self::Output, &'a mut Self) {
789 let (key, scratch) = self.take_like(&template.key);
790 (GGLWEAutomorphismKey { key, p: template.p }, scratch)
791 }
792}
793
794impl<B: Backend> TakeAutomorphismKeyExec<B> for Scratch<B>
795where
796 Scratch<B>: TakeGLWESwitchingKeyExec<B>,
797{
798 fn take_automorphism_key_exec(
799 &mut self,
800 n: usize,
801 basek: usize,
802 k: usize,
803 rows: usize,
804 digits: usize,
805 rank: usize,
806 ) -> (GGLWEAutomorphismKeyExec<&mut [u8], B>, &mut Self) {
807 let (data, scratch) = self.take_glwe_switching_key_exec(n, basek, k, rows, digits, rank, rank);
808 (GGLWEAutomorphismKeyExec { key: data, p: 0 }, scratch)
809 }
810}
811
812impl<'a, B, D> TakeLike<'a, B, GGLWEAutomorphismKeyExec<D, B>> for Scratch<B>
813where
814 Scratch<B>: TakeLike<'a, B, GGLWESwitchingKeyExec<D, B>, Output = GGLWESwitchingKeyExec<&'a mut [u8], B>>,
815 B: Backend + TakeMatZnxImpl<B>,
816 D: DataRef,
817{
818 type Output = GGLWEAutomorphismKeyExec<&'a mut [u8], B>;
819
820 fn take_like(&'a mut self, template: &GGLWEAutomorphismKeyExec<D, B>) -> (Self::Output, &'a mut Self) {
821 let (key, scratch) = self.take_like(&template.key);
822 (GGLWEAutomorphismKeyExec { key, p: template.p }, scratch)
823 }
824}
825
826impl<B: Backend> TakeTensorKey<B> for Scratch<B>
827where
828 Scratch<B>: TakeMatZnx,
829{
830 fn take_tensor_key(
831 &mut self,
832 n: usize,
833 basek: usize,
834 k: usize,
835 rows: usize,
836 digits: usize,
837 rank: usize,
838 ) -> (GGLWETensorKey<&mut [u8]>, &mut Self) {
839 let mut keys: Vec<GGLWESwitchingKey<&mut [u8]>> = Vec::new();
840 let pairs: usize = (((rank + 1) * rank) >> 1).max(1);
841
842 let mut scratch: &mut Scratch<B> = self;
843
844 if pairs != 0 {
845 let (gglwe, s) = scratch.take_glwe_switching_key(n, basek, k, rows, digits, 1, rank);
846 scratch = s;
847 keys.push(gglwe);
848 }
849 for _ in 1..pairs {
850 let (gglwe, s) = scratch.take_glwe_switching_key(n, basek, k, rows, digits, 1, rank);
851 scratch = s;
852 keys.push(gglwe);
853 }
854 (GGLWETensorKey { keys }, scratch)
855 }
856}
857
858impl<'a, B, D> TakeLike<'a, B, GGLWETensorKey<D>> for Scratch<B>
859where
860 Scratch<B>: TakeLike<'a, B, GGLWESwitchingKey<D>, Output = GGLWESwitchingKey<&'a mut [u8]>>,
861 B: Backend + TakeMatZnxImpl<B>,
862 D: DataRef,
863{
864 type Output = GGLWETensorKey<&'a mut [u8]>;
865
866 fn take_like(&'a mut self, template: &GGLWETensorKey<D>) -> (Self::Output, &'a mut Self) {
867 let mut keys: Vec<GGLWESwitchingKey<&mut [u8]>> = Vec::new();
868 let pairs: usize = template.keys.len();
869
870 let mut scratch: &mut Scratch<B> = self;
871
872 if pairs != 0 {
873 let (gglwe, s) = scratch.take_like(template.at(0, 0));
874 scratch = s;
875 keys.push(gglwe);
876 }
877 for _ in 1..pairs {
878 let (gglwe, s) = scratch.take_like(template.at(0, 0));
879 scratch = s;
880 keys.push(gglwe);
881 }
882
883 (GGLWETensorKey { keys }, scratch)
884 }
885}
886
887impl<B: Backend> TakeTensorKeyExec<B> for Scratch<B>
888where
889 Scratch<B>: TakeVmpPMat<B>,
890{
891 fn take_tensor_key_exec(
892 &mut self,
893 n: usize,
894 basek: usize,
895 k: usize,
896 rows: usize,
897 digits: usize,
898 rank: usize,
899 ) -> (GGLWETensorKeyExec<&mut [u8], B>, &mut Self) {
900 let mut keys: Vec<GGLWESwitchingKeyExec<&mut [u8], B>> = Vec::new();
901 let pairs: usize = (((rank + 1) * rank) >> 1).max(1);
902
903 let mut scratch: &mut Scratch<B> = self;
904
905 if pairs != 0 {
906 let (gglwe, s) = scratch.take_glwe_switching_key_exec(n, basek, k, rows, digits, 1, rank);
907 scratch = s;
908 keys.push(gglwe);
909 }
910 for _ in 1..pairs {
911 let (gglwe, s) = scratch.take_glwe_switching_key_exec(n, basek, k, rows, digits, 1, rank);
912 scratch = s;
913 keys.push(gglwe);
914 }
915 (GGLWETensorKeyExec { keys }, scratch)
916 }
917}
918
919impl<'a, B, D> TakeLike<'a, B, GGLWETensorKeyExec<D, B>> for Scratch<B>
920where
921 Scratch<B>: TakeLike<'a, B, GGLWESwitchingKeyExec<D, B>, Output = GGLWESwitchingKeyExec<&'a mut [u8], B>>,
922 B: Backend + TakeMatZnxImpl<B>,
923 D: DataRef,
924{
925 type Output = GGLWETensorKeyExec<&'a mut [u8], B>;
926
927 fn take_like(&'a mut self, template: &GGLWETensorKeyExec<D, B>) -> (Self::Output, &'a mut Self) {
928 let mut keys: Vec<GGLWESwitchingKeyExec<&mut [u8], B>> = Vec::new();
929 let pairs: usize = template.keys.len();
930
931 let mut scratch: &mut Scratch<B> = self;
932
933 if pairs != 0 {
934 let (gglwe, s) = scratch.take_like(template.at(0, 0));
935 scratch = s;
936 keys.push(gglwe);
937 }
938 for _ in 1..pairs {
939 let (gglwe, s) = scratch.take_like(template.at(0, 0));
940 scratch = s;
941 keys.push(gglwe);
942 }
943
944 (GGLWETensorKeyExec { keys }, scratch)
945 }
946}