p3_field/packed/
no_packing.rs

1/// Add two arrays of integers modulo `P` using packing.
2///
3/// This is a fallback which should only be compiled in situations where packings are
4/// unavailable.
5///
6/// Assumes that `P` is less than `2^31` and `a + b <= 2P` for all array pairs `a, b`.
7/// If the inputs are not in this range, the result may be incorrect.
8/// The result will be in the range `[0, P]` and equal to `(a + b) mod P`.
9/// It will be equal to `P` if and only if `a + b = 2P` so provided `a + b < 2P`
10/// the result is guaranteed to be less than `P`.
11///
12/// Scalar add is assumed to be a function which implements `a + b % P` with the
13/// same specifications as above.
14#[inline(always)]
15pub fn packed_mod_add<const WIDTH: usize>(
16    a: &[u32; WIDTH],
17    b: &[u32; WIDTH],
18    res: &mut [u32; WIDTH],
19    _p: u32,
20    scalar_add: fn(u32, u32) -> u32,
21) {
22    res.iter_mut()
23        .zip(a.iter().zip(b.iter()))
24        .for_each(|(r, (&a, &b))| *r = scalar_add(a, b));
25}
26
27/// Subtract two arrays of integers modulo `P` using packing.
28///
29/// This is a fallback which should only be compiled in situations where packings are
30/// unavailable.
31///
32/// Assumes that `p` is less than `2^31` and `|a - b| <= P`.
33/// If the inputs are not in this range, the result may be incorrect.
34/// The result will be in the range `[0, P]` and equal to `(a - b) mod p`.
35/// It will be equal to `P` if and only if `a - b = P` so provided `a - b < P`
36/// the result is guaranteed to be less than `P`.
37///
38/// Scalar sub is assumed to be a function which implements `a - b % P` with the
39/// same specifications as above.
40#[inline(always)]
41pub fn packed_mod_sub<const WIDTH: usize>(
42    a: &[u32; WIDTH],
43    b: &[u32; WIDTH],
44    res: &mut [u32; WIDTH],
45    _p: u32,
46    scalar_sub: fn(u32, u32) -> u32,
47) {
48    res.iter_mut()
49        .zip(a.iter().zip(b.iter()))
50        .for_each(|(r, (&a, &b))| *r = scalar_sub(a, b));
51}