use crate::ring::{Ring, RingRNS}; use crate::poly::PolyRNS; use crate::modulus::montgomery::Montgomery; use crate::modulus::barrett::Barrett; use crate::modulus::REDUCEMOD; use num_bigint::BigInt; pub fn new_rings(n: usize, moduli: Vec) -> Vec>{ assert!(!moduli.is_empty(), "moduli cannot be empty"); let rings: Vec> = moduli .into_iter() .map(|prime| Ring::new(n, prime, 1)) .collect(); return rings } impl<'a> RingRNS<'a, u64>{ pub fn new(rings:&'a [Ring]) -> Self{ RingRNS(rings) } pub fn rescaling_constant(&self) -> Vec> { let level = self.level(); let q_scale: u64 = self.0[level].modulus.q; (0..level).map(|i| {self.0[i].modulus.barrett.prepare(self.0[i].modulus.q - self.0[i].modulus.inv(q_scale))}).collect() } pub fn set_poly_from_bigint(&self, coeffs: &[BigInt], step:usize, a: &mut PolyRNS){ let level = self.level(); assert!(level <= a.level(), "invalid level: level={} > a.level()={}", level, a.level()); (0..level).for_each(|i|{self.0[i].from_bigint(coeffs, step, a.at_mut(i))}); } } impl RingRNS<'_, u64>{ #[inline(always)] pub fn add(&self, a: &PolyRNS, b: &PolyRNS, c: &mut PolyRNS){ let level: usize = self.level(); debug_assert!(self.max_level() <= level, "max_level={} < level={}", self.max_level(), level); debug_assert!(a.level() >= level, "a.level()={} < level={}", a.level(), level); debug_assert!(b.level() >= level, "b.level()={} < level={}", b.level(), level); debug_assert!(c.level() >= level, "c.level()={} < level={}", c.level(), level); self.0.iter().take(level + 1).enumerate().for_each(|(i, ring)| ring.add::(&a.0[i], &b.0[i], &mut c.0[i])); } #[inline(always)] pub fn add_inplace(&self, a: &PolyRNS, b: &mut PolyRNS){ let level: usize = self.level(); debug_assert!(self.max_level() <= level, "max_level={} < level={}", self.max_level(), level); debug_assert!(a.level() >= level, "a.level()={} < level={}", a.level(), level); debug_assert!(b.level() >= level, "b.level()={} < level={}", b.level(), level); self.0.iter().take(level + 1).enumerate().for_each(|(i, ring)| ring.add_inplace::(&a.0[i], &mut b.0[i])); } #[inline(always)] pub fn sub(&self, a: &PolyRNS, b: &PolyRNS, c: &mut PolyRNS){ let level: usize = self.level(); debug_assert!(self.max_level() <= level, "max_level={} < level={}", self.max_level(), level); debug_assert!(a.level() >= level, "a.level()={} < level={}", a.level(), level); debug_assert!(b.level() >= level, "b.level()={} < level={}", b.level(), level); debug_assert!(c.level() >= level, "c.level()={} < level={}", c.level(), level); self.0.iter().take(level + 1).enumerate().for_each(|(i, ring)| ring.sub::(&a.0[i], &b.0[i], &mut c.0[i])); } #[inline(always)] pub fn sub_inplace(&self, a: &PolyRNS, b: &mut PolyRNS){ let level: usize = self.level(); debug_assert!(self.max_level() <= level, "max_level={} < level={}", self.max_level(), level); debug_assert!(a.level() >= level, "a.level()={} < level={}", a.level(), level); debug_assert!(b.level() >= level, "b.level()={} < level={}", b.level(), level); self.0.iter().take(level + 1).enumerate().for_each(|(i, ring)| ring.sub_inplace::(&a.0[i], &mut b.0[i])); } #[inline(always)] pub fn neg(&self, a: &PolyRNS, b: &mut PolyRNS){ let level: usize = self.level(); debug_assert!(self.max_level() <= level, "max_level={} < level={}", self.max_level(), level); debug_assert!(a.level() >= level, "a.level()={} < level={}", a.level(), level); debug_assert!(b.level() >= level, "b.level()={} < level={}", b.level(), level); self.0.iter().take(level + 1).enumerate().for_each(|(i, ring)| ring.neg::(&a.0[i], &mut b.0[i])); } #[inline(always)] pub fn neg_inplace(&self, a: &mut PolyRNS){ let level: usize = self.level(); debug_assert!(self.max_level() <= level, "max_level={} < level={}", self.max_level(), level); debug_assert!(a.level() >= level, "a.level()={} < level={}", a.level(), level); self.0.iter().take(level + 1).enumerate().for_each(|(i, ring)| ring.neg_inplace::(&mut a.0[i])); } #[inline(always)] pub fn mul_montgomery_external(&self, a:&PolyRNS>, b:&PolyRNS, c: &mut PolyRNS){ let level: usize = self.level(); debug_assert!(self.max_level() <= level, "max_level={} < level={}", self.max_level(), level); debug_assert!(a.level() >= level, "a.level()={} < level={}", a.level(), level); debug_assert!(b.level() >= level, "b.level()={} < level={}", b.level(), level); debug_assert!(c.level() >= level, "c.level()={} < level={}", c.level(), level); self.0.iter().take(level + 1).enumerate().for_each(|(i, ring)| ring.mul_montgomery_external::(&a.0[i], &b.0[i], &mut c.0[i])); } #[inline(always)] pub fn mul_montgomery_external_inplace(&self, a:&PolyRNS>, b:&mut PolyRNS){ let level: usize = self.level(); debug_assert!(self.max_level() <= level, "max_level={} < level={}", self.max_level(), level); debug_assert!(a.level() >= level, "a.level()={} < level={}", a.level(), level); debug_assert!(b.level() >= level, "b.level()={} < level={}", b.level(), level); self.0.iter().take(level + 1).enumerate().for_each(|(i, ring)| ring.mul_montgomery_external_inplace::(&a.0[i], &mut b.0[i])); } }