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