poulpy/math/src/lib.rs
math/src/lib.rsRaw
1#![feature(bigint_helper_methods)]
2#![feature(test)]
3
4pub mod dft;
5pub mod modulus;
6pub mod num_bigint;
7pub mod poly;
8pub mod ring;
9pub mod scalar;
10
11pub const CHUNK: usize = 8;
12
13pub mod macros {
14
15 #[macro_export]
16 macro_rules! apply_v {
17 ($self:expr, $f:expr, $a:expr, $CHUNK:expr) => {
18 match CHUNK {
19 8 => {
20 $a.chunks_exact_mut(8).for_each(|a| {
21 $f(&$self, &mut a[0]);
22 $f(&$self, &mut a[1]);
23 $f(&$self, &mut a[2]);
24 $f(&$self, &mut a[3]);
25 $f(&$self, &mut a[4]);
26 $f(&$self, &mut a[5]);
27 $f(&$self, &mut a[6]);
28 $f(&$self, &mut a[7]);
29 });
30
31 let n: usize = $a.len();
32 let m = n - (n & (CHUNK - 1));
33 $a[m..].iter_mut().for_each(|a| {
34 $f(&$self, a);
35 });
36 }
37 _ => {
38 $a.iter_mut().for_each(|a| {
39 $f(&$self, a);
40 });
41 }
42 }
43 };
44 }
45
46 #[macro_export]
47 macro_rules! apply_vv {
48 ($self:expr, $f:expr, $a:expr, $b:expr, $CHUNK:expr) => {
49 let n: usize = $a.len();
50 debug_assert!(
51 $b.len() == n,
52 "invalid argument b: b.len() = {} != a.len() = {}",
53 $b.len(),
54 n
55 );
56 debug_assert!(
57 CHUNK & (CHUNK - 1) == 0,
58 "invalid CHUNK const: not a power of two"
59 );
60
61 match CHUNK {
62 8 => {
63 izip!($a.chunks_exact(8), $b.chunks_exact_mut(8)).for_each(|(a, b)| {
64 $f(&$self, &a[0], &mut b[0]);
65 $f(&$self, &a[1], &mut b[1]);
66 $f(&$self, &a[2], &mut b[2]);
67 $f(&$self, &a[3], &mut b[3]);
68 $f(&$self, &a[4], &mut b[4]);
69 $f(&$self, &a[5], &mut b[5]);
70 $f(&$self, &a[6], &mut b[6]);
71 $f(&$self, &a[7], &mut b[7]);
72 });
73
74 let m = n - (n & (CHUNK - 1));
75 izip!($a[m..].iter(), $b[m..].iter_mut()).for_each(|(a, b)| {
76 $f(&$self, a, b);
77 });
78 }
79 _ => {
80 izip!($a.iter(), $b.iter_mut()).for_each(|(a, b)| {
81 $f(&$self, a, b);
82 });
83 }
84 }
85 };
86 }
87
88 #[macro_export]
89 macro_rules! apply_vvv {
90 ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $CHUNK:expr) => {
91 let n: usize = $a.len();
92 debug_assert!(
93 $b.len() == n,
94 "invalid argument b: b.len() = {} != a.len() = {}",
95 $b.len(),
96 n
97 );
98 debug_assert!(
99 $c.len() == n,
100 "invalid argument c: b.len() = {} != a.len() = {}",
101 $c.len(),
102 n
103 );
104 debug_assert!(
105 CHUNK & (CHUNK - 1) == 0,
106 "invalid CHUNK const: not a power of two"
107 );
108
109 match CHUNK {
110 8 => {
111 izip!(
112 $a.chunks_exact(8),
113 $b.chunks_exact(8),
114 $c.chunks_exact_mut(8)
115 )
116 .for_each(|(a, b, c)| {
117 $f(&$self, &a[0], &b[0], &mut c[0]);
118 $f(&$self, &a[1], &b[1], &mut c[1]);
119 $f(&$self, &a[2], &b[2], &mut c[2]);
120 $f(&$self, &a[3], &b[3], &mut c[3]);
121 $f(&$self, &a[4], &b[4], &mut c[4]);
122 $f(&$self, &a[5], &b[5], &mut c[5]);
123 $f(&$self, &a[6], &b[6], &mut c[6]);
124 $f(&$self, &a[7], &b[7], &mut c[7]);
125 });
126
127 let m = n - (n & 7);
128 izip!($a[m..].iter(), $b[m..].iter(), $c[m..].iter_mut()).for_each(
129 |(a, b, c)| {
130 $f(&$self, a, b, c);
131 },
132 );
133 }
134 _ => {
135 izip!($a.iter(), $b.iter(), $c.iter_mut()).for_each(|(a, b, c)| {
136 $f(&$self, a, b, c);
137 });
138 }
139 }
140 };
141 }
142
143 #[macro_export]
144 macro_rules! apply_sv {
145 ($self:expr, $f:expr, $a:expr, $b:expr, $CHUNK:expr) => {
146 let n: usize = $b.len();
147
148 debug_assert!(
149 CHUNK & (CHUNK - 1) == 0,
150 "invalid CHUNK const: not a power of two"
151 );
152
153 match CHUNK {
154 8 => {
155 izip!($b.chunks_exact_mut(8)).for_each(|b| {
156 $f(&$self, $a, &mut b[0]);
157 $f(&$self, $a, &mut b[1]);
158 $f(&$self, $a, &mut b[2]);
159 $f(&$self, $a, &mut b[3]);
160 $f(&$self, $a, &mut b[4]);
161 $f(&$self, $a, &mut b[5]);
162 $f(&$self, $a, &mut b[6]);
163 $f(&$self, $a, &mut b[7]);
164 });
165
166 let m = n - (n & 7);
167 izip!($b[m..].iter_mut()).for_each(|b| {
168 $f(&$self, $a, b);
169 });
170 }
171 _ => {
172 izip!($b.iter_mut()).for_each(|b| {
173 $f(&$self, $a, b);
174 });
175 }
176 }
177 };
178 }
179
180 #[macro_export]
181 macro_rules! apply_svv {
182 ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $CHUNK:expr) => {
183 let n: usize = $b.len();
184 debug_assert!(
185 $c.len() == n,
186 "invalid argument c: c.len() = {} != b.len() = {}",
187 $c.len(),
188 n
189 );
190 debug_assert!(
191 CHUNK & (CHUNK - 1) == 0,
192 "invalid CHUNK const: not a power of two"
193 );
194
195 match CHUNK {
196 8 => {
197 izip!($b.chunks_exact(8), $c.chunks_exact_mut(8)).for_each(|(b, c)| {
198 $f(&$self, $a, &b[0], &mut c[0]);
199 $f(&$self, $a, &b[1], &mut c[1]);
200 $f(&$self, $a, &b[2], &mut c[2]);
201 $f(&$self, $a, &b[3], &mut c[3]);
202 $f(&$self, $a, &b[4], &mut c[4]);
203 $f(&$self, $a, &b[5], &mut c[5]);
204 $f(&$self, $a, &b[6], &mut c[6]);
205 $f(&$self, $a, &b[7], &mut c[7]);
206 });
207
208 let m = n - (n & 7);
209 izip!($b[m..].iter(), $c[m..].iter_mut()).for_each(|(b, c)| {
210 $f(&$self, $a, b, c);
211 });
212 }
213 _ => {
214 izip!($b.iter(), $c.iter_mut()).for_each(|(b, c)| {
215 $f(&$self, $a, b, c);
216 });
217 }
218 }
219 };
220 }
221
222 #[macro_export]
223 macro_rules! apply_vvsv {
224 ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $d:expr, $CHUNK:expr) => {
225 let n: usize = $a.len();
226 debug_assert!(
227 $b.len() == n,
228 "invalid argument b: b.len() = {} != a.len() = {}",
229 $b.len(),
230 n
231 );
232 debug_assert!(
233 $d.len() == n,
234 "invalid argument d: d.len() = {} != a.len() = {}",
235 $d.len(),
236 n
237 );
238 debug_assert!(
239 CHUNK & (CHUNK - 1) == 0,
240 "invalid CHUNK const: not a power of two"
241 );
242
243 match CHUNK {
244 8 => {
245 izip!(
246 $a.chunks_exact(8),
247 $b.chunks_exact(8),
248 $d.chunks_exact_mut(8)
249 )
250 .for_each(|(a, b, d)| {
251 $f(&$self, &a[0], &b[0], $c, &mut d[0]);
252 $f(&$self, &a[1], &b[1], $c, &mut d[1]);
253 $f(&$self, &a[2], &b[2], $c, &mut d[2]);
254 $f(&$self, &a[3], &b[3], $c, &mut d[3]);
255 $f(&$self, &a[4], &b[4], $c, &mut d[4]);
256 $f(&$self, &a[5], &b[5], $c, &mut d[5]);
257 $f(&$self, &a[6], &b[6], $c, &mut d[6]);
258 $f(&$self, &a[7], &b[7], $c, &mut d[7]);
259 });
260
261 let m = n - (n & 7);
262 izip!($a[m..].iter(), $b[m..].iter(), $d[m..].iter_mut()).for_each(
263 |(a, b, d)| {
264 $f(&$self, a, b, $c, d);
265 },
266 );
267 }
268 _ => {
269 izip!($a.iter(), $b.iter(), $d.iter_mut()).for_each(|(a, b, d)| {
270 $f(&$self, a, b, $c, d);
271 });
272 }
273 }
274 };
275 }
276
277 #[macro_export]
278 macro_rules! apply_vsv {
279 ($self:expr, $f:expr, $a:expr, $c:expr, $b:expr, $CHUNK:expr) => {
280 let n: usize = $a.len();
281 debug_assert!(
282 $b.len() == n,
283 "invalid argument b: b.len() = {} != a.len() = {}",
284 $b.len(),
285 n
286 );
287 debug_assert!(
288 CHUNK & (CHUNK - 1) == 0,
289 "invalid CHUNK const: not a power of two"
290 );
291
292 match CHUNK {
293 8 => {
294 izip!($a.chunks_exact(8), $b.chunks_exact_mut(8)).for_each(|(a, b)| {
295 $f(&$self, &a[0], $c, &mut b[0]);
296 $f(&$self, &a[1], $c, &mut b[1]);
297 $f(&$self, &a[2], $c, &mut b[2]);
298 $f(&$self, &a[3], $c, &mut b[3]);
299 $f(&$self, &a[4], $c, &mut b[4]);
300 $f(&$self, &a[5], $c, &mut b[5]);
301 $f(&$self, &a[6], $c, &mut b[6]);
302 $f(&$self, &a[7], $c, &mut b[7]);
303 });
304
305 let m = n - (n & 7);
306 izip!($a[m..].iter(), $b[m..].iter_mut()).for_each(|(a, b)| {
307 $f(&$self, a, $c, b);
308 });
309 }
310 _ => {
311 izip!($a.iter(), $b.iter_mut()).for_each(|(a, b)| {
312 $f(&$self, a, $c, b);
313 });
314 }
315 }
316 };
317 }
318
319 #[macro_export]
320 macro_rules! apply_vssv {
321 ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $d:expr, $CHUNK:expr) => {
322 let n: usize = $a.len();
323 debug_assert!(
324 $d.len() == n,
325 "invalid argument d: d.len() = {} != a.len() = {}",
326 $d.len(),
327 n
328 );
329 debug_assert!(
330 CHUNK & (CHUNK - 1) == 0,
331 "invalid CHUNK const: not a power of two"
332 );
333
334 match CHUNK {
335 8 => {
336 izip!($a.chunks_exact(8), $d.chunks_exact_mut(8)).for_each(|(a, d)| {
337 $f(&$self, &a[0], $b, $c, &mut d[0]);
338 $f(&$self, &a[1], $b, $c, &mut d[1]);
339 $f(&$self, &a[2], $b, $c, &mut d[2]);
340 $f(&$self, &a[3], $b, $c, &mut d[3]);
341 $f(&$self, &a[4], $b, $c, &mut d[4]);
342 $f(&$self, &a[5], $b, $c, &mut d[5]);
343 $f(&$self, &a[6], $b, $c, &mut d[6]);
344 $f(&$self, &a[7], $b, $c, &mut d[7]);
345 });
346
347 let m = n - (n & 7);
348 izip!($a[m..].iter(), $d[m..].iter_mut()).for_each(|(a, d)| {
349 $f(&$self, a, $b, $c, d);
350 });
351 }
352 _ => {
353 izip!($a.iter(), $d.iter_mut()).for_each(|(a, d)| {
354 $f(&$self, a, $b, $c, d);
355 });
356 }
357 }
358 };
359 }
360
361 #[macro_export]
362 macro_rules! apply_ssv {
363 ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $CHUNK:expr) => {
364 let n: usize = $c.len();
365 debug_assert!(
366 CHUNK & (CHUNK - 1) == 0,
367 "invalid CHUNK const: not a power of two"
368 );
369
370 match CHUNK {
371 8 => {
372 izip!($c.chunks_exact_mut(8)).for_each(|c| {
373 $f(&$self, $a, $b, &mut c[0]);
374 $f(&$self, $a, $b, &mut c[1]);
375 $f(&$self, $a, $b, &mut c[2]);
376 $f(&$self, $a, $b, &mut c[3]);
377 $f(&$self, $a, $b, &mut c[4]);
378 $f(&$self, $a, $b, &mut c[5]);
379 $f(&$self, $a, $b, &mut c[6]);
380 $f(&$self, $a, $b, &mut c[7]);
381 });
382
383 let m = n - (n & 7);
384 izip!($c[m..].iter_mut()).for_each(|c| {
385 $f(&$self, $a, $b, c);
386 });
387 }
388 _ => {
389 izip!($c.iter_mut()).for_each(|c| {
390 $f(&$self, $a, $b, c);
391 });
392 }
393 }
394 };
395 }
396
397 #[macro_export]
398 macro_rules! apply_vvssv {
399 ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $CHUNK:expr) => {
400 let n: usize = $a.len();
401 debug_assert!(
402 $b.len() == n,
403 "invalid argument b: b.len() = {} != a.len() = {}",
404 $b.len(),
405 n
406 );
407 debug_assert!(
408 $e.len() == n,
409 "invalid argument e: e.len() = {} != a.len() = {}",
410 $e.len(),
411 n
412 );
413 debug_assert!(
414 CHUNK & (CHUNK - 1) == 0,
415 "invalid CHUNK const: not a power of two"
416 );
417
418 match CHUNK {
419 8 => {
420 izip!(
421 $a.chunks_exact(8),
422 $b.chunks_exact(8),
423 $e.chunks_exact_mut(8)
424 )
425 .for_each(|(a, b, e)| {
426 $f(&$self, &a[0], &b[0], $c, $d, &mut e[0]);
427 $f(&$self, &a[1], &b[1], $c, $d, &mut e[1]);
428 $f(&$self, &a[2], &b[2], $c, $d, &mut e[2]);
429 $f(&$self, &a[3], &b[3], $c, $d, &mut e[3]);
430 $f(&$self, &a[4], &b[4], $c, $d, &mut e[4]);
431 $f(&$self, &a[5], &b[5], $c, $d, &mut e[5]);
432 $f(&$self, &a[6], &b[6], $c, $d, &mut e[6]);
433 $f(&$self, &a[7], &b[7], $c, $d, &mut e[7]);
434 });
435
436 let m = n - (n & 7);
437 izip!($a[m..].iter(), $b[m..].iter(), $e[m..].iter_mut()).for_each(
438 |(a, b, e)| {
439 $f(&$self, a, b, $c, $d, e);
440 },
441 );
442 }
443 _ => {
444 izip!($a.iter(), $b.iter(), $e.iter_mut()).for_each(|(a, b, e)| {
445 $f(&$self, a, b, $c, $d, e);
446 });
447 }
448 }
449 };
450 }
451}