use super::NTTPolynomialRingZq;
use crate::integer_mod_q::{PolyOverZq, PolynomialRingZq};
impl From<&PolynomialRingZq> for NTTPolynomialRingZq {
fn from(poly: &PolynomialRingZq) -> Self {
if let Some(ntt_basis) = poly.modulus.ntt_basis.as_ref() {
let value = PolyOverZq::from((
&poly.get_representative_least_nonnegative_residue(),
poly.get_mod().get_q(),
));
NTTPolynomialRingZq {
poly: ntt_basis.ntt(&value),
modulus: poly.modulus.clone(),
}
} else {
panic!("The NTTBasisPolynomialRingZq is not set.")
}
}
}
impl NTTPolynomialRingZq {
pub fn inv_ntt(self) -> PolynomialRingZq {
self.modulus
.ntt_basis
.as_ref()
.as_ref()
.map(|basis| PolynomialRingZq {
poly: basis
.inv_ntt(self.poly)
.get_representative_least_nonnegative_residue(),
modulus: self.modulus.clone(),
})
.unwrap()
}
}
#[cfg(test)]
mod test_from {
use crate::{
integer::{PolyOverZ, Z},
integer_mod_q::{ModulusPolynomialRingZq, NTTPolynomialRingZq, PolynomialRingZq},
};
use std::str::FromStr;
#[test]
fn from_polynomial_ring_zq() {
let mut modulus = ModulusPolynomialRingZq::from_str("5 1 0 0 0 1 mod 257").unwrap();
modulus.set_ntt_unchecked(64);
let poly = PolyOverZ::from_str("4 130 99 64 210").unwrap();
let poly_ring_zq = PolynomialRingZq::from((&poly, &modulus));
let cmp = vec![Z::from(114), Z::from(84), Z::from(154), Z::from(168)];
let ntt_poly = NTTPolynomialRingZq::from(&poly_ring_zq);
assert_eq!(ntt_poly.poly, cmp);
}
}