Skip to main content

simple_ring/
lib.rs

1pub mod ring;
2pub mod ntt;
3pub mod polys;
4pub mod modular;
5pub mod sampling;
6
7pub use ring::RingParams as RingParams;
8pub use polys::Polynomial as Polynomial;
9pub use modular::{find_valid_omega, is_q_valid, mod_pow, is_prime};
10pub use sampling::{generate_small_sample, generate_cbd_sample, generate_uniform_polynomial};
11pub use ntt::{forward_ntt, inverse_ntt, precalculate};
12#[cfg(test)]
13#[test]
14fn test_polynomials() {
15    let params = RingParams::new(4, 17, find_valid_omega(4, 17)); //We define the parameters
16    let ntt_tables = &precalculate(&params);
17    let mut coeffs = vec![0u64; 4]; //We create the coefficients for our first polynomial
18    coeffs[3] = 8;
19    let poly1 = Polynomial::new(coeffs.clone()); //We create the first polynomial as P1 = [0, 0, 0, 8]
20    let poly2 = Polynomial::zeros(4); //We create an empty polynomial, which will be the second one.
21    let sum = poly1.sum(&params, &poly2); //We execute the defined methods 
22    let mul = poly1.mul(&params, &poly2);
23    let mul_ntt = poly1.mul_ntt(&params, ntt_tables, &poly2); 
24    let scaled = poly1.scale(&params, 10);
25    let divided = poly1.divide_by_constant(2);
26    let reduced = poly1.reduce(2);
27    let opposite = poly1.opposite(&params);
28    println!();
29    assert_eq!(poly1.coeffs, coeffs.into_boxed_slice()); //We ensure, with all the assert_eqs, that the result is correct.
30    println!("First polynomial : {:?}", poly1);
31    println!();
32    println!("Second polynomial : {:?}", poly2);
33    assert_eq!(poly2.coeffs, vec![0u64; 4].into_boxed_slice());
34    println!();
35    println!("Sum is : {:?}", sum);
36    assert_eq!(poly1.coeffs, sum.coeffs);
37    println!();
38    println!("Product is : {:?}", mul);
39    assert_eq!(poly2.coeffs, mul.coeffs);
40    println!();
41    println!("Product with NTT is : {:?}", mul_ntt);
42    assert_eq!(poly2.coeffs, mul.coeffs);
43    println!();
44    println!("Scaled first polynomial is : {:?}", scaled);
45    let mut coeffs = vec![0u64; 4];
46    coeffs[3] = (8 * 10) % params.q; //We have to reduce because the scale is done modulo q
47    assert_eq!(coeffs.into_boxed_slice(), scaled.coeffs);
48    println!();
49    println!("Divided first polynomial is : {:?}", divided);
50    let mut coeffs = vec![0u64; 4];
51    coeffs[3] = 8 / 2;
52    assert_eq!(coeffs.into_boxed_slice(), divided.coeffs);
53    println!();
54    println!("Reduced first polynomial is : {:?}", reduced);
55    let mut coeffs = vec![0u64; 4];
56    coeffs[3] = 8 % 2;
57    assert_eq!(coeffs.into_boxed_slice(), reduced.coeffs);
58    println!();
59    println!("Opposite poly1 is : {:?}", opposite);
60    let mut coeffs = vec![0u64; 4];
61    coeffs[3] = (-8 as i64).rem_euclid(params.q as i64) as u64;//We have to reduce because the opposite is done modulo q
62    assert_eq!(coeffs.into_boxed_slice(), opposite.coeffs); 
63    println!()
64}