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