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>(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}