arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/src/modulus/impl_u64/operations.rs
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_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_prepare_montgomery_assign<const REDUCE:REDUCEMOD>(&self, a: &u64, b: &mut Montgomery<u64>){
 54        self.montgomery.prepare_assign::<REDUCE>(*a, b);
 55    }
 56
 57    #[inline(always)]
 58    fn word_mul_montgomery_external_binary_assign<const REDUCE:REDUCEMOD>(&self, a: &Montgomery<u64>, b:&u64, c: &mut u64){
 59        *c = self.montgomery.mul_external::<REDUCE>(*a, *b);
 60    }
 61
 62    #[inline(always)]
 63    fn word_mul_montgomery_external_unary_assign<const REDUCE:REDUCEMOD>(&self, lhs:&Montgomery<u64>, rhs:&mut u64){
 64        self.montgomery.mul_external_assign::<REDUCE>(*lhs, rhs);
 65    }
 66}
 67
 68impl VecOperations<u64> for Prime<u64>{
 69
 70    /// Applies a modular reduction on x based on REDUCE:
 71    /// - LAZY: no modular reduction.
 72    /// - ONCE: subtracts q if x >= q.
 73    /// - TWO: subtracts 2q if x >= 2q.
 74    /// - FOUR: subtracts 4q if x >= 4q.
 75    /// - BARRETT: maps x to x mod q using Barrett reduction.
 76    /// - BARRETTLAZY: maps x to x mod q using Barrett reduction with values in [0, 2q-1].
 77    #[inline(always)]
 78    fn vec_reduce_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, x: &mut [u64]){
 79        apply_unary!(self, Self::word_reduce_assign::<REDUCE>, x, CHUNK);
 80    }
 81
 82    #[inline(always)]
 83    fn vec_add_binary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&[u64], c:&mut [u64]){
 84        apply_ternary!(self, Self::word_add_binary_assign::<REDUCE>, a, b, c, CHUNK);
 85    }
 86
 87    #[inline(always)]
 88    fn vec_add_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&mut [u64]){
 89        apply_binary!(self, Self::word_add_unary_assign::<REDUCE>, a, b, CHUNK);
 90    }
 91
 92    #[inline(always)]
 93    fn vec_sub_binary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&[u64], c:&mut [u64]){
 94        apply_ternary!(self, Self::word_sub_binary_assign::<REDUCE>, a, b, c, CHUNK);
 95    }
 96
 97    #[inline(always)]
 98    fn vec_sub_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&mut [u64]){
 99        apply_binary!(self, Self::word_sub_unary_assign::<REDUCE>, a, b, CHUNK);
100    }
101
102    #[inline(always)]
103    fn vec_neg_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &mut [u64]){
104        apply_unary!(self, Self::word_neg_assign::<REDUCE>, a, CHUNK);
105    }
106
107    #[inline(always)]
108    fn vec_prepare_montgomery_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b: &mut [Montgomery<u64>]){
109        apply_binary!(self, Self::word_prepare_montgomery_assign::<REDUCE>, a, b, CHUNK);
110    }
111
112    #[inline(always)]
113    fn vec_mul_montgomery_external_binary_assign<const CHUNK:usize,const REDUCE:REDUCEMOD>(&self, a:& [Montgomery<u64>], b:&[u64], c: &mut [u64]){
114        apply_ternary!(self, Self::word_mul_montgomery_external_binary_assign::<REDUCE>, a, b, c, CHUNK);
115    }
116
117    #[inline(always)]
118    fn vec_mul_montgomery_external_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a:& [Montgomery<u64>], b:&mut [u64]){
119        apply_binary!(self, Self::word_mul_montgomery_external_unary_assign::<REDUCE>, a, b, CHUNK);
120    }
121}