arnaucube
arnaucube/poulpyPublic Self-hosted repository
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            debug_assert!(
150                CHUNK & (CHUNK - 1) == 0,
151                "invalid CHUNK const: not a power of two"
152            );
153
154            match CHUNK {
155                8 => {
156                    izip!($b.chunks_exact_mut(8)).for_each(|b| {
157                        $f(&$self, $a, &mut b[0]);
158                        $f(&$self, $a, &mut b[1]);
159                        $f(&$self, $a, &mut b[2]);
160                        $f(&$self, $a, &mut b[3]);
161                        $f(&$self, $a, &mut b[4]);
162                        $f(&$self, $a, &mut b[5]);
163                        $f(&$self, $a, &mut b[6]);
164                        $f(&$self, $a, &mut b[7]);
165                    });
166
167                    let m = n - (n & 7);
168                    izip!($b[m..].iter_mut()).for_each(|b| {
169                        $f(&$self, $a, b);
170                    });
171                }
172                _ => {
173                    izip!($b.iter_mut()).for_each(|b| {
174                        $f(&$self, $a, b);
175                    });
176                }
177            }
178        };
179    }
180
181    #[macro_export]
182    macro_rules! apply_svv {
183        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $CHUNK:expr) => {
184            let n: usize = $b.len();
185            debug_assert!(
186                $c.len() == n,
187                "invalid argument c: c.len() = {} != b.len() = {}",
188                $c.len(),
189                n
190            );
191            debug_assert!(
192                CHUNK & (CHUNK - 1) == 0,
193                "invalid CHUNK const: not a power of two"
194            );
195
196            match CHUNK {
197                8 => {
198                    izip!($b.chunks_exact(8), $c.chunks_exact_mut(8)).for_each(|(b, c)| {
199                        $f(&$self, $a, &b[0], &mut c[0]);
200                        $f(&$self, $a, &b[1], &mut c[1]);
201                        $f(&$self, $a, &b[2], &mut c[2]);
202                        $f(&$self, $a, &b[3], &mut c[3]);
203                        $f(&$self, $a, &b[4], &mut c[4]);
204                        $f(&$self, $a, &b[5], &mut c[5]);
205                        $f(&$self, $a, &b[6], &mut c[6]);
206                        $f(&$self, $a, &b[7], &mut c[7]);
207                    });
208
209                    let m = n - (n & 7);
210                    izip!($b[m..].iter(), $c[m..].iter_mut()).for_each(|(b, c)| {
211                        $f(&$self, $a, b, c);
212                    });
213                }
214                _ => {
215                    izip!($b.iter(), $c.iter_mut()).for_each(|(b, c)| {
216                        $f(&$self, $a, b, c);
217                    });
218                }
219            }
220        };
221    }
222
223    #[macro_export]
224    macro_rules! apply_vvsv {
225        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $d:expr, $CHUNK:expr) => {
226            let n: usize = $a.len();
227            debug_assert!(
228                $b.len() == n,
229                "invalid argument b: b.len() = {} != a.len() = {}",
230                $b.len(),
231                n
232            );
233            debug_assert!(
234                $d.len() == n,
235                "invalid argument d: d.len() = {} != a.len() = {}",
236                $d.len(),
237                n
238            );
239            debug_assert!(
240                CHUNK & (CHUNK - 1) == 0,
241                "invalid CHUNK const: not a power of two"
242            );
243
244            match CHUNK {
245                8 => {
246                    izip!(
247                        $a.chunks_exact(8),
248                        $b.chunks_exact(8),
249                        $d.chunks_exact_mut(8)
250                    )
251                    .for_each(|(a, b, d)| {
252                        $f(&$self, &a[0], &b[0], $c, &mut d[0]);
253                        $f(&$self, &a[1], &b[1], $c, &mut d[1]);
254                        $f(&$self, &a[2], &b[2], $c, &mut d[2]);
255                        $f(&$self, &a[3], &b[3], $c, &mut d[3]);
256                        $f(&$self, &a[4], &b[4], $c, &mut d[4]);
257                        $f(&$self, &a[5], &b[5], $c, &mut d[5]);
258                        $f(&$self, &a[6], &b[6], $c, &mut d[6]);
259                        $f(&$self, &a[7], &b[7], $c, &mut d[7]);
260                    });
261
262                    let m = n - (n & 7);
263                    izip!($a[m..].iter(), $b[m..].iter(), $d[m..].iter_mut()).for_each(
264                        |(a, b, d)| {
265                            $f(&$self, a, b, $c, d);
266                        },
267                    );
268                }
269                _ => {
270                    izip!($a.iter(), $b.iter(), $d.iter_mut()).for_each(|(a, b, d)| {
271                        $f(&$self, a, b, $c, d);
272                    });
273                }
274            }
275        };
276    }
277
278    #[macro_export]
279    macro_rules! apply_vsv {
280        ($self:expr, $f:expr, $a:expr, $c:expr, $b:expr, $CHUNK:expr) => {
281            let n: usize = $a.len();
282            debug_assert!(
283                $b.len() == n,
284                "invalid argument b: b.len() = {} != a.len() = {}",
285                $b.len(),
286                n
287            );
288            debug_assert!(
289                CHUNK & (CHUNK - 1) == 0,
290                "invalid CHUNK const: not a power of two"
291            );
292
293            match CHUNK {
294                8 => {
295                    izip!($a.chunks_exact(8), $b.chunks_exact_mut(8)).for_each(|(a, b)| {
296                        $f(&$self, &a[0], $c, &mut b[0]);
297                        $f(&$self, &a[1], $c, &mut b[1]);
298                        $f(&$self, &a[2], $c, &mut b[2]);
299                        $f(&$self, &a[3], $c, &mut b[3]);
300                        $f(&$self, &a[4], $c, &mut b[4]);
301                        $f(&$self, &a[5], $c, &mut b[5]);
302                        $f(&$self, &a[6], $c, &mut b[6]);
303                        $f(&$self, &a[7], $c, &mut b[7]);
304                    });
305
306                    let m = n - (n & 7);
307                    izip!($a[m..].iter(), $b[m..].iter_mut()).for_each(|(a, b)| {
308                        $f(&$self, a, $c, b);
309                    });
310                }
311                _ => {
312                    izip!($a.iter(), $b.iter_mut()).for_each(|(a, b)| {
313                        $f(&$self, a, $c, b);
314                    });
315                }
316            }
317        };
318    }
319
320    #[macro_export]
321    macro_rules! apply_vssv {
322        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $d:expr, $CHUNK:expr) => {
323            let n: usize = $a.len();
324            debug_assert!(
325                $d.len() == n,
326                "invalid argument d: d.len() = {} != a.len() = {}",
327                $d.len(),
328                n
329            );
330            debug_assert!(
331                CHUNK & (CHUNK - 1) == 0,
332                "invalid CHUNK const: not a power of two"
333            );
334
335            match CHUNK {
336                8 => {
337                    izip!($a.chunks_exact(8), $d.chunks_exact_mut(8)).for_each(|(a, d)| {
338                        $f(&$self, &a[0], $b, $c, &mut d[0]);
339                        $f(&$self, &a[1], $b, $c, &mut d[1]);
340                        $f(&$self, &a[2], $b, $c, &mut d[2]);
341                        $f(&$self, &a[3], $b, $c, &mut d[3]);
342                        $f(&$self, &a[4], $b, $c, &mut d[4]);
343                        $f(&$self, &a[5], $b, $c, &mut d[5]);
344                        $f(&$self, &a[6], $b, $c, &mut d[6]);
345                        $f(&$self, &a[7], $b, $c, &mut d[7]);
346                    });
347
348                    let m = n - (n & 7);
349                    izip!($a[m..].iter(), $d[m..].iter_mut()).for_each(|(a, d)| {
350                        $f(&$self, a, $b, $c, d);
351                    });
352                }
353                _ => {
354                    izip!($a.iter(), $d.iter_mut()).for_each(|(a, d)| {
355                        $f(&$self, a, $b, $c, d);
356                    });
357                }
358            }
359        };
360    }
361
362    #[macro_export]
363    macro_rules! apply_ssv {
364        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $CHUNK:expr) => {
365            let n: usize = $c.len();
366            debug_assert!(
367                CHUNK & (CHUNK - 1) == 0,
368                "invalid CHUNK const: not a power of two"
369            );
370
371            match CHUNK {
372                8 => {
373                    izip!($c.chunks_exact_mut(8)).for_each(|c| {
374                        $f(&$self, $a, $b, &mut c[0]);
375                        $f(&$self, $a, $b, &mut c[1]);
376                        $f(&$self, $a, $b, &mut c[2]);
377                        $f(&$self, $a, $b, &mut c[3]);
378                        $f(&$self, $a, $b, &mut c[4]);
379                        $f(&$self, $a, $b, &mut c[5]);
380                        $f(&$self, $a, $b, &mut c[6]);
381                        $f(&$self, $a, $b, &mut c[7]);
382                    });
383
384                    let m = n - (n & 7);
385                    izip!($c[m..].iter_mut()).for_each(|c| {
386                        $f(&$self, $a, $b, c);
387                    });
388                }
389                _ => {
390                    izip!($c.iter_mut()).for_each(|c| {
391                        $f(&$self, $a, $b, c);
392                    });
393                }
394            }
395        };
396    }
397
398    #[macro_export]
399    macro_rules! apply_vvssv {
400        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $CHUNK:expr) => {
401            let n: usize = $a.len();
402            debug_assert!(
403                $b.len() == n,
404                "invalid argument b: b.len() = {} != a.len() = {}",
405                $b.len(),
406                n
407            );
408            debug_assert!(
409                $e.len() == n,
410                "invalid argument e: e.len() = {} != a.len() = {}",
411                $e.len(),
412                n
413            );
414            debug_assert!(
415                CHUNK & (CHUNK - 1) == 0,
416                "invalid CHUNK const: not a power of two"
417            );
418
419            match CHUNK {
420                8 => {
421                    izip!(
422                        $a.chunks_exact(8),
423                        $b.chunks_exact(8),
424                        $e.chunks_exact_mut(8)
425                    )
426                    .for_each(|(a, b, e)| {
427                        $f(&$self, &a[0], &b[0], $c, $d, &mut e[0]);
428                        $f(&$self, &a[1], &b[1], $c, $d, &mut e[1]);
429                        $f(&$self, &a[2], &b[2], $c, $d, &mut e[2]);
430                        $f(&$self, &a[3], &b[3], $c, $d, &mut e[3]);
431                        $f(&$self, &a[4], &b[4], $c, $d, &mut e[4]);
432                        $f(&$self, &a[5], &b[5], $c, $d, &mut e[5]);
433                        $f(&$self, &a[6], &b[6], $c, $d, &mut e[6]);
434                        $f(&$self, &a[7], &b[7], $c, $d, &mut e[7]);
435                    });
436
437                    let m = n - (n & 7);
438                    izip!($a[m..].iter(), $b[m..].iter(), $e[m..].iter_mut()).for_each(
439                        |(a, b, e)| {
440                            $f(&$self, a, b, $c, $d, e);
441                        },
442                    );
443                }
444                _ => {
445                    izip!($a.iter(), $b.iter(), $e.iter_mut()).for_each(|(a, b, e)| {
446                        $f(&$self, a, b, $c, $d, e);
447                    });
448                }
449            }
450        };
451    }
452
453    #[macro_export]
454    macro_rules! apply_vsssvv {
455        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $g:expr, $CHUNK:expr) => {
456            let n: usize = $a.len();
457            debug_assert!(
458                $e.len() == n,
459                "invalid argument b: e.len() = {} != a.len() = {}",
460                $e.len(),
461                n
462            );
463            debug_assert!(
464                $g.len() == n,
465                "invalid argument g: g.len() = {} != a.len() = {}",
466                $g.len(),
467                n
468            );
469            debug_assert!(
470                CHUNK & (CHUNK - 1) == 0,
471                "invalid CHUNK const: not a power of two"
472            );
473
474            match CHUNK {
475                8 => {
476                    izip!(
477                        $a.chunks_exact(8),
478                        $e.chunks_exact_mut(8),
479                        $g.chunks_exact_mut(8)
480                    )
481                    .for_each(|(a, e, g)| {
482                        $f(&$self, &a[0], $b, $c, $d, &mut e[0], &mut g[0]);
483                        $f(&$self, &a[1], $b, $c, $d, &mut e[1], &mut g[1]);
484                        $f(&$self, &a[2], $b, $c, $d, &mut e[2], &mut g[2]);
485                        $f(&$self, &a[3], $b, $c, $d, &mut e[3], &mut g[3]);
486                        $f(&$self, &a[4], $b, $c, $d, &mut e[4], &mut g[4]);
487                        $f(&$self, &a[5], $b, $c, $d, &mut e[5], &mut g[5]);
488                        $f(&$self, &a[6], $b, $c, $d, &mut e[6], &mut g[6]);
489                        $f(&$self, &a[7], $b, $c, $d, &mut e[7], &mut g[7]);
490                    });
491
492                    let m = n - (n & 7);
493                    izip!($a[m..].iter(), $e[m..].iter_mut(), $g[m..].iter_mut()).for_each(
494                        |(a, e, g)| {
495                            $f(&$self, a, $b, $c, $d, e, g);
496                        },
497                    );
498                }
499                _ => {
500                    izip!($a.iter(), $e.iter_mut(), $g.iter_mut()).for_each(|(a, e, g)| {
501                        $f(&$self, a, $b, $c, $d, e, g);
502                    });
503                }
504            }
505        };
506    }
507}