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}