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