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, apply_vsv};
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 #[inline(always)]
91 fn word_sum_aqqmb_prod_c_barrett_assign_b<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 VecOperations<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 vec_reduce_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, x: &mut [u64]){
108 apply_v!(self, Self::word_reduce_assign::<REDUCE>, x, CHUNK);
109 }
110
111 #[inline(always)]
112 fn vec_add_binary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&[u64], c:&mut [u64]){
113 apply_vvv!(self, Self::word_add_binary_assign::<REDUCE>, a, b, c, CHUNK);
114 }
115
116 #[inline(always)]
117 fn vec_add_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&mut [u64]){
118 apply_vv!(self, Self::word_add_unary_assign::<REDUCE>, a, b, CHUNK);
119 }
120
121 #[inline(always)]
122 fn vec_sub_binary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&[u64], c:&mut [u64]){
123 apply_vvv!(self, Self::word_sub_binary_assign::<REDUCE>, a, b, c, CHUNK);
124 }
125
126 #[inline(always)]
127 fn vec_sub_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b:&mut [u64]){
128 apply_vv!(self, Self::word_sub_unary_assign::<REDUCE>, a, b, CHUNK);
129 }
130
131 #[inline(always)]
132 fn vec_neg_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &mut [u64]){
133 apply_v!(self, Self::word_neg_unary_assign::<REDUCE>, a, CHUNK);
134 }
135
136 #[inline(always)]
137 fn vec_neg_binary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b: &mut [u64]){
138 apply_vv!(self, Self::word_neg_binary_assign::<REDUCE>, a, b, CHUNK);
139 }
140
141 #[inline(always)]
142 fn vec_prepare_montgomery_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], b: &mut [Montgomery<u64>]){
143 apply_vv!(self, Self::word_prepare_montgomery_assign::<REDUCE>, a, b, CHUNK);
144 }
145
146 #[inline(always)]
147 fn vec_mul_montgomery_external_binary_assign<const CHUNK:usize,const REDUCE:REDUCEMOD>(&self, a:& [Montgomery<u64>], b:&[u64], c: &mut [u64]){
148 apply_vvv!(self, Self::word_mul_montgomery_external_binary_assign::<REDUCE>, a, b, c, CHUNK);
149 }
150
151 #[inline(always)]
152 fn vec_mul_montgomery_external_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a:& [Montgomery<u64>], b:&mut [u64]){
153 apply_vv!(self, Self::word_mul_montgomery_external_unary_assign::<REDUCE>, a, b, CHUNK);
154 }
155
156 #[inline(always)]
157 fn vec_mul_scalar_barrett_external_binary_assign<const CHUNK:usize,const REDUCE:REDUCEMOD>(&self, a:& Barrett<u64>, b:&[u64], c: &mut [u64]){
158 apply_svv!(self, Self::word_mul_barrett_binary_assign::<REDUCE>, a, b, c, CHUNK);
159 }
160
161 #[inline(always)]
162 fn vec_mul_scalar_barrett_external_unary_assign<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a:& Barrett<u64>, b:&mut [u64]){
163 apply_sv!(self, Self::word_mul_barrett_unary_assign::<REDUCE>, a, b, CHUNK);
164 }
165
166 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]){
167 apply_vvsv!(self, Self::word_sum_aqqmb_prod_c_barrett_assign_d::<REDUCE>, a, b, c, d, CHUNK);
168 }
169
170 fn vec_sum_aqqmb_prod_c_scalar_barrett_assign_b<const CHUNK:usize, const REDUCE:REDUCEMOD>(&self, a: &[u64], c: &Barrett<u64>, b: &mut [u64]){
171 apply_vsv!(self, Self::word_sum_aqqmb_prod_c_barrett_assign_b::<REDUCE>, a, c, b, CHUNK);
172 }
173}