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}