Skip to main content

finite_field/
lib.rs

1//! This crate provides traits for working with finite fields.
2
3#![no_std]
4#![cfg_attr(docsrs, feature(doc_cfg))]
5// Catch documentation errors caused by code changes.
6#![deny(rustdoc::broken_intra_doc_links)]
7#![forbid(unsafe_code)]
8
9#[cfg(feature = "alloc")]
10extern crate alloc;
11
12mod batch;
13pub use batch::*;
14
15pub mod helpers;
16
17use core::fmt;
18use core::iter::{Product, Sum};
19use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
20
21use rand_core::{Rng, TryRng};
22use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
23
24/// This trait represents an element of a field.
25pub trait Field:
26    Sized
27    + Eq
28    + Copy
29    + Clone
30    + Default
31    + Send
32    + Sync
33    + fmt::Debug
34    + 'static
35    + ConditionallySelectable
36    + ConstantTimeEq
37    + Neg<Output = Self>
38    + Add<Output = Self>
39    + Sub<Output = Self>
40    + Mul<Output = Self>
41    + Sum
42    + Product
43    + for<'a> Add<&'a Self, Output = Self>
44    + for<'a> Sub<&'a Self, Output = Self>
45    + for<'a> Mul<&'a Self, Output = Self>
46    + for<'a> Sum<&'a Self>
47    + for<'a> Product<&'a Self>
48    + AddAssign
49    + SubAssign
50    + MulAssign
51    + for<'a> AddAssign<&'a Self>
52    + for<'a> SubAssign<&'a Self>
53    + for<'a> MulAssign<&'a Self>
54{
55    /// The zero element of the field, the additive identity.
56    const ZERO: Self;
57
58    /// The one element of the field, the multiplicative identity.
59    const ONE: Self;
60
61    /// Returns an element chosen uniformly at random using a user-provided infallible RNG.
62    ///
63    /// This is a convenience wrapper around [`Field::try_random`] for RNGs that cannot
64    /// fail. Use [`Field::try_random`] if your RNG may fail (for example, an OS-backed
65    /// entropy source).
66    fn random<R: Rng + ?Sized>(rng: &mut R) -> Self {
67        let Ok(out) = Self::try_random(rng);
68        out
69    }
70
71    /// Returns an element chosen uniformly at random using a user-provided fallible RNG.
72    ///
73    /// Returns `Err` propagating the RNG's error if the underlying RNG fails to produce
74    /// the randomness required to sample an element. Implementors of `Field` must
75    /// provide this method; [`Field::random`] is derived from it for infallible RNGs.
76    fn try_random<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error>;
77
78    /// Returns true iff this element is zero.
79    fn is_zero(&self) -> Choice {
80        self.ct_eq(&Self::ZERO)
81    }
82
83    /// Returns true iff this element is zero.
84    ///
85    /// # Security
86    ///
87    /// This method provides **no** constant-time guarantees. Implementors of the
88    /// `Field` trait **may** optimise this method using non-constant-time logic.
89    fn is_zero_vartime(&self) -> bool {
90        self.is_zero().into()
91    }
92
93    /// Squares this element.
94    #[must_use]
95    fn square(&self) -> Self;
96
97    /// Cubes this element.
98    #[must_use]
99    fn cube(&self) -> Self {
100        self.square() * self
101    }
102
103    /// Doubles this element.
104    #[must_use]
105    fn double(&self) -> Self;
106
107    /// Computes the multiplicative inverse of this element,
108    /// failing if the element is zero.
109    fn invert(&self) -> CtOption<Self>;
110
111    /// Computes:
112    ///
113    /// - $(\textsf{true}, \sqrt{\textsf{num}/\textsf{div}})$, if $\textsf{num}$ and
114    ///   $\textsf{div}$ are nonzero and $\textsf{num}/\textsf{div}$ is a square in the
115    ///   field;
116    /// - $(\textsf{true}, 0)$, if $\textsf{num}$ is zero;
117    /// - $(\textsf{false}, 0)$, if $\textsf{num}$ is nonzero and $\textsf{div}$ is zero;
118    /// - $(\textsf{false}, \sqrt{G_S \cdot \textsf{num}/\textsf{div}})$, if
119    ///   $\textsf{num}$ and $\textsf{div}$ are nonzero and $\textsf{num}/\textsf{div}$ is
120    ///   a nonsquare in the field;
121    ///
122    /// where $G_S$ is a non-square.
123    ///
124    /// # Warnings
125    ///
126    /// - The choice of root from `sqrt` is unspecified.
127    /// - The value of $G_S$ is unspecified, and cannot be assumed to have any specific
128    ///   value in a generic context.
129    fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self);
130
131    /// Equivalent to `Self::sqrt_ratio(self, one())`.
132    ///
133    /// The provided method is implemented in terms of [`Self::sqrt_ratio`].
134    fn sqrt_alt(&self) -> (Choice, Self) {
135        Self::sqrt_ratio(self, &Self::ONE)
136    }
137
138    /// Returns the square root of the field element, if it is
139    /// quadratic residue.
140    ///
141    /// The provided method is implemented in terms of [`Self::sqrt_ratio`].
142    fn sqrt(&self) -> CtOption<Self> {
143        let (is_square, res) = Self::sqrt_ratio(self, &Self::ONE);
144        CtOption::new(res, is_square)
145    }
146
147    /// Exponentiates `self` by `exp`, where `exp` is a little-endian order integer
148    /// exponent.
149    ///
150    /// # Guarantees
151    ///
152    /// This operation is constant time with respect to `self`, for all exponents with the
153    /// same number of digits (`exp.as_ref().len()`). It is variable time with respect to
154    /// the number of digits in the exponent.
155    fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
156        let mut res = Self::ONE;
157        for e in exp.as_ref().iter().rev() {
158            for i in (0..64).rev() {
159                res = res.square();
160                let mut tmp = res;
161                tmp *= self;
162                res.conditional_assign(&tmp, (((*e >> i) & 1) as u8).into());
163            }
164        }
165        res
166    }
167
168    /// Exponentiates `self` by `exp`, where `exp` is a little-endian order integer
169    /// exponent.
170    ///
171    /// # Guarantees
172    ///
173    /// **This operation is variable time with respect to `self`, for all exponent.** If
174    /// the exponent is fixed, this operation is effectively constant time. However, for
175    /// stronger constant-time guarantees, [`Field::pow`] should be used.
176    fn pow_vartime<S: AsRef<[u64]>>(&self, exp: S) -> Self {
177        let mut res = Self::ONE;
178        for e in exp.as_ref().iter().rev() {
179            for i in (0..64).rev() {
180                res = res.square();
181
182                if ((*e >> i) & 1) == 1 {
183                    res.mul_assign(self);
184                }
185            }
186        }
187
188        res
189    }
190}
191
192/// This represents an element of a non-binary prime field.
193pub trait PrimeField: Field + From<u64> {
194    /// The prime field can be converted back and forth into this binary
195    /// representation.
196    type Repr: Copy + Default + Send + Sync + 'static + AsRef<[u8]> + AsMut<[u8]>;
197
198    /// Byte order to use when interpreting `Repr`.
199    ///
200    /// Defaults to little endian unless specified.
201    const BYTE_ORDER: ByteOrder = ByteOrder::LittleEndian;
202
203    /// Interpret a string of numbers as a (congruent) prime field element.
204    /// Does not accept unnecessary leading zeroes or a blank string.
205    ///
206    /// # Security
207    ///
208    /// This method provides **no** constant-time guarantees.
209    fn from_str_vartime(s: &str) -> Option<Self> {
210        if s.is_empty() {
211            return None;
212        }
213
214        if s == "0" {
215            return Some(Self::ZERO);
216        }
217
218        let mut res = Self::ZERO;
219
220        let ten = Self::from(10);
221
222        let mut first_digit = true;
223
224        for c in s.chars() {
225            match c.to_digit(10) {
226                Some(c) => {
227                    if first_digit {
228                        if c == 0 {
229                            return None;
230                        }
231
232                        first_digit = false;
233                    }
234
235                    res.mul_assign(&ten);
236                    res.add_assign(&Self::from(u64::from(c)));
237                }
238                None => {
239                    return None;
240                }
241            }
242        }
243
244        Some(res)
245    }
246
247    /// Obtains a field element congruent to the integer `v`.
248    ///
249    /// For fields where `Self::CAPACITY >= 128`, this is injective and will produce a
250    /// unique field element.
251    ///
252    /// For fields where `Self::CAPACITY < 128`, this is surjective; some field elements
253    /// will be produced by multiple values of `v`.
254    ///
255    /// If you want to deterministically sample a field element representing a value, use
256    /// [`FromUniformBytes`] instead.
257    fn from_u128(v: u128) -> Self {
258        let lower = v as u64;
259        let upper = (v >> 64) as u64;
260        let mut tmp = Self::from(upper);
261        for _ in 0..64 {
262            tmp = tmp.double();
263        }
264        tmp + Self::from(lower)
265    }
266
267    /// Attempts to convert a byte representation of a field element into an element of
268    /// this prime field, failing if the input is not canonical (is not smaller than the
269    /// field's modulus).
270    ///
271    /// The byte representation is interpreted with the same endianness as elements
272    /// returned by [`PrimeField::to_repr`].
273    fn from_repr(repr: Self::Repr) -> CtOption<Self>;
274
275    /// Attempts to convert a byte representation of a field element into an element of
276    /// this prime field, failing if the input is not canonical (is not smaller than the
277    /// field's modulus).
278    ///
279    /// The byte representation is interpreted with the same endianness as elements
280    /// returned by [`PrimeField::to_repr`].
281    ///
282    /// # Security
283    ///
284    /// This method provides **no** constant-time guarantees. Implementors of the
285    /// `PrimeField` trait **may** optimise this method using non-constant-time logic.
286    fn from_repr_vartime(repr: Self::Repr) -> Option<Self> {
287        Self::from_repr(repr).into()
288    }
289
290    /// Converts an element of the prime field into the standard byte representation for
291    /// this field.
292    ///
293    /// The endianness of the byte representation is implementation-specific and may be specified
294    /// using the associated [`PrimeField::BYTE_ORDER`] constant.
295    fn to_repr(&self) -> Self::Repr;
296
297    /// Returns true iff this element is odd.
298    fn is_odd(&self) -> Choice;
299
300    /// Returns true iff this element is even.
301    #[inline(always)]
302    fn is_even(&self) -> Choice {
303        !self.is_odd()
304    }
305
306    /// Modulus of the field written as a string for debugging purposes.
307    ///
308    /// The encoding of the modulus is implementation-specific. Generic users of the
309    /// `PrimeField` trait should treat this string as opaque.
310    const MODULUS: &'static str;
311
312    /// How many bits are needed to represent an element of this field.
313    const NUM_BITS: u32;
314
315    /// How many bits of information can be reliably stored in the field element.
316    ///
317    /// This is usually `Self::NUM_BITS - 1`.
318    const CAPACITY: u32;
319
320    /// Inverse of $2$ in the field.
321    const TWO_INV: Self;
322
323    /// A fixed multiplicative generator of `modulus - 1` order. This element must also be
324    /// a quadratic nonresidue.
325    ///
326    /// It can be calculated using [SageMath] as `GF(modulus).primitive_element()`.
327    ///
328    /// Implementations of this trait MUST ensure that this is the generator used to
329    /// derive `Self::ROOT_OF_UNITY`.
330    ///
331    /// [SageMath]: https://www.sagemath.org/
332    const MULTIPLICATIVE_GENERATOR: Self;
333
334    /// An integer `s` satisfying the equation `2^s * t = modulus - 1` with `t` odd.
335    ///
336    /// This is the number of leading zero bits in the little-endian bit representation of
337    /// `modulus - 1`.
338    const S: u32;
339
340    /// The `2^s` root of unity.
341    ///
342    /// It can be calculated by exponentiating `Self::MULTIPLICATIVE_GENERATOR` by `t`,
343    /// where `t = (modulus - 1) >> Self::S`.
344    const ROOT_OF_UNITY: Self;
345
346    /// Inverse of [`Self::ROOT_OF_UNITY`].
347    const ROOT_OF_UNITY_INV: Self;
348
349    /// Generator of the `t-order` multiplicative subgroup.
350    ///
351    /// It can be calculated by exponentiating [`Self::MULTIPLICATIVE_GENERATOR`] by `2^s`,
352    /// where `s` is [`Self::S`].
353    const DELTA: Self;
354}
355
356/// Byte order used when encoding/decoding field elements as bytestrings.
357#[derive(Clone, Copy, Debug, Eq, PartialEq)]
358pub enum ByteOrder {
359    /// Big endian.
360    BigEndian,
361
362    /// Little endian.
363    LittleEndian,
364}
365
366/// The subset of prime-order fields such that `(modulus - 1)` is divisible by `N`.
367///
368/// If `N` is prime, there will be `N - 1` valid choices of [`Self::ZETA`]. Similarly to
369/// [`PrimeField::MULTIPLICATIVE_GENERATOR`], the specific choice does not matter, as long
370/// as the choice is consistent across all uses of the field.
371pub trait WithSmallOrderMulGroup<const N: u8>: PrimeField {
372    /// A field element of small multiplicative order $N$.
373    ///
374    /// The presence of this element allows you to perform (certain types of)
375    /// endomorphisms on some elliptic curves.
376    ///
377    /// It can be calculated using [SageMath] as
378    /// `GF(modulus).primitive_element() ^ ((modulus - 1) // N)`.
379    /// Choosing the element of order $N$ that is smallest, when considered
380    /// as an integer, may help to ensure consistency.
381    ///
382    /// [SageMath]: https://www.sagemath.org/
383    const ZETA: Self;
384}
385
386/// Trait for constructing a [`PrimeField`] element from a fixed-length uniform byte
387/// array.
388///
389/// "Uniform" means that the byte array's contents must be indistinguishable from the
390/// [discrete uniform distribution]. Suitable byte arrays can be obtained:
391/// - from a cryptographically-secure randomness source (which makes this constructor
392///   equivalent to [`Field::random`]).
393/// - from a cryptographic hash function output, which enables a "random" field element to
394///   be selected deterministically. This is the primary use case for `FromUniformBytes`.
395///
396/// The length `N` of the byte array is chosen by the trait implementer such that the loss
397/// of uniformity in the mapping from byte arrays to field elements is cryptographically
398/// negligible.
399///
400/// [discrete uniform distribution]: https://en.wikipedia.org/wiki/Discrete_uniform_distribution
401///
402/// # Implementing `FromUniformBytes`
403///
404/// [`Self::from_uniform_bytes`] should always be implemented by interpreting the provided
405/// byte array as the little endian unsigned encoding of an integer, and then reducing that
406/// integer modulo the field modulus.
407///
408/// For security, `N` must be chosen so that `N * 8 >= Self::NUM_BITS + 128`. A larger
409/// value of `N` may be chosen for convenience; for example, for a field with a 255-bit
410/// modulus, `N = 64` is convenient as it matches the output length of several common
411/// cryptographic hash functions (such as SHA-512 and BLAKE2b).
412///
413/// ## Trait design
414///
415/// This trait exists because `PrimeField::from_uniform_bytes([u8; N])` cannot currently
416/// exist (trait methods cannot use associated constants in the const positions of their
417/// type signature, and we do not want `PrimeField` to require a generic const parameter).
418/// However, this has the side-effect that `FromUniformBytes` can be implemented multiple
419/// times for different values of `N`. Most implementations of [`PrimeField`] should only
420/// need to implement `FromUniformBytes` trait for one value of `N` (chosen following the
421/// above considerations); if you find yourself needing to implement it multiple times,
422/// please [let us know about your use case](https://github.com/zkcrypto/ff/issues/new) so
423/// we can take it into consideration for future evolutions of the `ff` traits.
424pub trait FromUniformBytes<const N: usize>: PrimeField {
425    /// Returns a field element that is congruent to the provided little endian unsigned
426    /// byte representation of an integer.
427    fn from_uniform_bytes(bytes: &[u8; N]) -> Self;
428}