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::REDUCEMOD;
  7use crate::{apply_unary, apply_binary, apply_ternary};
  8use itertools::izip;
  9
 10impl WordOperations<u64> for Prime<u64>{
 11
 12    /// Applies a modular reduction on x based on REDUCE:
 13    /// - LAZY: no modular reduction.
 14    /// - ONCE: subtracts q if x >= q.
 15    /// - TWO: subtracts 2q if x >= 2q.
 16    /// - FOUR: subtracts 4q if x >= 4q.
 17    /// - BARRETT: maps x to x mod q using Barrett reduction.
 18    /// - BARRETTLAZY: maps x to x mod q using Barrett reduction with values in [0, 2q-1].
 19    #[inline(always)]
 20    fn word_reduce_assign<const REDUCE:REDUCEMOD>(&self, x: &mut u64){
 21        self.montgomery.reduce_assign::<REDUCE>(x);
 22    }
 23
 24    #[inline(always)]
 25    fn word_add_binary_assign<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &u64, c: &mut u64){
 26        *c = a.wrapping_add(*b);
 27        self.word_reduce_assign::<REDUCE>(c);
 28    }
 29
 30    #[inline(always)]
 31    fn word_add_unary_assign<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &mut u64){
 32        *b = a.wrapping_add(*b);
 33        self.word_reduce_assign::<REDUCE>(b);
 34    }
 35
 36    #[inline(always)]
 37    fn word_sub_binary_assign<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &u64, c: &mut u64){
 38        *c = a.wrapping_add(self.q.wrapping_sub(*b)).reduce_once(self.q);
 39    }
 40
 41    #[inline(always)]
 42    fn word_sub_unary_assign<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &mut u64){
 43        *b = a.wrapping_add(self.q.wrapping_sub(*b)).reduce_once(self.q);
 44    }
 45
 46    #[inline(always)]
 47    fn word_neg_unary_assign<const REDUCE:REDUCEMOD>(&self, a: &mut u64){
 48        *a = self.q.wrapping_sub(*a);
 49        self.word_reduce_assign::<REDUCE>(a)
 50    }
 51
 52    #[inline(always)]
 53    fn word_neg_binary_assign<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &mut u64){
 54        *b = self.q.wrapping_sub(*a);
 55        self.word_reduce_assign::<REDUCE>(b)
 56    }
 57
 58    #[inline(always)]
 59    fn word_prepare_montgomery_assign<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &mut Montgomery<u64>){
 60        self.montgomery.prepare_assign::<REDUCE>(*a, b);
 61    }
 62
 63    #[inline(always)]
 64    fn word_mul_montgomery_external_binary_assign<const REDUCE:REDUCEMOD>(&self, a: &Montgomery<u64>, b:&u64, c: &mut u64){
 65        *c = self.montgomery.mul_external::<REDUCE>(*a, *b);
 66    }
 67
 68    #[inline(always)]
 69    fn word_mul_montgomery_external_unary_assign<const REDUCE:REDUCEMOD>(&self, lhs:&Montgomery<u64>, rhs:&mut u64){
 70        self.montgomery.mul_external_assign::<REDUCE>(*lhs, rhs);
 71    }
 72}
 73
 74impl VecOperations<u64> for Prime<u64>{
 75
 76    /// Applies a modular reduction on x based on REDUCE:
 77    /// - LAZY: no modular reduction.
 78    /// - ONCE: subtracts q if x >= q.
 79    /// - TWO: subtracts 2q if x >= 2q.
 80    /// - FOUR: subtracts 4q if x >= 4q.
 81    /// - BARRETT: maps x to x mod q using Barrett reduction.
 82    /// - BARRETTLAZY: maps x to x mod q using Barrett reduction with values in [0, 2q-1].
 83    #[inline(always)]
 84    fn vec_reduce_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, x: &mut [u64]){
 85        apply_unary!(self, Self::word_reduce_assign::<REDUCE>, x, CHUNK);
 86    }
 87
 88    #[inline(always)]
 89    fn vec_add_binary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&[u64], c:&mut [u64]){
 90        apply_ternary!(self, Self::word_add_binary_assign::<REDUCE>, a, b, c, CHUNK);
 91    }
 92
 93    #[inline(always)]
 94    fn vec_add_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&mut [u64]){
 95        apply_binary!(self, Self::word_add_unary_assign::<REDUCE>, a, b, CHUNK);
 96    }
 97
 98    #[inline(always)]
 99    fn vec_sub_binary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&[u64], c:&mut [u64]){
100        apply_ternary!(self, Self::word_sub_binary_assign::<REDUCE>, a, b, c, CHUNK);
101    }
102
103    #[inline(always)]
104    fn vec_sub_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&mut [u64]){
105        apply_binary!(self, Self::word_sub_unary_assign::<REDUCE>, a, b, CHUNK);
106    }
107
108    #[inline(always)]
109    fn vec_neg_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &mut [u64]){
110        apply_unary!(self, Self::word_neg_unary_assign::<REDUCE>, a, CHUNK);
111    }
112
113    #[inline(always)]
114    fn vec_neg_binary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b: &mut [u64]){
115        apply_binary!(self, Self::word_neg_binary_assign::<REDUCE>, a, b, CHUNK);
116    }
117
118    #[inline(always)]
119    fn vec_prepare_montgomery_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b: &mut [Montgomery<u64>]){
120        apply_binary!(self, Self::word_prepare_montgomery_assign::<REDUCE>, a, b, CHUNK);
121    }
122
123    #[inline(always)]
124    fn vec_mul_montgomery_external_binary_assign<const CHUNK:usize,const REDUCE:REDUCEMOD>(&self, a:& [Montgomery<u64>], b:&[u64], c: &mut [u64]){
125        apply_ternary!(self, Self::word_mul_montgomery_external_binary_assign::<REDUCE>, a, b, c, CHUNK);
126    }
127
128    #[inline(always)]
129    fn vec_mul_montgomery_external_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a:& [Montgomery<u64>], b:&mut [u64]){
130        apply_binary!(self, Self::word_mul_montgomery_external_unary_assign::<REDUCE>, a, b, CHUNK);
131    }
132}