use super::PolynomialRingZq;
use crate::integer::fmpz_poly_helpers::reduce_fmpz_poly_by_fmpz_mod_poly_sparse;
impl PolynomialRingZq {
pub(crate) fn reduce(&mut self) {
let degree = self.get_degree();
if degree >= 0 {
unsafe {
reduce_fmpz_poly_by_fmpz_mod_poly_sparse(
&mut self.poly.poly,
&self.modulus.modulus.poly,
&self.modulus.non_zero,
self.modulus.get_q_as_modulus().get_fmpz_mod_ctx_struct(),
)
};
}
}
}
#[cfg(test)]
mod test_reduced {
use crate::{
integer::PolyOverZ,
integer_mod_q::{ModulusPolynomialRingZq, PolynomialRingZq},
};
use std::str::FromStr;
const LARGE_PRIME: u64 = u64::MAX - 58;
#[test]
fn reduces() {
let modulus =
ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {LARGE_PRIME}")).unwrap();
let poly =
PolyOverZ::from_str(&format!("4 {} {} 1 1", LARGE_PRIME + 2, u64::MAX)).unwrap();
let mut poly_ring = PolynomialRingZq { poly, modulus };
let cmp_modulus =
ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {LARGE_PRIME}")).unwrap();
let cmp_poly = PolyOverZ::from_str("3 1 58 1").unwrap();
let cmp_poly_ring = PolynomialRingZq {
poly: cmp_poly.clone(),
modulus: cmp_modulus,
};
assert_ne!(poly_ring.poly, cmp_poly);
assert_ne!(poly_ring, cmp_poly_ring);
poly_ring.reduce();
assert_eq!(poly_ring.poly, cmp_poly);
assert_eq!(poly_ring, cmp_poly_ring);
}
}