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}