Skip to main content

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 + 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    /// See [`p3_field::Field::BENEFITS_FROM_LOCKSTEP_EVALUATION`].
73    ///
74    /// Defaults to `false`: this trait backs every `MontyField31<Self>` field, including
75    /// ones not yet benchmarked, so opting in is left to parameter sets that have measured
76    /// a win (e.g. `BabyBearParameters`, `KoalaBearParameters`).
77    const BENEFITS_FROM_LOCKSTEP_EVALUATION: bool = false;
78}
79
80/// An integer `D` such that `gcd(D, p - 1) = 1`.
81pub trait RelativelyPrimePower<const D: u64> {
82    /// Compute `x -> x^{1/D}` using the modular inverse
83    /// of `D mod p - 1`.
84    fn exp_root_d<R: PrimeCharacteristicRing>(val: R) -> R;
85}
86
87/// TwoAdicData contains constants needed to imply TwoAdicField for Monty31 fields.
88pub trait TwoAdicData: MontyParameters {
89    /// Largest n such that 2^n divides p - 1.
90    const TWO_ADICITY: usize;
91
92    /// The odd constant r such that p = r * 2^n + 1
93    const ODD_FACTOR: i32 = (Self::PRIME >> Self::TWO_ADICITY) as i32;
94
95    /// ArrayLike should usually be `&'static [MontyField31]`.
96    type ArrayLike: AsRef<[MontyField31<Self>]> + Sized;
97
98    /// A list of generators of 2-adic subgroups.
99    /// 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.
100    const TWO_ADIC_GENERATORS: Self::ArrayLike;
101
102    /// Precomputation of the first 3 8th-roots of unity.
103    ///
104    /// Must agree with the 8th-root in TWO_ADIC_GENERATORS, i.e.
105    /// `ROOTS_8[1] == TWO_ADIC_GENERATORS[3]`
106    const ROOTS_8: Self::ArrayLike;
107
108    /// Precomputation of the inverses of ROOTS_8.
109    const INV_ROOTS_8: Self::ArrayLike;
110
111    /// Precomputation of the first 7 16th-roots of unity.
112    ///
113    /// Must agree with the 16th-root in TWO_ADIC_GENERATORS, i.e.
114    /// `ROOTS_16[1] == TWO_ADIC_GENERATORS[4]`
115    const ROOTS_16: Self::ArrayLike;
116
117    /// Precomputation of the inverses of ROOTS_16.
118    const INV_ROOTS_16: Self::ArrayLike;
119}
120
121/// TODO: This should be deleted long term once we have improved our API for defining extension fields.
122/// This allows us to implement Binomial Extensions over Monty31 fields.
123pub trait BinomialExtensionData<const DEG: usize>: MontyParameters + Sized {
124    /// W is a value such that (x^DEG - W) is irreducible.
125    const W: MontyField31<Self>;
126
127    /// Multiply a field element (or packed field element) by W.
128    ///
129    /// Defaults to standard multiplication but this can be reimplemented to
130    /// make use of the exact value of `W`. E.g. if `W = 2, 3` this should be
131    /// reimplemented using addition.
132    fn mul_w<A: Algebra<MontyField31<Self>>>(a: A) -> A {
133        a * Self::W
134    }
135
136    /// DTH_ROOT = W^((p - 1)/DEG)
137    const DTH_ROOT: MontyField31<Self>;
138
139    /// A generator of the extension fields multiplicative group.
140    const EXT_GENERATOR: [MontyField31<Self>; DEG];
141
142    const EXT_TWO_ADICITY: usize;
143
144    /// ArrayLike should usually be [MontyField31; EXT_TWO_ADICITY - TWO_ADICITY].
145    type ArrayLike: AsRef<[[MontyField31<Self>; DEG]]> + Sized;
146
147    /// A list of generators of 2-adic subgroups not contained in the base field.
148    const TWO_ADIC_EXTENSION_GENERATORS: Self::ArrayLike;
149}
150
151/// Data for a quintic extension using the trinomial polynomial `X^5 + X^2 - 1`.
152///
153/// This is required for fields where 5 does not divide `(P - 1)`, making simple
154/// binomial extensions `X^5 - W` impossible.
155pub trait TrinomialQuinticData: MontyParameters + Sized {
156    /// Multiplicative generator of the extension field `F_{p^5}*`.
157    const EXT_GENERATOR: [MontyField31<Self>; 5];
158
159    /// Two-adicity of the extension field order `p^5 - 1`.
160    const EXT_TWO_ADICITY: usize;
161
162    /// Frobenius coefficients: `FROBENIUS_COEFFS[k] = X^{(k+1)*p} mod (X^5 + X^2 - 1)`.
163    const FROBENIUS_COEFFS: [[MontyField31<Self>; 5]; 4];
164
165    /// Type for storing two-adic extension generators.
166    type ArrayLike: AsRef<[[MontyField31<Self>; 5]]> + Sized;
167
168    /// Generators of 2-adic subgroups not in the base field.
169    const TWO_ADIC_EXTENSION_GENERATORS: Self::ArrayLike;
170}