arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/math/src/ring/impl_u64/ring_rns.rs
math/src/ring/impl_u64/ring_rns.rsRaw
  1use crate::ring::{Ring, RingRNS};
  2use crate::poly::PolyRNS;
  3use crate::modulus::montgomery::Montgomery;
  4use crate::modulus::REDUCEMOD;
  5
  6impl RingRNS<u64>{
  7    pub fn new(n:usize, moduli: Vec<u64>) -> Self{
  8        assert!(!moduli.is_empty(), "moduli cannot be empty");
  9        let rings: Vec<Ring<u64>> = moduli
 10            .into_iter()
 11            .map(|prime: u64| Ring::new(n, prime, 1))
 12            .collect();
 13        RingRNS(rings)
 14    }
 15
 16    pub fn n(&self) -> usize{
 17        self.0[0].n()
 18    }
 19
 20    pub fn max_level(&self) -> usize{
 21        self.0.len()-1
 22    }
 23}
 24
 25impl RingRNS<u64>{
 26    
 27}
 28
 29impl RingRNS<u64>{
 30    
 31    #[inline(always)]
 32    pub fn add<const LEVEL:usize, const REDUCE: REDUCEMOD>(&self, a: &PolyRNS<u64>, b: &PolyRNS<u64>, c: &mut PolyRNS<u64>){
 33        debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL);
 34        debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n());
 35        debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n());
 36        debug_assert!(c.n() >= self.n(), "c.n()={} < n={}", c.n(), self.n());
 37        debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL);
 38        debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL);
 39        debug_assert!(c.level() >= LEVEL, "c.level()={} < LEVEL={}", c.level(), LEVEL);
 40        self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.add::<REDUCE>(&a.0[i], &b.0[i], &mut c.0[i]));
 41    }
 42
 43    #[inline(always)]
 44    pub fn add_inplace<const LEVEL:usize, const REDUCE: REDUCEMOD>(&self, a: &PolyRNS<u64>, b: &mut PolyRNS<u64>){
 45        debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL);
 46        debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n());
 47        debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n());
 48        debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL);
 49        debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL);
 50        self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.add_inplace::<REDUCE>(&a.0[i], &mut b.0[i]));
 51    }
 52
 53    #[inline(always)]
 54    pub fn sub<const LEVEL:usize, const REDUCE: REDUCEMOD>(&self, a: &PolyRNS<u64>, b: &PolyRNS<u64>, c: &mut PolyRNS<u64>){
 55        debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL);
 56        debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n());
 57        debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n());
 58        debug_assert!(c.n() >= self.n(), "c.n()={} < n={}", c.n(), self.n());
 59        debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL);
 60        debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL);
 61        debug_assert!(c.level() >= LEVEL, "c.level()={} < LEVEL={}", c.level(), LEVEL);
 62        self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.sub::<REDUCE>(&a.0[i], &b.0[i], &mut c.0[i]));
 63    }
 64
 65    #[inline(always)]
 66    pub fn sub_inplace<const LEVEL:usize, const REDUCE: REDUCEMOD>(&self, a: &PolyRNS<u64>, b: &mut PolyRNS<u64>){
 67        debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL);
 68        debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n());
 69        debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n());
 70        debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL);
 71        debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL);
 72        self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.sub_inplace::<REDUCE>(&a.0[i], &mut b.0[i]));
 73    }
 74
 75    #[inline(always)]
 76    pub fn neg<const LEVEL:usize, const REDUCE: REDUCEMOD>(&self, a: &PolyRNS<u64>, b: &mut PolyRNS<u64>){
 77        debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL);
 78        debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n());
 79        debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n());
 80        debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL);
 81        debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL);
 82        self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.neg::<REDUCE>(&a.0[i], &mut b.0[i]));
 83    }
 84
 85    #[inline(always)]
 86    pub fn neg_inplace<const LEVEL:usize, const REDUCE: REDUCEMOD>(&self, a: &mut PolyRNS<u64>){
 87        debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL);
 88        debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n());
 89        debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL);
 90        self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.neg_inplace::<REDUCE>(&mut a.0[i]));
 91    }
 92
 93    #[inline(always)]
 94    pub fn  mul_montgomery_external<const LEVEL:usize, const REDUCE:REDUCEMOD>(&self, a:&PolyRNS<Montgomery<u64>>, b:&PolyRNS<u64>, c: &mut PolyRNS<u64>){
 95        debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL);
 96        debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n());
 97        debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n());
 98        debug_assert!(c.n() >= self.n(), "c.n()={} < n={}", c.n(), self.n());
 99        debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL);
100        debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL);
101        debug_assert!(c.level() >= LEVEL, "c.level()={} < LEVEL={}", c.level(), LEVEL);
102        self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.mul_montgomery_external::<REDUCE>(&a.0[i], &b.0[i], &mut c.0[i]));
103    }
104
105    #[inline(always)]
106    pub fn mul_montgomery_external_inplace<const LEVEL:usize, const REDUCE:REDUCEMOD>(&self, a:&PolyRNS<Montgomery<u64>>, b:&mut PolyRNS<u64>){
107        debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL);
108        debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n());
109        debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n());
110        debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL);
111        debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL);
112        self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.mul_montgomery_external_inplace::<REDUCE>(&a.0[i], &mut b.0[i]));
113    }
114}