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