poulpy/rns/src/lib.rs
rns/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}