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 println!("res_big_ref: {}", res_big_ref);
210 println!("res_big_test: {}", res_big_test);
211
212 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
213 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
214
215 for j in 0..cols {
216 module_ref.vec_znx_big_normalize(
217 basek,
218 &mut res_ref,
219 j,
220 &res_big_ref,
221 j,
222 scratch_ref.borrow(),
223 );
224 module_test.vec_znx_big_normalize(
225 basek,
226 &mut res_test,
227 j,
228 &res_big_test,
229 j,
230 scratch_test.borrow(),
231 );
232 }
233
234 assert_eq!(res_ref, res_test);
235 }
236 }
237}
238
239pub fn test_svp_apply_dft_to_dft_add<BR: Backend, BT: Backend>(basek: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
240where
241 Module<BR>: SvpPrepare<BR>
242 + SvpApplyDftToDftAdd<BR>
243 + SvpPPolAlloc<BR>
244 + VecZnxDftAlloc<BR>
245 + VecZnxBigNormalize<BR>
246 + VecZnxDftApply<BR>
247 + VecZnxIdftApplyConsume<BR>
248 + VecZnxBigNormalizeTmpBytes,
249 Module<BT>: SvpPrepare<BT>
250 + SvpApplyDftToDftAdd<BT>
251 + SvpPPolAlloc<BT>
252 + VecZnxDftAlloc<BT>
253 + VecZnxBigNormalize<BT>
254 + VecZnxDftApply<BT>
255 + VecZnxIdftApplyConsume<BT>
256 + VecZnxBigNormalizeTmpBytes,
257 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
258 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
259{
260 assert_eq!(module_ref.n(), module_test.n());
261 let n: usize = module_ref.n();
262
263 let cols: usize = 2;
264
265 let mut source: Source = Source::new([0u8; 32]);
266
267 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
268 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
269
270 let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
271 scalar.fill_uniform(basek, &mut source);
272
273 let scalar_digest: u64 = scalar.digest_u64();
274
275 let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
276 let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
277
278 for j in 0..cols {
279 module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
280 module_test.svp_prepare(&mut svp_test, j, &scalar, j);
281 }
282
283 assert_eq!(scalar.digest_u64(), scalar_digest);
284
285 let svp_ref_digest: u64 = svp_ref.digest_u64();
286 let svp_test_digest: u64 = svp_test.digest_u64();
287
288 for a_size in [1, 2, 3, 4] {
289 // Create a random input VecZnx
290 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
291 a.fill_uniform(basek, &mut source);
292
293 let a_digest: u64 = a.digest_u64();
294
295 let mut a_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, a_size);
296 let mut a_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, a_size);
297
298 for j in 0..cols {
299 module_ref.vec_znx_dft_apply(1, 0, &mut a_dft_ref, j, &a, j);
300 module_test.vec_znx_dft_apply(1, 0, &mut a_dft_test, j, &a, j);
301 }
302
303 let a_dft_ref_digest: u64 = a_dft_ref.digest_u64();
304 let a_dft_test_digest: u64 = a_dft_test.digest_u64();
305
306 for res_size in [1, 2, 3, 4] {
307 let mut res: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
308 res.fill_uniform(basek, &mut source);
309
310 let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
311 let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
312
313 for j in 0..cols {
314 module_ref.vec_znx_dft_apply(1, 0, &mut res_dft_ref, j, &res, j);
315 module_test.vec_znx_dft_apply(1, 0, &mut res_dft_test, j, &res, j);
316 }
317
318 // Fill output with garbage
319 source.fill_bytes(res_dft_ref.data_mut());
320 source.fill_bytes(res_dft_test.data_mut());
321
322 for j in 0..cols {
323 module_ref.svp_apply_dft_to_dft_add(&mut res_dft_ref, j, &svp_ref, j, &a_dft_ref, j);
324 module_test.svp_apply_dft_to_dft_add(&mut res_dft_test, j, &svp_test, j, &a_dft_test, j);
325 }
326
327 // Assert no change to inputs
328 assert_eq!(a_dft_ref.digest_u64(), a_dft_ref_digest);
329 assert_eq!(a_dft_test.digest_u64(), a_dft_test_digest);
330 assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
331 assert_eq!(svp_test.digest_u64(), svp_test_digest);
332 assert_eq!(a.digest_u64(), a_digest);
333
334 let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
335 let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
336
337 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
338 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
339
340 for j in 0..cols {
341 module_ref.vec_znx_big_normalize(
342 basek,
343 &mut res_ref,
344 j,
345 &res_big_ref,
346 j,
347 scratch_ref.borrow(),
348 );
349 module_test.vec_znx_big_normalize(
350 basek,
351 &mut res_test,
352 j,
353 &res_big_test,
354 j,
355 scratch_test.borrow(),
356 );
357 }
358
359 assert_eq!(res_ref, res_test);
360 }
361 }
362}
363
364pub fn test_svp_apply_dft_to_dft_inplace<BR: Backend, BT: Backend>(
365 basek: usize,
366 module_ref: &Module<BR>,
367 module_test: &Module<BT>,
368) where
369 Module<BR>: SvpPrepare<BR>
370 + SvpApplyDftToDftInplace<BR>
371 + SvpPPolAlloc<BR>
372 + VecZnxDftAlloc<BR>
373 + VecZnxBigNormalize<BR>
374 + VecZnxDftApply<BR>
375 + VecZnxIdftApplyConsume<BR>
376 + VecZnxBigNormalizeTmpBytes,
377 Module<BT>: SvpPrepare<BT>
378 + SvpApplyDftToDftInplace<BT>
379 + SvpPPolAlloc<BT>
380 + VecZnxDftAlloc<BT>
381 + VecZnxBigNormalize<BT>
382 + VecZnxDftApply<BT>
383 + VecZnxIdftApplyConsume<BT>
384 + VecZnxBigNormalizeTmpBytes,
385 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
386 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
387{
388 assert_eq!(module_ref.n(), module_test.n());
389 let n: usize = module_ref.n();
390
391 let cols: usize = 2;
392
393 let mut source: Source = Source::new([0u8; 32]);
394
395 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
396 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
397
398 let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
399 scalar.fill_uniform(basek, &mut source);
400
401 let scalar_digest: u64 = scalar.digest_u64();
402
403 let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
404 let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
405
406 for j in 0..cols {
407 module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
408 module_test.svp_prepare(&mut svp_test, j, &scalar, j);
409 }
410
411 assert_eq!(scalar.digest_u64(), scalar_digest);
412
413 let svp_ref_digest: u64 = svp_ref.digest_u64();
414 let svp_test_digest: u64 = svp_test.digest_u64();
415
416 for res_size in [1, 2, 3, 4] {
417 let mut res: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
418 res.fill_uniform(basek, &mut source);
419 let res_digest: u64 = res.digest_u64();
420
421 let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
422 let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
423
424 for j in 0..cols {
425 module_ref.vec_znx_dft_apply(1, 0, &mut res_dft_ref, j, &res, j);
426 module_test.vec_znx_dft_apply(1, 0, &mut res_dft_test, j, &res, j);
427 }
428
429 assert_eq!(res.digest_u64(), res_digest);
430
431 for j in 0..cols {
432 module_ref.svp_apply_dft_to_dft_inplace(&mut res_dft_ref, j, &svp_ref, j);
433 module_test.svp_apply_dft_to_dft_inplace(&mut res_dft_test, j, &svp_test, j);
434 }
435
436 // Assert no change to inputs
437 assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
438 assert_eq!(svp_test.digest_u64(), svp_test_digest);
439
440 let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
441 let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
442
443 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
444 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
445
446 for j in 0..cols {
447 module_ref.vec_znx_big_normalize(
448 basek,
449 &mut res_ref,
450 j,
451 &res_big_ref,
452 j,
453 scratch_ref.borrow(),
454 );
455 module_test.vec_znx_big_normalize(
456 basek,
457 &mut res_test,
458 j,
459 &res_big_test,
460 j,
461 scratch_test.borrow(),
462 );
463 }
464
465 println!("res_ref: {}", res_ref);
466 println!("res_test: {}", res_test);
467
468 assert_eq!(res_ref, res_test);
469 }
470}