p3_monty_31/
data_traits.rs

1use core::fmt::Debug;
2use core::hash::Hash;
3
4use p3_field::{Algebra, PrimeCharacteristicRing};
5
6use crate::MontyField31;
7
8/// MontyParameters contains the prime P along with constants needed to convert elements into and out of MONTY form.
9/// The MONTY constant is assumed to be a power of 2.
10pub trait MontyParameters:
11    Copy + Clone + Default + Debug + Eq + PartialEq + Sync + Send + Hash + 'static
12{
13    // A 31-bit prime.
14    const PRIME: u32;
15
16    // The log_2 of our MONTY constant.
17    const MONTY_BITS: u32;
18
19    // We define MONTY_MU = PRIME^-1 (mod 2^MONTY_BITS). This is different from the usual convention
20    // (MONTY_MU = -PRIME^-1 (mod 2^MONTY_BITS)) but it avoids a carry.
21    const MONTY_MU: u32;
22
23    const MONTY_MASK: u32 = ((1u64 << Self::MONTY_BITS) - 1) as u32;
24}
25
26/// PackedMontyParameters contains constants needed for MONTY operations for packings of Monty31 fields.
27#[cfg(all(target_arch = "aarch64", target_feature = "neon"))]
28pub trait PackedMontyParameters: crate::MontyParametersNeon + MontyParameters {}
29#[cfg(all(
30    target_arch = "x86_64",
31    target_feature = "avx2",
32    not(target_feature = "avx512f")
33))]
34/// PackedMontyParameters contains constants needed for MONTY operations for packings of Monty31 fields.
35pub trait PackedMontyParameters: crate::MontyParametersAVX2 + MontyParameters {}
36#[cfg(all(target_arch = "x86_64", target_feature = "avx512f"))]
37/// PackedMontyParameters contains constants needed for MONTY operations for packings of Monty31 fields.
38pub trait PackedMontyParameters: crate::MontyParametersAVX512 + MontyParameters {}
39#[cfg(not(any(
40    all(target_arch = "aarch64", target_feature = "neon"),
41    all(
42        target_arch = "x86_64",
43        target_feature = "avx2",
44        not(target_feature = "avx512f")
45    ),
46    all(target_arch = "x86_64", target_feature = "avx512f"),
47)))]
48/// PackedMontyParameters contains constants needed for MONTY operations for packings of Monty31 fields.
49pub trait PackedMontyParameters: MontyParameters {}
50
51/// BarrettParameters contains constants needed for the Barrett reduction used in the MDS code.
52pub trait BarrettParameters: MontyParameters {
53    const N: usize = 40; // beta = 2^N, fixing N = 40 here
54    const PRIME_I128: i128 = Self::PRIME as i128;
55    const PSEUDO_INV: i64 = (((1_i128) << (2 * Self::N)) / Self::PRIME_I128) as i64; // I = 2^80 / P => I < 2**50
56    const MASK: i64 = !((1 << 10) - 1); // Lets us 0 out the bottom 10 digits of an i64.
57}
58
59/// FieldParameters contains constants and methods needed to imply PrimeCharacteristicRing, Field and PrimeField32 for MontyField31.
60pub trait FieldParameters: PackedMontyParameters + Sized {
61    // Simple field constants.
62    const MONTY_ZERO: MontyField31<Self> = MontyField31::new(0);
63    const MONTY_ONE: MontyField31<Self> = MontyField31::new(1);
64    const MONTY_TWO: MontyField31<Self> = MontyField31::new(2);
65    const MONTY_NEG_ONE: MontyField31<Self> = MontyField31::new(Self::PRIME - 1);
66
67    // A generator of the fields multiplicative group. Needs to be given in Monty Form.
68    const MONTY_GEN: MontyField31<Self>;
69
70    const HALF_P_PLUS_1: u32 = (Self::PRIME + 1) >> 1;
71}
72
73/// An integer `D` such that `gcd(D, p - 1) = 1`.
74pub trait RelativelyPrimePower<const D: u64> {
75    /// Compute `x -> x^{1/D}` using the modular inverse
76    /// of `D mod p - 1`.
77    fn exp_root_d<R: PrimeCharacteristicRing>(val: R) -> R;
78}
79
80/// TwoAdicData contains constants needed to imply TwoAdicField for Monty31 fields.
81pub trait TwoAdicData: MontyParameters {
82    /// Largest n such that 2^n divides p - 1.
83    const TWO_ADICITY: usize;
84
85    /// The odd constant r such that p = r * 2^n + 1
86    const ODD_FACTOR: i32 = (Self::PRIME >> Self::TWO_ADICITY) as i32;
87
88    /// ArrayLike should usually be `&'static [MontyField31]`.
89    type ArrayLike: AsRef<[MontyField31<Self>]> + Sized;
90
91    /// A list of generators of 2-adic subgroups.
92    /// The i'th element must be a 2^i root of unity and the i'th element squared must be the i-1'th element.
93    const TWO_ADIC_GENERATORS: Self::ArrayLike;
94
95    /// Precomputation of the first 3 8th-roots of unity.
96    ///
97    /// Must agree with the 8th-root in TWO_ADIC_GENERATORS, i.e.
98    /// ROOTS_8[1] == TWO_ADIC_GENERATORS[3]
99    const ROOTS_8: Self::ArrayLike;
100
101    /// Precomputation of the inverses of ROOTS_8.
102    const INV_ROOTS_8: Self::ArrayLike;
103
104    /// Precomputation of the first 7 16th-roots of unity.
105    ///
106    /// Must agree with the 16th-root in TWO_ADIC_GENERATORS, i.e.
107    /// ROOTS_16[1] == TWO_ADIC_GENERATORS[4]
108    const ROOTS_16: Self::ArrayLike;
109
110    /// Precomputation of the inverses of ROOTS_16.
111    const INV_ROOTS_16: Self::ArrayLike;
112}
113
114/// TODO: This should be deleted long term once we have improved our API for defining extension fields.
115/// This allows us to implement Binomial Extensions over Monty31 fields.
116pub trait BinomialExtensionData<const DEG: usize>: MontyParameters + Sized {
117    /// W is a value such that (x^DEG - W) is irreducible.
118    const W: MontyField31<Self>;
119
120    /// Multiply a field element (or packed field element) by W.
121    ///
122    /// Defaults to standard multiplication but this can be reimplemented to
123    /// make use of the exact value of `W`. E.g. if `W = 2, 3` this should be
124    /// reimplemented using addition.
125    fn mul_w<A: Algebra<MontyField31<Self>>>(a: A) -> A {
126        a * Self::W
127    }
128
129    /// DTH_ROOT = W^((p - 1)/DEG)
130    const DTH_ROOT: MontyField31<Self>;
131
132    /// A generator of the extension fields multiplicative group.
133    const EXT_GENERATOR: [MontyField31<Self>; DEG];
134
135    const EXT_TWO_ADICITY: usize;
136
137    /// ArrayLike should usually be [MontyField31; EXT_TWO_ADICITY - TWO_ADICITY].
138    type ArrayLike: AsRef<[[MontyField31<Self>; DEG]]> + Sized;
139
140    /// A list of generators of 2-adic subgroups not contained in the base field.
141    const TWO_ADIC_EXTENSION_GENERATORS: Self::ArrayLike;
142}