arnaucube
arnaucube/poulpyPublic Self-hosted repository
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        assert_eq!(res_ref, res_test);
463    }
464}