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
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}