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