arnaucube
arnaucube/poulpyPublic Self-hosted repository
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}