poulpy/poulpy-hal/src/test_suite/svp.rs
poulpy-hal/src/test_suite/svp.rsRaw
1use rand::RngCore;
2
3use crate::{
4 api::{
5 ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDft, SvpApplyDftToDft, SvpApplyDftToDftAdd, SvpApplyDftToDftInplace,
6 SvpPPolAlloc, SvpPrepare, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxDftAlloc, VecZnxDftApply,
7 VecZnxIdftApplyConsume,
8 },
9 layouts::{Backend, DataViewMut, DigestU64, FillUniform, Module, ScalarZnx, ScratchOwned, SvpPPol, VecZnx, VecZnxDft},
10 source::Source,
11};
12
13pub fn test_svp_apply_dft<BR: Backend, BT: Backend>(basek: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
14where
15 Module<BR>: SvpPrepare<BR>
16 + SvpApplyDft<BR>
17 + SvpPPolAlloc<BR>
18 + VecZnxDftAlloc<BR>
19 + VecZnxBigNormalize<BR>
20 + VecZnxIdftApplyConsume<BR>
21 + VecZnxBigNormalizeTmpBytes,
22 Module<BT>: SvpPrepare<BT>
23 + SvpApplyDft<BT>
24 + SvpPPolAlloc<BT>
25 + VecZnxDftAlloc<BT>
26 + VecZnxBigNormalize<BT>
27 + VecZnxIdftApplyConsume<BT>
28 + VecZnxBigNormalizeTmpBytes,
29 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
30 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
31{
32 assert_eq!(module_ref.n(), module_test.n());
33 let n: usize = module_ref.n();
34
35 let cols: usize = 2;
36
37 let mut source: Source = Source::new([0u8; 32]);
38
39 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
40 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
41
42 let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
43 scalar.fill_uniform(basek, &mut source);
44
45 let scalar_digest: u64 = scalar.digest_u64();
46
47 let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
48 let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
49
50 for j in 0..cols {
51 module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
52 module_test.svp_prepare(&mut svp_test, j, &scalar, j);
53 }
54
55 assert_eq!(scalar.digest_u64(), scalar_digest);
56
57 let svp_ref_digest: u64 = svp_ref.digest_u64();
58 let svp_test_digest: u64 = svp_test.digest_u64();
59
60 for a_size in [1, 2, 3, 4] {
61 // Create a random input VecZnx
62 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
63 a.fill_uniform(basek, &mut source);
64
65 let a_digest: u64 = a.digest_u64();
66
67 for res_size in [1, 2, 3, 4] {
68 // Allocate VecZnxDft from FFT64Ref and module to test
69 let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
70 let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
71
72 // Fill output with garbage
73 source.fill_bytes(res_dft_ref.data_mut());
74 source.fill_bytes(res_dft_test.data_mut());
75
76 for j in 0..cols {
77 module_ref.svp_apply_dft(&mut res_dft_ref, j, &svp_ref, j, &a, j);
78 module_test.svp_apply_dft(&mut res_dft_test, j, &svp_test, j, &a, j);
79 }
80
81 // Assert no change to inputs
82 assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
83 assert_eq!(svp_test.digest_u64(), svp_test_digest);
84 assert_eq!(a.digest_u64(), a_digest);
85
86 let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
87 let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
88
89 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
90 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
91
92 for j in 0..cols {
93 module_ref.vec_znx_big_normalize(
94 basek,
95 &mut res_ref,
96 j,
97 &res_big_ref,
98 j,
99 scratch_ref.borrow(),
100 );
101 module_test.vec_znx_big_normalize(
102 basek,
103 &mut res_test,
104 j,
105 &res_big_test,
106 j,
107 scratch_test.borrow(),
108 );
109 }
110
111 assert_eq!(res_ref, res_test);
112 }
113 }
114}
115
116pub fn test_svp_apply_dft_to_dft<BR: Backend, BT: Backend>(basek: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
117where
118 Module<BR>: SvpPrepare<BR>
119 + SvpApplyDftToDft<BR>
120 + SvpPPolAlloc<BR>
121 + VecZnxDftAlloc<BR>
122 + VecZnxBigNormalize<BR>
123 + VecZnxDftApply<BR>
124 + VecZnxIdftApplyConsume<BR>
125 + VecZnxBigNormalizeTmpBytes,
126 Module<BT>: SvpPrepare<BT>
127 + SvpApplyDftToDft<BT>
128 + SvpPPolAlloc<BT>
129 + VecZnxDftAlloc<BT>
130 + VecZnxBigNormalize<BT>
131 + VecZnxDftApply<BT>
132 + VecZnxIdftApplyConsume<BT>
133 + VecZnxBigNormalizeTmpBytes,
134 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
135 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
136{
137 assert_eq!(module_ref.n(), module_test.n());
138 let n: usize = module_ref.n();
139
140 let cols: usize = 2;
141
142 let mut source: Source = Source::new([0u8; 32]);
143
144 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
145 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
146
147 let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
148 scalar.fill_uniform(basek, &mut source);
149
150 let scalar_digest: u64 = scalar.digest_u64();
151
152 let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
153 let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
154
155 for j in 0..cols {
156 module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
157 module_test.svp_prepare(&mut svp_test, j, &scalar, j);
158 }
159
160 assert_eq!(scalar.digest_u64(), scalar_digest);
161
162 let svp_ref_digest: u64 = svp_ref.digest_u64();
163 let svp_test_digest: u64 = svp_test.digest_u64();
164
165 for a_size in [3] {
166 // Create a random input VecZnx
167 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
168 a.fill_uniform(basek, &mut source);
169
170 let a_digest: u64 = a.digest_u64();
171
172 let mut a_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, a_size);
173 let mut a_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, a_size);
174
175 for j in 0..cols {
176 module_ref.vec_znx_dft_apply(1, 0, &mut a_dft_ref, j, &a, j);
177 module_test.vec_znx_dft_apply(1, 0, &mut a_dft_test, j, &a, j);
178 }
179
180 assert_eq!(a.digest_u64(), a_digest);
181
182 let a_dft_ref_digest: u64 = a_dft_ref.digest_u64();
183 let a_dft_test_digest: u64 = a_dft_test.digest_u64();
184
185 for res_size in [3] {
186 // Allocate VecZnxDft from FFT64Ref and module to test
187 let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
188 let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
189
190 // Fill output with garbage
191 source.fill_bytes(res_dft_ref.data_mut());
192 source.fill_bytes(res_dft_test.data_mut());
193
194 for j in 0..cols {
195 module_ref.svp_apply_dft_to_dft(&mut res_dft_ref, j, &svp_ref, j, &a_dft_ref, j);
196 module_test.svp_apply_dft_to_dft(&mut res_dft_test, j, &svp_test, j, &a_dft_test, j);
197 }
198
199 // Assert no change to inputs
200 assert_eq!(a_dft_ref.digest_u64(), a_dft_ref_digest);
201 assert_eq!(a_dft_test.digest_u64(), a_dft_test_digest);
202 assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
203 assert_eq!(svp_test.digest_u64(), svp_test_digest);
204 assert_eq!(a.digest_u64(), a_digest);
205
206 let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
207 let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
208
209 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
210 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
211
212 for j in 0..cols {
213 module_ref.vec_znx_big_normalize(
214 basek,
215 &mut res_ref,
216 j,
217 &res_big_ref,
218 j,
219 scratch_ref.borrow(),
220 );
221 module_test.vec_znx_big_normalize(
222 basek,
223 &mut res_test,
224 j,
225 &res_big_test,
226 j,
227 scratch_test.borrow(),
228 );
229 }
230
231 assert_eq!(res_ref, res_test);
232 }
233 }
234}
235
236pub fn test_svp_apply_dft_to_dft_add<BR: Backend, BT: Backend>(basek: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
237where
238 Module<BR>: SvpPrepare<BR>
239 + SvpApplyDftToDftAdd<BR>
240 + SvpPPolAlloc<BR>
241 + VecZnxDftAlloc<BR>
242 + VecZnxBigNormalize<BR>
243 + VecZnxDftApply<BR>
244 + VecZnxIdftApplyConsume<BR>
245 + VecZnxBigNormalizeTmpBytes,
246 Module<BT>: SvpPrepare<BT>
247 + SvpApplyDftToDftAdd<BT>
248 + SvpPPolAlloc<BT>
249 + VecZnxDftAlloc<BT>
250 + VecZnxBigNormalize<BT>
251 + VecZnxDftApply<BT>
252 + VecZnxIdftApplyConsume<BT>
253 + VecZnxBigNormalizeTmpBytes,
254 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
255 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
256{
257 assert_eq!(module_ref.n(), module_test.n());
258 let n: usize = module_ref.n();
259
260 let cols: usize = 2;
261
262 let mut source: Source = Source::new([0u8; 32]);
263
264 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
265 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
266
267 let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
268 scalar.fill_uniform(basek, &mut source);
269
270 let scalar_digest: u64 = scalar.digest_u64();
271
272 let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
273 let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
274
275 for j in 0..cols {
276 module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
277 module_test.svp_prepare(&mut svp_test, j, &scalar, j);
278 }
279
280 assert_eq!(scalar.digest_u64(), scalar_digest);
281
282 let svp_ref_digest: u64 = svp_ref.digest_u64();
283 let svp_test_digest: u64 = svp_test.digest_u64();
284
285 for a_size in [1, 2, 3, 4] {
286 // Create a random input VecZnx
287 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
288 a.fill_uniform(basek, &mut source);
289
290 let a_digest: u64 = a.digest_u64();
291
292 let mut a_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, a_size);
293 let mut a_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, a_size);
294
295 for j in 0..cols {
296 module_ref.vec_znx_dft_apply(1, 0, &mut a_dft_ref, j, &a, j);
297 module_test.vec_znx_dft_apply(1, 0, &mut a_dft_test, j, &a, j);
298 }
299
300 let a_dft_ref_digest: u64 = a_dft_ref.digest_u64();
301 let a_dft_test_digest: u64 = a_dft_test.digest_u64();
302
303 for res_size in [1, 2, 3, 4] {
304 let mut res: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
305 res.fill_uniform(basek, &mut source);
306
307 let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
308 let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
309
310 for j in 0..cols {
311 module_ref.vec_znx_dft_apply(1, 0, &mut res_dft_ref, j, &res, j);
312 module_test.vec_znx_dft_apply(1, 0, &mut res_dft_test, j, &res, j);
313 }
314
315 // Fill output with garbage
316 source.fill_bytes(res_dft_ref.data_mut());
317 source.fill_bytes(res_dft_test.data_mut());
318
319 for j in 0..cols {
320 module_ref.svp_apply_dft_to_dft_add(&mut res_dft_ref, j, &svp_ref, j, &a_dft_ref, j);
321 module_test.svp_apply_dft_to_dft_add(&mut res_dft_test, j, &svp_test, j, &a_dft_test, j);
322 }
323
324 // Assert no change to inputs
325 assert_eq!(a_dft_ref.digest_u64(), a_dft_ref_digest);
326 assert_eq!(a_dft_test.digest_u64(), a_dft_test_digest);
327 assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
328 assert_eq!(svp_test.digest_u64(), svp_test_digest);
329 assert_eq!(a.digest_u64(), a_digest);
330
331 let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
332 let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
333
334 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
335 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
336
337 for j in 0..cols {
338 module_ref.vec_znx_big_normalize(
339 basek,
340 &mut res_ref,
341 j,
342 &res_big_ref,
343 j,
344 scratch_ref.borrow(),
345 );
346 module_test.vec_znx_big_normalize(
347 basek,
348 &mut res_test,
349 j,
350 &res_big_test,
351 j,
352 scratch_test.borrow(),
353 );
354 }
355
356 assert_eq!(res_ref, res_test);
357 }
358 }
359}
360
361pub fn test_svp_apply_dft_to_dft_inplace<BR: Backend, BT: Backend>(
362 basek: usize,
363 module_ref: &Module<BR>,
364 module_test: &Module<BT>,
365) where
366 Module<BR>: SvpPrepare<BR>
367 + SvpApplyDftToDftInplace<BR>
368 + SvpPPolAlloc<BR>
369 + VecZnxDftAlloc<BR>
370 + VecZnxBigNormalize<BR>
371 + VecZnxDftApply<BR>
372 + VecZnxIdftApplyConsume<BR>
373 + VecZnxBigNormalizeTmpBytes,
374 Module<BT>: SvpPrepare<BT>
375 + SvpApplyDftToDftInplace<BT>
376 + SvpPPolAlloc<BT>
377 + VecZnxDftAlloc<BT>
378 + VecZnxBigNormalize<BT>
379 + VecZnxDftApply<BT>
380 + VecZnxIdftApplyConsume<BT>
381 + VecZnxBigNormalizeTmpBytes,
382 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
383 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
384{
385 assert_eq!(module_ref.n(), module_test.n());
386 let n: usize = module_ref.n();
387
388 let cols: usize = 2;
389
390 let mut source: Source = Source::new([0u8; 32]);
391
392 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
393 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
394
395 let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
396 scalar.fill_uniform(basek, &mut source);
397
398 let scalar_digest: u64 = scalar.digest_u64();
399
400 let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
401 let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
402
403 for j in 0..cols {
404 module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
405 module_test.svp_prepare(&mut svp_test, j, &scalar, j);
406 }
407
408 assert_eq!(scalar.digest_u64(), scalar_digest);
409
410 let svp_ref_digest: u64 = svp_ref.digest_u64();
411 let svp_test_digest: u64 = svp_test.digest_u64();
412
413 for res_size in [1, 2, 3, 4] {
414 let mut res: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
415 res.fill_uniform(basek, &mut source);
416 let res_digest: u64 = res.digest_u64();
417
418 let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
419 let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
420
421 for j in 0..cols {
422 module_ref.vec_znx_dft_apply(1, 0, &mut res_dft_ref, j, &res, j);
423 module_test.vec_znx_dft_apply(1, 0, &mut res_dft_test, j, &res, j);
424 }
425
426 assert_eq!(res.digest_u64(), res_digest);
427
428 for j in 0..cols {
429 module_ref.svp_apply_dft_to_dft_inplace(&mut res_dft_ref, j, &svp_ref, j);
430 module_test.svp_apply_dft_to_dft_inplace(&mut res_dft_test, j, &svp_test, j);
431 }
432
433 // Assert no change to inputs
434 assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
435 assert_eq!(svp_test.digest_u64(), svp_test_digest);
436
437 let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
438 let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
439
440 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
441 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
442
443 for j in 0..cols {
444 module_ref.vec_znx_big_normalize(
445 basek,
446 &mut res_ref,
447 j,
448 &res_big_ref,
449 j,
450 scratch_ref.borrow(),
451 );
452 module_test.vec_znx_big_normalize(
453 basek,
454 &mut res_test,
455 j,
456 &res_big_test,
457 j,
458 scratch_test.borrow(),
459 );
460 }
461
462
463
464 assert_eq!(res_ref, res_test);
465 }
466}