arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/rns/tests/ring_switch.rs
rns/tests/ring_switch.rsRaw
 1use rns::poly::Poly;
 2use rns::ring::Ring;
 3
 4#[test]
 5fn ring_switch_u64() {
 6    let n: usize = 1 << 4;
 7    let q_base: u64 = 65537u64;
 8    let q_power: usize = 1usize;
 9    let ring_small: Ring<u64> = Ring::new(n, q_base, q_power);
10    let ring_large = Ring::new(2 * n, q_base, q_power);
11
12    sub_test("test_ring_switch_small_to_large_u64::<NTT:false>", || {
13        test_ring_switch_small_to_large_u64::<false>(&ring_small, &ring_large)
14    });
15    sub_test("test_ring_switch_small_to_large_u64::<NTT:true>", || {
16        test_ring_switch_small_to_large_u64::<true>(&ring_small, &ring_large)
17    });
18    sub_test("test_ring_switch_large_to_small_u64::<NTT:false>", || {
19        test_ring_switch_large_to_small_u64::<false>(&ring_small, &ring_large)
20    });
21    sub_test("test_ring_switch_large_to_small_u64::<NTT:true>", || {
22        test_ring_switch_large_to_small_u64::<true>(&ring_small, &ring_large)
23    });
24}
25
26fn sub_test<F: FnOnce()>(name: &str, f: F) {
27    println!("Running {}", name);
28    f();
29}
30
31fn test_ring_switch_small_to_large_u64<const NTT: bool>(
32    ring_small: &Ring<u64>,
33    ring_large: &Ring<u64>,
34) {
35    let mut a: Poly<u64> = ring_small.new_poly();
36    let mut buf: Poly<u64> = ring_small.new_poly();
37    let mut b: Poly<u64> = ring_large.new_poly();
38
39    a.0.iter_mut().enumerate().for_each(|(i, x)| *x = i as u64);
40
41    if NTT {
42        ring_small.ntt_inplace::<false>(&mut a);
43    }
44
45    ring_large.switch_degree::<NTT>(&a, &mut buf, &mut b);
46
47    if NTT {
48        ring_small.intt_inplace::<false>(&mut a);
49        ring_large.intt_inplace::<false>(&mut b);
50    }
51
52    let gap: usize = ring_large.n() / ring_small.n();
53
54    b.0.iter()
55        .step_by(gap)
56        .zip(a.0.iter())
57        .for_each(|(x_out, x_in)| assert_eq!(x_out, x_in));
58}
59
60fn test_ring_switch_large_to_small_u64<const NTT: bool>(
61    ring_small: &Ring<u64>,
62    ring_large: &Ring<u64>,
63) {
64    let mut a: Poly<u64> = ring_large.new_poly();
65    let mut buf: Poly<u64> = ring_large.new_poly();
66    let mut b: Poly<u64> = ring_small.new_poly();
67
68    a.0.iter_mut().enumerate().for_each(|(i, x)| *x = i as u64);
69
70    if NTT {
71        ring_large.ntt_inplace::<false>(&mut a);
72    }
73
74    ring_large.switch_degree::<NTT>(&a, &mut buf, &mut b);
75
76    if NTT {
77        ring_large.intt_inplace::<false>(&mut a);
78        ring_small.intt_inplace::<false>(&mut b);
79    }
80
81    let gap: usize = ring_large.n() / ring_small.n();
82
83    a.0.iter()
84        .step_by(gap)
85        .zip(b.0.iter())
86        .for_each(|(x_out, x_in)| assert_eq!(x_out, x_in));
87}