poulpy/poulpy-hal/src/test_suite/vec_znx.rs
poulpy-hal/src/test_suite/vec_znx.rsRaw
1use std::f64::consts::SQRT_2;
2
3use crate::{
4 api::{
5 ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxAdd, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalar,
6 VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxAutomorphismInplace, VecZnxAutomorphismInplaceTmpBytes, VecZnxCopy,
7 VecZnxFillNormal, VecZnxFillUniform, VecZnxLsh, VecZnxLshInplace, VecZnxLshTmpBytes, VecZnxMergeRings,
8 VecZnxMergeRingsTmpBytes, VecZnxMulXpMinusOne, VecZnxMulXpMinusOneInplace, VecZnxMulXpMinusOneInplaceTmpBytes,
9 VecZnxNegate, VecZnxNegateInplace, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxRotate,
10 VecZnxRotateInplace, VecZnxRotateInplaceTmpBytes, VecZnxRsh, VecZnxRshInplace, VecZnxSplitRing, VecZnxSplitRingTmpBytes,
11 VecZnxSub, VecZnxSubInplace, VecZnxSubNegateInplace, VecZnxSubScalar, VecZnxSubScalarInplace, VecZnxSwitchRing,
12 },
13 layouts::{Backend, DigestU64, FillUniform, Module, ScalarZnx, ScratchOwned, VecZnx, ZnxInfos, ZnxView, ZnxViewMut},
14 reference::znx::znx_copy_ref,
15 source::Source,
16};
17
18pub fn test_vec_znx_encode_vec_i64() {
19 let n: usize = 32;
20 let base2k: usize = 17;
21 let size: usize = 5;
22 for k in [1, base2k / 2, size * base2k - 5] {
23 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, 2, size);
24 let mut source = Source::new([0u8; 32]);
25 let raw: &mut [i64] = a.raw_mut();
26 raw.iter_mut().enumerate().for_each(|(i, x)| *x = i as i64);
27 (0..a.cols()).for_each(|col_i| {
28 let mut have: Vec<i64> = vec![i64::default(); n];
29 have.iter_mut().for_each(|x| {
30 if k < 64 {
31 *x = source.next_u64n(1 << k, (1 << k) - 1) as i64;
32 } else {
33 *x = source.next_i64();
34 }
35 });
36 a.encode_vec_i64(base2k, col_i, k, &have);
37 let mut want: Vec<i64> = vec![i64::default(); n];
38 a.decode_vec_i64(base2k, col_i, k, &mut want);
39 assert_eq!(have, want, "{:?} != {:?}", &have, &want);
40 })
41 }
42}
43
44pub fn test_vec_znx_add_scalar<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
45where
46 Module<BR>: VecZnxAddScalar,
47 Module<BT>: VecZnxAddScalar,
48{
49 assert_eq!(module_ref.n(), module_test.n());
50
51 let n: usize = module_ref.n();
52
53 let mut source: Source = Source::new([0u8; 32]);
54 let cols: usize = 2;
55
56 let mut a: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
57 a.fill_uniform(base2k, &mut source);
58 let a_digest = a.digest_u64();
59
60 for a_size in [1, 2, 3, 4] {
61 let mut b: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
62 b.fill_uniform(base2k, &mut source);
63 let b_digest: u64 = b.digest_u64();
64
65 for res_size in [1, 2, 3, 4] {
66 let mut rest_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
67 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
68
69 // Set d to garbage
70 rest_ref.fill_uniform(base2k, &mut source);
71 res_test.fill_uniform(base2k, &mut source);
72
73 // Reference
74 for i in 0..cols {
75 module_ref.vec_znx_add_scalar(&mut rest_ref, i, &a, i, &b, i, (res_size.min(a_size)) - 1);
76 module_test.vec_znx_add_scalar(&mut res_test, i, &a, i, &b, i, (res_size.min(a_size)) - 1);
77 }
78
79 assert_eq!(b.digest_u64(), b_digest);
80 assert_eq!(a.digest_u64(), a_digest);
81 assert_eq!(rest_ref, res_test);
82 }
83 }
84}
85
86pub fn test_vec_znx_add_scalar_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
87where
88 Module<BR>: VecZnxAddScalarInplace,
89 Module<BT>: VecZnxAddScalarInplace,
90{
91 assert_eq!(module_ref.n(), module_test.n());
92
93 let n: usize = module_ref.n();
94
95 let mut source: Source = Source::new([0u8; 32]);
96 let cols: usize = 2;
97
98 let mut b: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
99 b.fill_uniform(base2k, &mut source);
100 let b_digest: u64 = b.digest_u64();
101
102 for res_size in [1, 2, 3, 4] {
103 let mut rest_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
104 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
105
106 rest_ref.fill_uniform(base2k, &mut source);
107 res_test.raw_mut().copy_from_slice(rest_ref.raw());
108
109 for i in 0..cols {
110 module_ref.vec_znx_add_scalar_inplace(&mut rest_ref, i, res_size - 1, &b, i);
111 module_test.vec_znx_add_scalar_inplace(&mut res_test, i, res_size - 1, &b, i);
112 }
113
114 assert_eq!(b.digest_u64(), b_digest);
115 assert_eq!(rest_ref, res_test);
116 }
117}
118pub fn test_vec_znx_add<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
119where
120 Module<BR>: VecZnxAdd,
121 Module<BT>: VecZnxAdd,
122{
123 assert_eq!(module_ref.n(), module_test.n());
124 let n: usize = module_ref.n();
125
126 let mut source: Source = Source::new([0u8; 32]);
127 let cols: usize = 2;
128
129 for a_size in [1, 2, 3, 4] {
130 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
131 a.fill_uniform(base2k, &mut source);
132
133 let a_digest: u64 = a.digest_u64();
134
135 for b_size in [1, 2, 3, 4] {
136 let mut b: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, b_size);
137 b.fill_uniform(base2k, &mut source);
138
139 let b_digest: u64 = b.digest_u64();
140
141 for res_size in [1, 2, 3, 4] {
142 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
143 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
144
145 // Set d to garbage
146 res_ref.fill_uniform(base2k, &mut source);
147 res_test.fill_uniform(base2k, &mut source);
148
149 // Reference
150 for i in 0..cols {
151 module_test.vec_znx_add(&mut res_ref, i, &a, i, &b, i);
152 module_ref.vec_znx_add(&mut res_test, i, &a, i, &b, i);
153 }
154
155 assert_eq!(a.digest_u64(), a_digest);
156 assert_eq!(b.digest_u64(), b_digest);
157
158 assert_eq!(res_ref, res_test);
159 }
160 }
161 }
162}
163
164pub fn test_vec_znx_add_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
165where
166 Module<BR>: VecZnxAddInplace,
167 Module<BT>: VecZnxAddInplace,
168{
169 assert_eq!(module_ref.n(), module_test.n());
170 let n: usize = module_ref.n();
171
172 let mut source: Source = Source::new([0u8; 32]);
173 let cols: usize = 2;
174
175 for a_size in [1, 2, 3, 4] {
176 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
177 a.fill_uniform(base2k, &mut source);
178 let a_digest: u64 = a.digest_u64();
179
180 for res_size in [1, 2, 3, 4] {
181 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
182 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
183
184 res_ref.fill_uniform(base2k, &mut source);
185 res_test.raw_mut().copy_from_slice(res_ref.raw());
186
187 for i in 0..cols {
188 module_ref.vec_znx_add_inplace(&mut res_ref, i, &a, i);
189 module_test.vec_znx_add_inplace(&mut res_test, i, &a, i);
190 }
191
192 assert_eq!(a.digest_u64(), a_digest);
193 assert_eq!(res_ref, res_test);
194 }
195 }
196}
197
198pub fn test_vec_znx_automorphism<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
199where
200 Module<BR>: VecZnxAutomorphism,
201 Module<BT>: VecZnxAutomorphism,
202{
203 assert_eq!(module_ref.n(), module_test.n());
204 let n: usize = module_ref.n();
205
206 let mut source: Source = Source::new([0u8; 32]);
207 let cols: usize = 2;
208
209 for a_size in [1, 2, 3, 4] {
210 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
211 a.fill_uniform(base2k, &mut source);
212 let a_digest: u64 = a.digest_u64();
213
214 for res_size in [1, 2, 3, 4] {
215 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
216 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
217
218 let p: i64 = -5;
219
220 // Normalize on c
221 for i in 0..cols {
222 module_ref.vec_znx_automorphism(p, &mut res_ref, i, &a, i);
223 module_test.vec_znx_automorphism(p, &mut res_test, i, &a, i);
224 }
225
226 assert_eq!(a.digest_u64(), a_digest);
227 assert_eq!(res_ref, res_test);
228
229 let p: i64 = 5;
230
231 // Normalize on c
232 for i in 0..cols {
233 module_ref.vec_znx_automorphism(p, &mut res_ref, i, &a, i);
234 module_test.vec_znx_automorphism(p, &mut res_test, i, &a, i);
235 }
236
237 assert_eq!(a.digest_u64(), a_digest);
238 assert_eq!(res_ref, res_test);
239 }
240 }
241}
242
243pub fn test_vec_znx_automorphism_inplace<BR: Backend, BT: Backend>(
244 base2k: usize,
245 module_ref: &Module<BR>,
246 module_test: &Module<BT>,
247) where
248 Module<BR>: VecZnxAutomorphismInplace<BR> + VecZnxAutomorphismInplaceTmpBytes,
249 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
250 Module<BT>: VecZnxAutomorphismInplace<BT> + VecZnxAutomorphismInplaceTmpBytes,
251 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
252{
253 assert_eq!(module_ref.n(), module_test.n());
254 let n: usize = module_ref.n();
255
256 let mut source: Source = Source::new([0u8; 32]);
257 let cols: usize = 2;
258
259 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_automorphism_inplace_tmp_bytes());
260 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_automorphism_inplace_tmp_bytes());
261
262 for size in [1, 2, 3, 4] {
263 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
264 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
265
266 // Fill a with random i64
267 res_ref.fill_uniform(base2k, &mut source);
268 znx_copy_ref(res_test.raw_mut(), res_ref.raw());
269
270 let p: i64 = -7;
271
272 // Normalize on c
273 for i in 0..cols {
274 module_ref.vec_znx_automorphism_inplace(p, &mut res_ref, i, scratch_ref.borrow());
275 module_test.vec_znx_automorphism_inplace(p, &mut res_test, i, scratch_test.borrow());
276 }
277
278 assert_eq!(res_ref, res_test);
279
280 let p: i64 = 7;
281
282 // Normalize on c
283 for i in 0..cols {
284 module_ref.vec_znx_automorphism_inplace(p, &mut res_ref, i, scratch_ref.borrow());
285 module_test.vec_znx_automorphism_inplace(p, &mut res_test, i, scratch_test.borrow());
286 }
287
288 assert_eq!(res_ref, res_test);
289 }
290}
291
292pub fn test_vec_znx_copy<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
293where
294 Module<BR>: VecZnxCopy,
295 Module<BT>: VecZnxCopy,
296{
297 assert_eq!(module_ref.n(), module_test.n());
298 let n: usize = module_ref.n();
299
300 let mut source: Source = Source::new([0u8; 32]);
301 let cols: usize = 2;
302
303 for a_size in [1, 2, 3, 4] {
304 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
305 a.fill_uniform(base2k, &mut source);
306 let a_digest: u64 = a.digest_u64();
307
308 for res_size in [1, 2, 3, 4] {
309 let mut res_0: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
310 let mut res_1: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
311
312 // Set d to garbage
313 res_0.fill_uniform(base2k, &mut source);
314 res_1.fill_uniform(base2k, &mut source);
315
316 // Reference
317 for i in 0..cols {
318 module_ref.vec_znx_copy(&mut res_0, i, &a, i);
319 module_ref.vec_znx_copy(&mut res_1, i, &a, i);
320 }
321
322 assert_eq!(a.digest_u64(), a_digest);
323 assert_eq!(res_0, res_1);
324 }
325 }
326}
327
328pub fn test_vec_znx_merge_rings<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
329where
330 Module<BR>: VecZnxMergeRings<BR> + ModuleNew<BR> + VecZnxMergeRingsTmpBytes,
331 Module<BT>: VecZnxMergeRings<BT> + ModuleNew<BT> + VecZnxMergeRingsTmpBytes,
332 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
333 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
334{
335 assert_eq!(module_ref.n(), module_test.n());
336 let n: usize = module_ref.n();
337
338 let mut source: Source = Source::new([0u8; 32]);
339 let cols: usize = 2;
340 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_merge_rings_tmp_bytes());
341 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_merge_rings_tmp_bytes());
342
343 for a_size in [1, 2, 3, 4] {
344 let mut a: [VecZnx<Vec<u8>>; 2] = [
345 VecZnx::alloc(n >> 1, cols, a_size),
346 VecZnx::alloc(n >> 1, cols, a_size),
347 ];
348
349 a.iter_mut().for_each(|ai| {
350 ai.fill_uniform(base2k, &mut source);
351 });
352
353 let a_digests: [u64; 2] = [a[0].digest_u64(), a[1].digest_u64()];
354
355 for res_size in [1, 2, 3, 4] {
356 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
357 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
358
359 res_ref.fill_uniform(base2k, &mut source);
360 res_test.fill_uniform(base2k, &mut source);
361
362 for i in 0..cols {
363 module_ref.vec_znx_merge_rings(&mut res_test, i, &a, i, scratch_ref.borrow());
364 module_test.vec_znx_merge_rings(&mut res_ref, i, &a, i, scratch_test.borrow());
365 }
366
367 assert_eq!([a[0].digest_u64(), a[1].digest_u64()], a_digests);
368 assert_eq!(res_ref, res_test);
369 }
370 }
371}
372
373pub fn test_vec_znx_mul_xp_minus_one<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
374where
375 Module<BR>: VecZnxMulXpMinusOne,
376 Module<BT>: VecZnxMulXpMinusOne,
377{
378 assert_eq!(module_ref.n(), module_test.n());
379 let n: usize = module_ref.n();
380
381 let mut source: Source = Source::new([0u8; 32]);
382 let cols: usize = 2;
383
384 for a_size in [1, 2, 3, 4] {
385 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
386 a.fill_uniform(base2k, &mut source);
387
388 let a_digest: u64 = a.digest_u64();
389
390 for res_size in [1, 2, 3, 4] {
391 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
392 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
393
394 let p: i64 = -5;
395
396 // Normalize on c
397 for i in 0..cols {
398 module_ref.vec_znx_mul_xp_minus_one(p, &mut res_ref, i, &a, i);
399 module_test.vec_znx_mul_xp_minus_one(p, &mut res_test, i, &a, i);
400 }
401
402 assert_eq!(a.digest_u64(), a_digest);
403 assert_eq!(res_test, res_ref);
404
405 let p: i64 = 5;
406
407 // Normalize on c
408 for i in 0..cols {
409 module_ref.vec_znx_mul_xp_minus_one(p, &mut res_ref, i, &a, i);
410 module_test.vec_znx_mul_xp_minus_one(p, &mut res_test, i, &a, i);
411 }
412
413 assert_eq!(a.digest_u64(), a_digest);
414 assert_eq!(res_test, res_ref);
415 }
416 }
417}
418
419pub fn test_vec_znx_mul_xp_minus_one_inplace<BR: Backend, BT: Backend>(
420 base2k: usize,
421 module_ref: &Module<BR>,
422 module_test: &Module<BT>,
423) where
424 Module<BR>: VecZnxMulXpMinusOneInplace<BR> + VecZnxMulXpMinusOneInplaceTmpBytes,
425 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
426 Module<BT>: VecZnxMulXpMinusOneInplace<BT> + VecZnxMulXpMinusOneInplaceTmpBytes,
427 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
428{
429 assert_eq!(module_ref.n(), module_test.n());
430 let n: usize = module_ref.n();
431
432 let mut source: Source = Source::new([0u8; 32]);
433 let cols: usize = 2;
434
435 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_mul_xp_minus_one_inplace_tmp_bytes());
436 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_mul_xp_minus_one_inplace_tmp_bytes());
437
438 for size in [1, 2, 3, 4] {
439 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
440 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
441
442 // Fill a with random i64
443 res_ref.fill_uniform(base2k, &mut source);
444 znx_copy_ref(res_test.raw_mut(), res_ref.raw());
445
446 let p: i64 = -7;
447
448 for i in 0..cols {
449 module_ref.vec_znx_mul_xp_minus_one_inplace(p, &mut res_ref, i, scratch_ref.borrow());
450 module_test.vec_znx_mul_xp_minus_one_inplace(p, &mut res_test, i, scratch_test.borrow());
451 }
452
453 assert_eq!(res_ref, res_test);
454
455 let p: i64 = 7;
456
457 for i in 0..cols {
458 module_ref.vec_znx_mul_xp_minus_one_inplace(p, &mut res_ref, i, scratch_ref.borrow());
459 module_test.vec_znx_mul_xp_minus_one_inplace(p, &mut res_test, i, scratch_test.borrow());
460 }
461
462 assert_eq!(res_ref, res_test);
463 }
464}
465
466pub fn test_vec_znx_negate<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
467where
468 Module<BR>: VecZnxNegate,
469 Module<BT>: VecZnxNegate,
470{
471 assert_eq!(module_ref.n(), module_test.n());
472 let n: usize = module_ref.n();
473
474 let mut source: Source = Source::new([0u8; 32]);
475 let cols: usize = 2;
476
477 for a_size in [1, 2, 3, 4] {
478 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
479 a.fill_uniform(base2k, &mut source);
480 let a_digest: u64 = a.digest_u64();
481
482 for res_size in [1, 2, 3, 4] {
483 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
484 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
485
486 res_ref.fill_uniform(base2k, &mut source);
487 res_test.raw_mut().copy_from_slice(res_ref.raw());
488
489 for i in 0..cols {
490 module_ref.vec_znx_negate(&mut res_ref, i, &a, i);
491 module_test.vec_znx_negate(&mut res_test, i, &a, i);
492 }
493
494 assert_eq!(a.digest_u64(), a_digest);
495 assert_eq!(res_ref, res_test);
496 }
497 }
498}
499
500pub fn test_vec_znx_negate_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
501where
502 Module<BR>: VecZnxNegateInplace,
503 Module<BT>: VecZnxNegateInplace,
504{
505 assert_eq!(module_ref.n(), module_test.n());
506 let n: usize = module_ref.n();
507
508 let mut source: Source = Source::new([0u8; 32]);
509 let cols: usize = 2;
510
511 for res_size in [1, 2, 3, 4] {
512 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
513 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
514
515 res_ref.fill_uniform(base2k, &mut source);
516 res_test.raw_mut().copy_from_slice(res_ref.raw());
517
518 for i in 0..cols {
519 module_ref.vec_znx_negate_inplace(&mut res_ref, i);
520 module_test.vec_znx_negate_inplace(&mut res_test, i);
521 }
522
523 assert_eq!(res_ref, res_test);
524 }
525}
526
527pub fn test_vec_znx_normalize<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
528where
529 Module<BR>: VecZnxNormalize<BR> + VecZnxNormalizeTmpBytes,
530 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
531 Module<BT>: VecZnxNormalize<BT> + VecZnxNormalizeTmpBytes,
532 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
533{
534 assert_eq!(module_ref.n(), module_test.n());
535 let n: usize = module_ref.n();
536
537 let mut source: Source = Source::new([0u8; 32]);
538 let cols: usize = 2;
539
540 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_normalize_tmp_bytes());
541 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_normalize_tmp_bytes());
542
543 for a_size in [1, 2, 3, 4] {
544 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
545 a.fill_uniform(base2k, &mut source);
546 let a_digest: u64 = a.digest_u64();
547
548 for res_size in [1, 2, 3, 4] {
549 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
550 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
551
552 // Set d to garbage
553 res_ref.fill_uniform(base2k, &mut source);
554 res_test.fill_uniform(base2k, &mut source);
555
556 // Reference
557 for i in 0..cols {
558 module_ref.vec_znx_normalize(base2k, &mut res_ref, i, base2k, &a, i, scratch_ref.borrow());
559 module_test.vec_znx_normalize(
560 base2k,
561 &mut res_test,
562 i,
563 base2k,
564 &a,
565 i,
566 scratch_test.borrow(),
567 );
568 }
569
570 assert_eq!(a.digest_u64(), a_digest);
571 assert_eq!(res_ref, res_test);
572 }
573 }
574}
575
576pub fn test_vec_znx_normalize_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
577where
578 Module<BR>: VecZnxNormalizeInplace<BR> + VecZnxNormalizeTmpBytes,
579 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
580 Module<BT>: VecZnxNormalizeInplace<BT> + VecZnxNormalizeTmpBytes,
581 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
582{
583 assert_eq!(module_ref.n(), module_test.n());
584 let n: usize = module_ref.n();
585
586 let mut source: Source = Source::new([0u8; 32]);
587 let cols: usize = 2;
588
589 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_normalize_tmp_bytes());
590 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_normalize_tmp_bytes());
591
592 for res_size in [1, 2, 3, 4] {
593 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
594 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
595
596 res_ref.fill_uniform(base2k, &mut source);
597 res_test.raw_mut().copy_from_slice(res_ref.raw());
598
599 // Reference
600 for i in 0..cols {
601 module_ref.vec_znx_normalize_inplace(base2k, &mut res_ref, i, scratch_ref.borrow());
602 module_test.vec_znx_normalize_inplace(base2k, &mut res_test, i, scratch_test.borrow());
603 }
604
605 assert_eq!(res_ref, res_test);
606 }
607}
608
609pub fn test_vec_znx_rotate<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
610where
611 Module<BR>: VecZnxRotate,
612 Module<BT>: VecZnxRotate,
613{
614 assert_eq!(module_ref.n(), module_test.n());
615 let n: usize = module_ref.n();
616
617 let mut source: Source = Source::new([0u8; 32]);
618 let cols: usize = 2;
619
620 for a_size in [1, 2, 3, 4] {
621 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
622 a.fill_uniform(base2k, &mut source);
623 let a_digest: u64 = a.digest_u64();
624
625 for res_size in [1, 2, 3, 4] {
626 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
627 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
628
629 let p: i64 = -5;
630
631 // Normalize on c
632 for i in 0..cols {
633 module_ref.vec_znx_rotate(p, &mut res_ref, i, &a, i);
634 module_test.vec_znx_rotate(p, &mut res_test, i, &a, i);
635 }
636
637 assert_eq!(a.digest_u64(), a_digest);
638 assert_eq!(res_ref, res_test);
639
640 let p: i64 = 5;
641
642 // Normalize on c
643 for i in 0..cols {
644 module_ref.vec_znx_rotate(p, &mut res_ref, i, &a, i);
645 module_test.vec_znx_rotate(p, &mut res_test, i, &a, i);
646 }
647
648 assert_eq!(a.digest_u64(), a_digest);
649 assert_eq!(res_ref, res_test);
650 }
651 }
652}
653
654pub fn test_vec_znx_rotate_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
655where
656 Module<BR>: VecZnxRotateInplace<BR> + VecZnxRotateInplaceTmpBytes,
657 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
658 Module<BT>: VecZnxRotateInplace<BT> + VecZnxRotateInplaceTmpBytes,
659 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
660{
661 assert_eq!(module_ref.n(), module_test.n());
662 let n: usize = module_ref.n();
663
664 let mut source: Source = Source::new([0u8; 32]);
665 let cols: usize = 2;
666
667 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_rotate_inplace_tmp_bytes());
668 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_rotate_inplace_tmp_bytes());
669
670 for size in [1, 2, 3, 4] {
671 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
672 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
673
674 // Fill a with random i64
675 res_ref.fill_uniform(base2k, &mut source);
676 znx_copy_ref(res_test.raw_mut(), res_ref.raw());
677
678 let p: i64 = -5;
679
680 // Normalize on c
681 for i in 0..cols {
682 module_ref.vec_znx_rotate_inplace(p, &mut res_ref, i, scratch_ref.borrow());
683 module_test.vec_znx_rotate_inplace(p, &mut res_test, i, scratch_test.borrow());
684 }
685
686 assert_eq!(res_ref, res_test);
687
688 let p: i64 = 5;
689
690 // Normalize on c
691 for i in 0..cols {
692 module_ref.vec_znx_rotate_inplace(p, &mut res_ref, i, scratch_ref.borrow());
693 module_test.vec_znx_rotate_inplace(p, &mut res_test, i, scratch_test.borrow());
694 }
695
696 assert_eq!(res_ref, res_test);
697 }
698}
699
700pub fn test_vec_znx_fill_uniform<B: Backend>(module: &Module<B>)
701where
702 Module<B>: VecZnxFillUniform,
703{
704 let n: usize = module.n();
705 let base2k: usize = 17;
706 let size: usize = 5;
707 let mut source: Source = Source::new([0u8; 32]);
708 let cols: usize = 2;
709 let zero: Vec<i64> = vec![0; n];
710 let one_12_sqrt: f64 = 0.28867513459481287;
711 (0..cols).for_each(|col_i| {
712 let mut a: VecZnx<_> = VecZnx::alloc(n, cols, size);
713 module.vec_znx_fill_uniform(base2k, &mut a, col_i, &mut source);
714 (0..cols).for_each(|col_j| {
715 if col_j != col_i {
716 (0..size).for_each(|limb_i| {
717 assert_eq!(a.at(col_j, limb_i), zero);
718 })
719 } else {
720 let std: f64 = a.stats(base2k, col_i).std();
721 assert!(
722 (std - one_12_sqrt).abs() < 0.01,
723 "std={std} ~!= {one_12_sqrt}",
724 );
725 }
726 })
727 });
728}
729
730pub fn test_vec_znx_fill_normal<B: Backend>(module: &Module<B>)
731where
732 Module<B>: VecZnxFillNormal,
733{
734 let n: usize = module.n();
735 let base2k: usize = 17;
736 let k: usize = 2 * 17;
737 let size: usize = 5;
738 let sigma: f64 = 3.2;
739 let bound: f64 = 6.0 * sigma;
740 let mut source: Source = Source::new([0u8; 32]);
741 let cols: usize = 2;
742 let zero: Vec<i64> = vec![0; n];
743 let k_f64: f64 = (1u64 << k as u64) as f64;
744 (0..cols).for_each(|col_i| {
745 let mut a: VecZnx<_> = VecZnx::alloc(n, cols, size);
746 module.vec_znx_fill_normal(base2k, &mut a, col_i, k, &mut source, sigma, bound);
747 (0..cols).for_each(|col_j| {
748 if col_j != col_i {
749 (0..size).for_each(|limb_i| {
750 assert_eq!(a.at(col_j, limb_i), zero);
751 })
752 } else {
753 let std: f64 = a.stats(base2k, col_i).std() * k_f64;
754 assert!((std - sigma).abs() < 0.1, "std={std} ~!= {sigma}");
755 }
756 })
757 });
758}
759
760pub fn test_vec_znx_add_normal<B: Backend>(module: &Module<B>)
761where
762 Module<B>: VecZnxFillNormal + VecZnxAddNormal,
763{
764 let n: usize = module.n();
765 let base2k: usize = 17;
766 let k: usize = 2 * 17;
767 let size: usize = 5;
768 let sigma: f64 = 3.2;
769 let bound: f64 = 6.0 * sigma;
770 let mut source: Source = Source::new([0u8; 32]);
771 let cols: usize = 2;
772 let zero: Vec<i64> = vec![0; n];
773 let k_f64: f64 = (1u64 << k as u64) as f64;
774 let sqrt2: f64 = SQRT_2;
775 (0..cols).for_each(|col_i| {
776 let mut a: VecZnx<_> = VecZnx::alloc(n, cols, size);
777 module.vec_znx_fill_normal(base2k, &mut a, col_i, k, &mut source, sigma, bound);
778 module.vec_znx_add_normal(base2k, &mut a, col_i, k, &mut source, sigma, bound);
779 (0..cols).for_each(|col_j| {
780 if col_j != col_i {
781 (0..size).for_each(|limb_i| {
782 assert_eq!(a.at(col_j, limb_i), zero);
783 })
784 } else {
785 let std: f64 = a.stats(base2k, col_i).std() * k_f64;
786 assert!(
787 (std - sigma * sqrt2).abs() < 0.1,
788 "std={std} ~!= {}",
789 sigma * sqrt2
790 );
791 }
792 })
793 });
794}
795
796pub fn test_vec_znx_lsh<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
797where
798 Module<BR>: VecZnxLsh<BR> + VecZnxLshTmpBytes,
799 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
800 Module<BT>: VecZnxLsh<BT> + VecZnxLshTmpBytes,
801 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
802{
803 assert_eq!(module_ref.n(), module_test.n());
804 let n: usize = module_ref.n();
805
806 let mut source: Source = Source::new([0u8; 32]);
807 let cols: usize = 2;
808
809 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_lsh_tmp_bytes());
810 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_lsh_tmp_bytes());
811
812 for a_size in [1, 2, 3, 4] {
813 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
814 a.fill_uniform(base2k, &mut source);
815 let a_digest: u64 = a.digest_u64();
816
817 for res_size in [1, 2, 3, 4] {
818 for k in 0..res_size * base2k {
819 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
820 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
821
822 // Set d to garbage
823 res_ref.fill_uniform(base2k, &mut source);
824 res_test.fill_uniform(base2k, &mut source);
825
826 // Reference
827 for i in 0..cols {
828 module_ref.vec_znx_lsh(base2k, k, &mut res_ref, i, &a, i, scratch_ref.borrow());
829 module_test.vec_znx_lsh(base2k, k, &mut res_test, i, &a, i, scratch_test.borrow());
830 }
831
832 assert_eq!(a.digest_u64(), a_digest);
833 assert_eq!(res_ref, res_test);
834 }
835 }
836 }
837}
838
839pub fn test_vec_znx_lsh_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
840where
841 Module<BR>: VecZnxLshInplace<BR> + VecZnxLshTmpBytes,
842 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
843 Module<BT>: VecZnxLshInplace<BT> + VecZnxLshTmpBytes,
844 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
845{
846 assert_eq!(module_ref.n(), module_test.n());
847 let n: usize = module_ref.n();
848
849 let mut source: Source = Source::new([0u8; 32]);
850 let cols: usize = 2;
851
852 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_lsh_tmp_bytes());
853 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_lsh_tmp_bytes());
854
855 for res_size in [1, 2, 3, 4] {
856 for k in 0..base2k * res_size {
857 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
858 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
859
860 res_ref.fill_uniform(base2k, &mut source);
861 res_test.raw_mut().copy_from_slice(res_ref.raw());
862
863 for i in 0..cols {
864 module_ref.vec_znx_lsh_inplace(base2k, k, &mut res_ref, i, scratch_ref.borrow());
865 module_test.vec_znx_lsh_inplace(base2k, k, &mut res_test, i, scratch_test.borrow());
866 }
867
868 assert_eq!(res_ref, res_test);
869 }
870 }
871}
872
873pub fn test_vec_znx_rsh<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
874where
875 Module<BR>: VecZnxRsh<BR> + VecZnxLshTmpBytes,
876 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
877 Module<BT>: VecZnxRsh<BT> + VecZnxLshTmpBytes,
878 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
879{
880 assert_eq!(module_ref.n(), module_test.n());
881 let n: usize = module_ref.n();
882 let mut source: Source = Source::new([0u8; 32]);
883 let cols: usize = 2;
884
885 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_lsh_tmp_bytes());
886 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_lsh_tmp_bytes());
887
888 for a_size in [1, 2, 3, 4] {
889 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
890 a.fill_uniform(base2k, &mut source);
891 let a_digest: u64 = a.digest_u64();
892
893 for res_size in [1, 2, 3, 4] {
894 for k in 0..res_size * base2k {
895 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
896 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
897
898 // Set d to garbage
899 res_ref.fill_uniform(base2k, &mut source);
900 res_test.fill_uniform(base2k, &mut source);
901
902 // Reference
903 for i in 0..cols {
904 module_ref.vec_znx_rsh(base2k, k, &mut res_ref, i, &a, i, scratch_ref.borrow());
905 module_test.vec_znx_rsh(base2k, k, &mut res_test, i, &a, i, scratch_test.borrow());
906 }
907
908 assert_eq!(a.digest_u64(), a_digest);
909 assert_eq!(res_ref, res_test);
910 }
911 }
912 }
913}
914
915pub fn test_vec_znx_rsh_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
916where
917 Module<BR>: VecZnxRshInplace<BR> + VecZnxLshTmpBytes,
918 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
919 Module<BT>: VecZnxRshInplace<BT> + VecZnxLshTmpBytes,
920 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
921{
922 assert_eq!(module_ref.n(), module_test.n());
923 let n: usize = module_ref.n();
924 let mut source: Source = Source::new([0u8; 32]);
925 let cols: usize = 2;
926
927 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_lsh_tmp_bytes());
928 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_lsh_tmp_bytes());
929
930 for res_size in [1, 2, 3, 4] {
931 for k in 0..base2k * res_size {
932 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
933 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
934
935 res_ref.fill_uniform(base2k, &mut source);
936 res_test.raw_mut().copy_from_slice(res_ref.raw());
937
938 for i in 0..cols {
939 module_ref.vec_znx_rsh_inplace(base2k, k, &mut res_ref, i, scratch_ref.borrow());
940 module_test.vec_znx_rsh_inplace(base2k, k, &mut res_test, i, scratch_test.borrow());
941 }
942
943 assert_eq!(res_ref, res_test);
944 }
945 }
946}
947
948pub fn test_vec_znx_split_ring<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
949where
950 Module<BR>: VecZnxSplitRing<BR> + ModuleNew<BR> + VecZnxSplitRingTmpBytes,
951 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
952 Module<BT>: VecZnxSplitRing<BT> + ModuleNew<BT> + VecZnxSplitRingTmpBytes,
953 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
954{
955 assert_eq!(module_ref.n(), module_test.n());
956 let n: usize = module_ref.n();
957
958 let mut source: Source = Source::new([0u8; 32]);
959 let cols: usize = 2;
960 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_split_ring_tmp_bytes());
961 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_split_ring_tmp_bytes());
962
963 for a_size in [1, 2, 3, 4] {
964 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
965 a.fill_uniform(base2k, &mut source);
966 let a_digest = a.digest_u64();
967
968 for res_size in [1, 2, 3, 4] {
969 let mut res_ref: [VecZnx<Vec<u8>>; 2] = [
970 VecZnx::alloc(n >> 1, cols, res_size),
971 VecZnx::alloc(n >> 1, cols, res_size),
972 ];
973
974 let mut res_test: [VecZnx<Vec<u8>>; 2] = [
975 VecZnx::alloc(n >> 1, cols, res_size),
976 VecZnx::alloc(n >> 1, cols, res_size),
977 ];
978
979 res_ref.iter_mut().for_each(|ri| {
980 ri.fill_uniform(base2k, &mut source);
981 });
982
983 res_test.iter_mut().for_each(|ri| {
984 ri.fill_uniform(base2k, &mut source);
985 });
986
987 for i in 0..cols {
988 module_ref.vec_znx_split_ring(&mut res_ref, i, &a, i, scratch_ref.borrow());
989 module_test.vec_znx_split_ring(&mut res_test, i, &a, i, scratch_test.borrow());
990 }
991
992 assert_eq!(a.digest_u64(), a_digest);
993
994 for (a, b) in res_ref.iter().zip(res_test.iter()) {
995 assert_eq!(a, b);
996 }
997 }
998 }
999}
1000
1001pub fn test_vec_znx_sub_scalar<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
1002where
1003 Module<BR>: VecZnxSubScalar,
1004 Module<BT>: VecZnxSubScalar,
1005{
1006 assert_eq!(module_ref.n(), module_test.n());
1007 let n: usize = module_ref.n();
1008
1009 let mut source: Source = Source::new([0u8; 32]);
1010 let cols: usize = 2;
1011
1012 let mut a: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
1013 a.fill_uniform(base2k, &mut source);
1014 let a_digest: u64 = a.digest_u64();
1015
1016 for b_size in [1, 2, 3, 4] {
1017 let mut b: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, b_size);
1018 b.fill_uniform(base2k, &mut source);
1019 let b_digest: u64 = b.digest_u64();
1020
1021 for res_size in [1, 2, 3, 4] {
1022 let mut res_0: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1023 let mut res_1: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1024
1025 // Set d to garbage
1026 res_0.fill_uniform(base2k, &mut source);
1027 res_1.fill_uniform(base2k, &mut source);
1028
1029 // Reference
1030 for i in 0..cols {
1031 module_ref.vec_znx_sub_scalar(&mut res_0, i, &a, i, &b, i, (res_size.min(b_size)) - 1);
1032 module_test.vec_znx_sub_scalar(&mut res_1, i, &a, i, &b, i, (res_size.min(b_size)) - 1);
1033 }
1034
1035 assert_eq!(a.digest_u64(), a_digest);
1036 assert_eq!(b.digest_u64(), b_digest);
1037 assert_eq!(res_0, res_1);
1038 }
1039 }
1040}
1041
1042pub fn test_vec_znx_sub_scalar_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
1043where
1044 Module<BR>: VecZnxSubScalarInplace,
1045 Module<BT>: VecZnxSubScalarInplace,
1046{
1047 assert_eq!(module_ref.n(), module_test.n());
1048 let n: usize = module_ref.n();
1049
1050 let mut source: Source = Source::new([0u8; 32]);
1051 let cols: usize = 2;
1052
1053 let mut a: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
1054 a.fill_uniform(base2k, &mut source);
1055 let a_digest: u64 = a.digest_u64();
1056
1057 for res_size in [1, 2, 3, 4] {
1058 let mut res_0: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1059 let mut res_1: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1060
1061 res_0.fill_uniform(base2k, &mut source);
1062 res_1.raw_mut().copy_from_slice(res_0.raw());
1063
1064 for i in 0..cols {
1065 module_ref.vec_znx_sub_scalar_inplace(&mut res_0, i, res_size - 1, &a, i);
1066 module_test.vec_znx_sub_scalar_inplace(&mut res_1, i, res_size - 1, &a, i);
1067 }
1068
1069 assert_eq!(a.digest_u64(), a_digest);
1070 assert_eq!(res_0, res_1);
1071 }
1072}
1073
1074pub fn test_vec_znx_sub<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
1075where
1076 Module<BR>: VecZnxSub,
1077 Module<BT>: VecZnxSub,
1078{
1079 assert_eq!(module_ref.n(), module_test.n());
1080 let n: usize = module_ref.n();
1081
1082 let mut source: Source = Source::new([0u8; 32]);
1083 let cols: usize = 2;
1084
1085 for a_size in [1, 2, 3, 4] {
1086 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
1087 a.fill_uniform(base2k, &mut source);
1088 let a_digest: u64 = a.digest_u64();
1089
1090 for b_size in [1, 2, 3, 4] {
1091 let mut b: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, b_size);
1092 b.fill_uniform(base2k, &mut source);
1093 let b_digest: u64 = b.digest_u64();
1094
1095 for res_size in [1, 2, 3, 4] {
1096 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1097 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1098
1099 // Set d to garbage
1100 res_ref.fill_uniform(base2k, &mut source);
1101 res_test.fill_uniform(base2k, &mut source);
1102
1103 // Reference
1104 for i in 0..cols {
1105 module_test.vec_znx_sub(&mut res_ref, i, &a, i, &b, i);
1106 module_ref.vec_znx_sub(&mut res_test, i, &a, i, &b, i);
1107 }
1108
1109 assert_eq!(a.digest_u64(), a_digest);
1110 assert_eq!(b.digest_u64(), b_digest);
1111
1112 assert_eq!(res_ref, res_test);
1113 }
1114 }
1115 }
1116}
1117
1118pub fn test_vec_znx_sub_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
1119where
1120 Module<BR>: VecZnxSubInplace,
1121 Module<BT>: VecZnxSubInplace,
1122{
1123 assert_eq!(module_ref.n(), module_test.n());
1124 let n: usize = module_ref.n();
1125
1126 let mut source: Source = Source::new([0u8; 32]);
1127 let cols: usize = 2;
1128
1129 for a_size in [1, 2, 3, 4] {
1130 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
1131 a.fill_uniform(base2k, &mut source);
1132 let a_digest: u64 = a.digest_u64();
1133
1134 for res_size in [1, 2, 3, 4] {
1135 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1136 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1137
1138 res_ref.fill_uniform(base2k, &mut source);
1139 res_test.raw_mut().copy_from_slice(res_ref.raw());
1140
1141 for i in 0..cols {
1142 module_test.vec_znx_sub_inplace(&mut res_ref, i, &a, i);
1143 module_ref.vec_znx_sub_inplace(&mut res_test, i, &a, i);
1144 }
1145
1146 assert_eq!(a.digest_u64(), a_digest);
1147 assert_eq!(res_ref, res_test);
1148 }
1149 }
1150}
1151
1152pub fn test_vec_znx_sub_negate_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
1153where
1154 Module<BR>: VecZnxSubNegateInplace,
1155 Module<BT>: VecZnxSubNegateInplace,
1156{
1157 assert_eq!(module_ref.n(), module_test.n());
1158 let n: usize = module_ref.n();
1159
1160 let mut source: Source = Source::new([0u8; 32]);
1161 let cols: usize = 2;
1162
1163 for a_size in [1, 2, 3, 4] {
1164 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
1165 a.fill_uniform(base2k, &mut source);
1166 let a_digest: u64 = a.digest_u64();
1167
1168 for res_size in [1, 2, 3, 4] {
1169 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1170 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1171
1172 res_ref.fill_uniform(base2k, &mut source);
1173 res_test.raw_mut().copy_from_slice(res_ref.raw());
1174
1175 for i in 0..cols {
1176 module_test.vec_znx_sub_negate_inplace(&mut res_ref, i, &a, i);
1177 module_ref.vec_znx_sub_negate_inplace(&mut res_test, i, &a, i);
1178 }
1179
1180 assert_eq!(a.digest_u64(), a_digest);
1181 assert_eq!(res_ref, res_test);
1182 }
1183 }
1184}
1185
1186pub fn test_vec_znx_switch_ring<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
1187where
1188 Module<BR>: VecZnxSwitchRing,
1189 Module<BT>: VecZnxSwitchRing,
1190{
1191 assert_eq!(module_ref.n(), module_test.n());
1192 let n: usize = module_ref.n();
1193
1194 let mut source: Source = Source::new([0u8; 32]);
1195 let cols: usize = 2;
1196
1197 for a_size in [1, 2, 3, 4] {
1198 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
1199
1200 // Fill a with random i64
1201 a.fill_uniform(base2k, &mut source);
1202 let a_digest: u64 = a.digest_u64();
1203
1204 for res_size in [1, 2, 3, 4] {
1205 {
1206 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n << 1, cols, res_size);
1207 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n << 1, cols, res_size);
1208
1209 res_ref.fill_uniform(base2k, &mut source);
1210 res_test.fill_uniform(base2k, &mut source);
1211
1212 // Normalize on c
1213 for i in 0..cols {
1214 module_ref.vec_znx_switch_ring(&mut res_ref, i, &a, i);
1215 module_test.vec_znx_switch_ring(&mut res_test, i, &a, i);
1216 }
1217
1218 assert_eq!(a.digest_u64(), a_digest);
1219 assert_eq!(res_ref, res_test);
1220 }
1221
1222 {
1223 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n >> 1, cols, res_size);
1224 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n >> 1, cols, res_size);
1225
1226 res_ref.fill_uniform(base2k, &mut source);
1227 res_test.fill_uniform(base2k, &mut source);
1228
1229 // Normalize on c
1230 for i in 0..cols {
1231 module_ref.vec_znx_switch_ring(&mut res_ref, i, &a, i);
1232 module_test.vec_znx_switch_ring(&mut res_test, i, &a, i);
1233 }
1234
1235 assert_eq!(a.digest_u64(), a_digest);
1236 assert_eq!(res_ref, res_test);
1237 }
1238 }
1239 }
1240}