use qfall_math::{
error::MathError,
integer_mod_q::{Modulus, ModulusPolynomialRingZq, PolyOverZq},
traits::SetCoefficient,
};
use std::fmt::Display;
pub fn new_anticyclic(
n: impl TryInto<i64> + Display,
q: impl Into<Modulus>,
) -> Result<ModulusPolynomialRingZq, MathError> {
let mut poly = PolyOverZq::from((1, q));
poly.set_coeff(n, 1)?;
Ok(ModulusPolynomialRingZq::from(&poly))
}
pub fn new_cyclic(
n: impl TryInto<i64> + Display,
q: impl Into<Modulus>,
) -> Result<ModulusPolynomialRingZq, MathError> {
let mut poly = PolyOverZq::from((-1, q));
poly.set_coeff(n, 1)?;
Ok(ModulusPolynomialRingZq::from(&poly))
}
#[cfg(test)]
mod test_new_anticyclic {
use super::new_anticyclic;
use qfall_math::{integer::Z, integer_mod_q::PolyOverZq, traits::GetCoefficient};
#[test]
fn degree() {
let degrees = [1, 4, 7, 16, 32, 128];
for degree in degrees {
let poly_mod = new_anticyclic(degree, 7).unwrap();
assert_eq!(degree, poly_mod.get_degree());
}
}
#[test]
fn correct_polynomial() {
let degrees = [1, 4, 7, 16, 32, 128];
for degree in degrees {
let poly_mod = new_anticyclic(degree, 7).unwrap();
let poly_zq = PolyOverZq::from(&poly_mod);
assert_eq!(
Z::ONE,
GetCoefficient::<Z>::get_coeff(&poly_zq, degree).unwrap()
);
assert_eq!(Z::ONE, GetCoefficient::<Z>::get_coeff(&poly_zq, 0).unwrap());
for i in 1..degree {
assert_eq!(
Z::ZERO,
GetCoefficient::<Z>::get_coeff(&poly_zq, i).unwrap()
);
}
}
}
#[test]
fn correct_modulus() {
let moduli = [7, 10, i64::MAX];
for modulus in moduli {
let poly_mod = new_anticyclic(2, modulus).unwrap();
assert_eq!(Z::from(modulus), poly_mod.get_q());
}
}
#[test]
fn invalid_n() {
let res = new_anticyclic(-1, 7);
assert!(res.is_err());
}
#[test]
#[should_panic]
fn invalid_modulus() {
let _ = new_anticyclic(2, 0);
}
}
#[cfg(test)]
mod test_new_cyclic {
use super::new_cyclic;
use qfall_math::{integer::Z, integer_mod_q::PolyOverZq, traits::GetCoefficient};
#[test]
fn degree() {
let degrees = [1, 4, 7, 16, 32, 128];
for degree in degrees {
let poly_mod = new_cyclic(degree, 7).unwrap();
assert_eq!(degree, poly_mod.get_degree());
}
}
#[test]
fn correct_polynomial() {
let degrees = [1, 4, 7, 16, 32, 128];
for degree in degrees {
let poly_mod = new_cyclic(degree, 7).unwrap();
let poly_zq = PolyOverZq::from(&poly_mod);
assert_eq!(
Z::ONE,
GetCoefficient::<Z>::get_coeff(&poly_zq, degree).unwrap()
);
assert_eq!(
Z::from(6),
GetCoefficient::<Z>::get_coeff(&poly_zq, 0).unwrap()
);
for i in 1..degree {
assert_eq!(
Z::ZERO,
GetCoefficient::<Z>::get_coeff(&poly_zq, i).unwrap()
);
}
}
}
#[test]
fn correct_modulus() {
let moduli = [7, 10, i64::MAX];
for modulus in moduli {
let poly_mod = new_cyclic(2, modulus).unwrap();
assert_eq!(Z::from(modulus), poly_mod.get_q());
}
}
#[test]
fn invalid_n() {
let res = new_cyclic(-1, 7);
assert!(res.is_err());
}
#[test]
#[should_panic]
fn invalid_modulus() {
let _ = new_cyclic(2, 0);
}
}