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::{WordOperations, VecOperations};
  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};
  9use itertools::izip;
 10
 11impl WordOperations<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 word_reduce_assign<const REDUCE:REDUCEMOD>(&self, x: &mut u64){
 22        self.montgomery.reduce_assign::<REDUCE>(x);
 23    }
 24
 25    #[inline(always)]
 26    fn word_add_binary_assign<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &u64, c: &mut u64){
 27        *c = a.wrapping_add(*b);
 28        self.word_reduce_assign::<REDUCE>(c);
 29    }
 30
 31    #[inline(always)]
 32    fn word_add_unary_assign<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &mut u64){
 33        *b = a.wrapping_add(*b);
 34        self.word_reduce_assign::<REDUCE>(b);
 35    }
 36
 37    #[inline(always)]
 38    fn word_sub_binary_assign<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 word_sub_unary_assign<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 word_neg_unary_assign<const REDUCE:REDUCEMOD>(&self, a: &mut u64){
 49        *a = self.q.wrapping_sub(*a);
 50        self.word_reduce_assign::<REDUCE>(a)
 51    }
 52
 53    #[inline(always)]
 54    fn word_neg_binary_assign<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &mut u64){
 55        *b = self.q.wrapping_sub(*a);
 56        self.word_reduce_assign::<REDUCE>(b)
 57    }
 58
 59    #[inline(always)]
 60    fn word_prepare_montgomery_assign<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 word_mul_montgomery_external_binary_assign<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 word_mul_montgomery_external_unary_assign<const REDUCE:REDUCEMOD>(&self, lhs:&Montgomery<u64>, rhs:&mut u64){
 71        self.montgomery.mul_external_assign::<REDUCE>(*lhs, rhs);
 72    }
 73
 74    #[inline(always)]
 75    fn word_mul_barrett_binary_assign<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 word_mul_barrett_unary_assign<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 word_sum_aqqmb_prod_c_barrett_assign_d<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
 91impl VecOperations<u64> for Prime<u64>{
 92
 93    /// Applies a modular reduction on x based on REDUCE:
 94    /// - LAZY: no modular reduction.
 95    /// - ONCE: subtracts q if x >= q.
 96    /// - TWO: subtracts 2q if x >= 2q.
 97    /// - FOUR: subtracts 4q if x >= 4q.
 98    /// - BARRETT: maps x to x mod q using Barrett reduction.
 99    /// - BARRETTLAZY: maps x to x mod q using Barrett reduction with values in [0, 2q-1].
100    #[inline(always)]
101    fn vec_reduce_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, x: &mut [u64]){
102        apply_v!(self, Self::word_reduce_assign::<REDUCE>, x, CHUNK);
103    }
104
105    #[inline(always)]
106    fn vec_add_binary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&[u64], c:&mut [u64]){
107        apply_vvv!(self, Self::word_add_binary_assign::<REDUCE>, a, b, c, CHUNK);
108    }
109
110    #[inline(always)]
111    fn vec_add_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&mut [u64]){
112        apply_vv!(self, Self::word_add_unary_assign::<REDUCE>, a, b, CHUNK);
113    }
114
115    #[inline(always)]
116    fn vec_sub_binary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&[u64], c:&mut [u64]){
117        apply_vvv!(self, Self::word_sub_binary_assign::<REDUCE>, a, b, c, CHUNK);
118    }
119
120    #[inline(always)]
121    fn vec_sub_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&mut [u64]){
122        apply_vv!(self, Self::word_sub_unary_assign::<REDUCE>, a, b, CHUNK);
123    }
124
125    #[inline(always)]
126    fn vec_neg_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &mut [u64]){
127        apply_v!(self, Self::word_neg_unary_assign::<REDUCE>, a, CHUNK);
128    }
129
130    #[inline(always)]
131    fn vec_neg_binary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b: &mut [u64]){
132        apply_vv!(self, Self::word_neg_binary_assign::<REDUCE>, a, b, CHUNK);
133    }
134
135    #[inline(always)]
136    fn vec_prepare_montgomery_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b: &mut [Montgomery<u64>]){
137        apply_vv!(self, Self::word_prepare_montgomery_assign::<REDUCE>, a, b, CHUNK);
138    }
139
140    #[inline(always)]
141    fn vec_mul_montgomery_external_binary_assign<const CHUNK:usize,const REDUCE:REDUCEMOD>(&self, a:& [Montgomery<u64>], b:&[u64], c: &mut [u64]){
142        apply_vvv!(self, Self::word_mul_montgomery_external_binary_assign::<REDUCE>, a, b, c, CHUNK);
143    }
144
145    #[inline(always)]
146    fn vec_mul_montgomery_external_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a:& [Montgomery<u64>], b:&mut [u64]){
147        apply_vv!(self, Self::word_mul_montgomery_external_unary_assign::<REDUCE>, a, b, CHUNK);
148    }
149
150    #[inline(always)]
151    fn vec_mul_scalar_barrett_external_binary_assign<const CHUNK:usize,const REDUCE:REDUCEMOD>(&self, a:& Barrett<u64>, b:&[u64], c: &mut [u64]){
152        apply_svv!(self, Self::word_mul_barrett_binary_assign::<REDUCE>, a, b, c, CHUNK);
153    }
154
155    #[inline(always)]
156    fn vec_mul_scalar_barrett_external_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a:& Barrett<u64>, b:&mut [u64]){
157        apply_sv!(self, Self::word_mul_barrett_unary_assign::<REDUCE>, a, b, CHUNK);
158    }
159
160    fn vec_sum_aqqmb_prod_c_scalar_barrett_assign_d<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b: &[u64], c: &Barrett<u64>, d: &mut [u64]){
161        apply_vvsv!(self, Self::word_sum_aqqmb_prod_c_barrett_assign_d::<REDUCE>, a, b, c, d, CHUNK);
162    }
163}