use crate::integer_mod_q::{
Modulus, ModulusPolynomialRingZq, PolyOverZq,
modulus_polynomial_ring_zq::from::non_zero_positions,
};
use std::rc::Rc;
impl ModulusPolynomialRingZq {
pub fn change_q(&mut self, modulus: impl Into<Modulus>) {
self.ntt_basis = Rc::new(None);
let new_poly_zq =
PolyOverZq::from((self.get_representative_least_nonnegative_residue(), modulus));
self.non_zero = non_zero_positions(&new_poly_zq);
self.modulus = Rc::new(new_poly_zq);
}
}
#[cfg(test)]
mod test_change_q {
use super::ModulusPolynomialRingZq;
use crate::integer_mod_q::Modulus;
use std::str::FromStr;
#[test]
fn q_correct() {
let mut modulus = ModulusPolynomialRingZq::from_str("6 1 2 3 4 5 1 mod 7").unwrap();
let q = Modulus::from(8);
modulus.change_q(&q);
assert_eq!("6 1 2 3 4 5 1 mod 8", modulus.to_string());
}
#[test]
fn big_q_correct() {
let mut modulus =
ModulusPolynomialRingZq::from_str(&format!("6 1 2 3 4 5 1 mod {}", i64::MAX)).unwrap();
let q = Modulus::from(u64::MAX);
modulus.change_q(&q);
assert_eq!(
format!("6 1 2 3 4 5 1 mod {}", u64::MAX),
modulus.to_string()
);
}
#[test]
fn reduced_correct() {
let mut modulus = ModulusPolynomialRingZq::from_str("6 1 2 3 4 5 1 mod 7").unwrap();
let q = Modulus::from(2);
modulus.change_q(&q);
assert_eq!("6 1 0 1 0 1 1 mod 2", modulus.to_string());
}
#[test]
fn reset_ntt_values() {
let mut modulus = ModulusPolynomialRingZq::from_str("6 1 2 3 4 5 1 mod 7").unwrap();
let q = Modulus::from(2);
modulus.change_q(&q);
assert_eq!(vec![0, 2, 4], modulus.non_zero);
assert!(modulus.ntt_basis.is_none());
}
}