arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/math/src/modulus/impl_u64/operations.rs
math/src/modulus/impl_u64/operations.rsRaw
  1
  2use crate::modulus::{ScalarOperations, VectorOperations};
  3use crate::modulus::prime::Prime;
  4use crate::modulus::ReduceOnce;
  5use crate::modulus::montgomery::Montgomery;
  6use crate::modulus::barrett::Barrett;
  7use crate::modulus::REDUCEMOD;
  8use crate::{apply_v, apply_vv, apply_vvv, apply_sv, apply_svv, apply_vvsv, apply_vsv};
  9use itertools::izip;
 10
 11impl ScalarOperations<u64> for Prime<u64>{
 12
 13    /// Applies a modular reduction on x based on REDUCE:
 14    /// - LAZY: no modular reduction.
 15    /// - ONCE: subtracts q if x >= q.
 16    /// - TWO: subtracts 2q if x >= 2q.
 17    /// - FOUR: subtracts 4q if x >= 4q.
 18    /// - BARRETT: maps x to x mod q using Barrett reduction.
 19    /// - BARRETTLAZY: maps x to x mod q using Barrett reduction with values in [0, 2q-1].
 20    #[inline(always)]
 21    fn sa_reduce_into_sa<const REDUCE:REDUCEMOD>(&self, a: &mut u64){
 22        self.montgomery.reduce_assign::<REDUCE>(a);
 23    }
 24
 25    #[inline(always)]
 26    fn sa_add_sb_into_sc<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &u64, c: &mut u64){
 27        *c = a.wrapping_add(*b);
 28        self.sa_reduce_into_sa::<REDUCE>(c);
 29    }
 30
 31    #[inline(always)]
 32    fn sa_add_sb_into_sb<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &mut u64){
 33        *b = a.wrapping_add(*b);
 34        self.sa_reduce_into_sa::<REDUCE>(b);
 35    }
 36
 37    #[inline(always)]
 38    fn sa_sub_sb_into_sc<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &u64, c: &mut u64){
 39        *c = a.wrapping_add(self.q.wrapping_sub(*b)).reduce_once(self.q);
 40    }
 41
 42    #[inline(always)]
 43    fn sa_sub_sb_into_sb<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &mut u64){
 44        *b = a.wrapping_add(self.q.wrapping_sub(*b)).reduce_once(self.q);
 45    }
 46
 47    #[inline(always)]
 48    fn sa_neg_into_sa<const REDUCE:REDUCEMOD>(&self, a: &mut u64){
 49        *a = self.q.wrapping_sub(*a);
 50        self.sa_reduce_into_sa::<REDUCE>(a)
 51    }
 52
 53    #[inline(always)]
 54    fn sa_neg_into_sb<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &mut u64){
 55        *b = self.q.wrapping_sub(*a);
 56        self.sa_reduce_into_sa::<REDUCE>(b)
 57    }
 58
 59    #[inline(always)]
 60    fn sa_prep_mont_into_sb<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &mut Montgomery<u64>){
 61        self.montgomery.prepare_assign::<REDUCE>(*a, b);
 62    }
 63
 64    #[inline(always)]
 65    fn sa_mont_mul_sb_into_sc<const REDUCE:REDUCEMOD>(&self, a: &Montgomery<u64>, b:&u64, c: &mut u64){
 66        *c = self.montgomery.mul_external::<REDUCE>(*a, *b);
 67    }
 68
 69    #[inline(always)]
 70    fn sa_mont_mul_sb_into_sb<const REDUCE:REDUCEMOD>(&self, a:&Montgomery<u64>, b:&mut u64){
 71        self.montgomery.mul_external_assign::<REDUCE>(*a, b);
 72    }
 73
 74    #[inline(always)]
 75    fn sa_barrett_mul_sb_into_sc<const REDUCE:REDUCEMOD>(&self, a: &Barrett<u64>, b:&u64, c: &mut u64){
 76        *c = self.barrett.mul_external::<REDUCE>(*a, *b);
 77    }
 78
 79    #[inline(always)]
 80    fn sa_barrett_mul_sb_into_sb<const REDUCE:REDUCEMOD>(&self, a:&Barrett<u64>, b:&mut u64){
 81        self.barrett.mul_external_assign::<REDUCE>(*a, b);
 82    }
 83
 84    #[inline(always)]
 85    fn sa_sub_sb_mul_sc_into_sd<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &u64, c: &Barrett<u64>, d: &mut u64){
 86        *d = self.two_q.wrapping_sub(*b).wrapping_add(*a);
 87        self.barrett.mul_external_assign::<REDUCE>(*c, d);
 88    }
 89
 90    #[inline(always)]
 91    fn sa_sub_sb_mul_sc_into_sb<const REDUCE:REDUCEMOD>(&self, a: &u64, c: &Barrett<u64>, b: &mut u64){
 92        *b = self.two_q.wrapping_sub(*b).wrapping_add(*a);
 93        self.barrett.mul_external_assign::<REDUCE>(*c, b);
 94    }
 95}
 96
 97impl VectorOperations<u64> for Prime<u64>{
 98
 99    /// Applies a modular reduction on x based on REDUCE:
100    /// - LAZY: no modular reduction.
101    /// - ONCE: subtracts q if x >= q.
102    /// - TWO: subtracts 2q if x >= 2q.
103    /// - FOUR: subtracts 4q if x >= 4q.
104    /// - BARRETT: maps x to x mod q using Barrett reduction.
105    /// - BARRETTLAZY: maps x to x mod q using Barrett reduction with values in [0, 2q-1].
106    #[inline(always)]
107    fn va_reduce_into_va<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &mut [u64]){
108        apply_v!(self, Self::sa_reduce_into_sa::<REDUCE>, a, CHUNK);
109    }
110
111    #[inline(always)]
112    fn va_add_vb_into_vc<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&[u64], c:&mut [u64]){
113        apply_vvv!(self, Self::sa_add_sb_into_sc::<REDUCE>, a, b, c, CHUNK);
114    }
115
116    #[inline(always)]
117    fn va_add_vb_into_vb<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&mut [u64]){
118        apply_vv!(self, Self::sa_add_sb_into_sb::<REDUCE>, a, b, CHUNK);
119    }
120
121    #[inline(always)]
122    fn va_add_sb_into_vc<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&u64, c:&mut [u64]){
123        apply_vsv!(self, Self::sa_add_sb_into_sc::<REDUCE>, a, b, c, CHUNK);
124    }
125
126    #[inline(always)]
127    fn sa_add_vb_into_vb<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a:&u64, b:&mut [u64]){
128        apply_sv!(self, Self::sa_add_sb_into_sb::<REDUCE>, a, b, CHUNK);
129    }
130
131    #[inline(always)]
132    fn va_sub_vb_into_vc<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&[u64], c:&mut [u64]){
133        apply_vvv!(self, Self::sa_sub_sb_into_sc::<REDUCE>, a, b, c, CHUNK);
134    }
135    
136    #[inline(always)]
137    fn va_sub_vb_into_vb<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&mut [u64]){
138        apply_vv!(self, Self::sa_sub_sb_into_sb::<REDUCE>, a, b, CHUNK);
139    }
140
141    #[inline(always)]
142    fn va_neg_into_va<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &mut [u64]){
143        apply_v!(self, Self::sa_neg_into_sa::<REDUCE>, a, CHUNK);
144    }
145
146    #[inline(always)]
147    fn va_neg_into_vb<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b: &mut [u64]){
148        apply_vv!(self, Self::sa_neg_into_sb::<REDUCE>, a, b, CHUNK);
149    }
150
151    #[inline(always)]
152    fn va_prep_mont_into_vb<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b: &mut [Montgomery<u64>]){
153        apply_vv!(self, Self::sa_prep_mont_into_sb::<REDUCE>, a, b, CHUNK);
154    }
155
156    #[inline(always)]
157    fn va_mont_mul_vb_into_vc<const CHUNK:usize,const REDUCE:REDUCEMOD>(&self, a:& [Montgomery<u64>], b:&[u64], c: &mut [u64]){
158        apply_vvv!(self, Self::sa_mont_mul_sb_into_sc::<REDUCE>, a, b, c, CHUNK);
159    }
160
161    #[inline(always)]
162    fn va_mont_mul_vb_into_vb<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a:& [Montgomery<u64>], b:&mut [u64]){
163        apply_vv!(self, Self::sa_mont_mul_sb_into_sb::<REDUCE>, a, b, CHUNK);
164    }
165
166    #[inline(always)]
167    fn sa_barrett_mul_vb_into_vc<const CHUNK:usize,const REDUCE:REDUCEMOD>(&self, a:& Barrett<u64>, b:&[u64], c: &mut [u64]){
168        apply_svv!(self, Self::sa_barrett_mul_sb_into_sc::<REDUCE>, a, b, c, CHUNK);
169    }
170
171    #[inline(always)]
172    fn sa_barrett_mul_vb_into_vb<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a:& Barrett<u64>, b:&mut [u64]){
173        apply_sv!(self, Self::sa_barrett_mul_sb_into_sb::<REDUCE>, a, b, CHUNK);
174    }
175
176    fn va_sub_vb_mul_sc_into_vd<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b: &[u64], c: &Barrett<u64>, d: &mut [u64]){
177        apply_vvsv!(self, Self::sa_sub_sb_mul_sc_into_sd::<REDUCE>, a, b, c, d, CHUNK);
178    }
179
180    fn va_sub_vb_mul_sc_into_vb<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b: &Barrett<u64>, c: &mut [u64]){
181        apply_vsv!(self, Self::sa_sub_sb_mul_sc_into_sb::<REDUCE>, a, b, c, CHUNK);
182    }
183}