../../.cargo/katex-header.html

winter_math/field/
traits.rs

1// Copyright (c) Facebook, Inc. and its affiliates.
2//
3// This source code is licensed under the MIT license found in the
4// LICENSE file in the root directory of this source tree.
5
6use alloc::vec::Vec;
7use core::{
8    fmt::{Debug, Display},
9    ops::{
10        Add, AddAssign, BitAnd, Div, DivAssign, Mul, MulAssign, Neg, Shl, Shr, ShrAssign, Sub,
11        SubAssign,
12    },
13};
14
15use utils::{AsBytes, Deserializable, DeserializationError, Randomizable, Serializable};
16
17// FIELD ELEMENT
18// ================================================================================================
19/// Defines an element in a finite field.
20///
21/// This trait defines basic arithmetic operations for elements in
22/// [finite fields](https://en.wikipedia.org/wiki/Finite_field) (e.g. addition subtraction,
23/// multiplication, division) as well as several convenience functions (e.g. double, square cube).
24/// Moreover, it defines interfaces for serializing and deserializing field elements.
25///
26/// The elements could be in a prime field or an extension of a prime field. Currently, only
27/// quadratic and cubic field extensions are supported.
28pub trait FieldElement:
29    Copy
30    + Clone
31    + Debug
32    + Display
33    + Default
34    + Send
35    + Sync
36    + Eq
37    + PartialEq
38    + Sized
39    + Add<Self, Output = Self>
40    + Sub<Self, Output = Self>
41    + Mul<Self, Output = Self>
42    + Div<Self, Output = Self>
43    + AddAssign<Self>
44    + SubAssign<Self>
45    + MulAssign<Self>
46    + DivAssign<Self>
47    + Neg<Output = Self>
48    + From<u32>
49    + From<u16>
50    + From<u8>
51    + TryFrom<u64>
52    + TryFrom<u128>
53    + for<'a> TryFrom<&'a [u8]>
54    + ExtensionOf<<Self as FieldElement>::BaseField>
55    + AsBytes
56    + Randomizable
57    + Serializable
58    + Deserializable
59{
60    /// A type defining positive integers big enough to describe a field modulus for
61    /// `Self::BaseField` with no loss of precision.
62    type PositiveInteger: Debug
63        + Copy
64        + PartialEq
65        + PartialOrd
66        + ShrAssign
67        + Shl<u32, Output = Self::PositiveInteger>
68        + Shr<u32, Output = Self::PositiveInteger>
69        + BitAnd<Output = Self::PositiveInteger>
70        + From<u32>
71        + From<u64>;
72
73    /// Base field type for this finite field. For prime fields, `BaseField` should be set
74    /// to `Self`.
75    type BaseField: StarkField;
76
77    /// Extension degree of this field with respect to `Self::BaseField`. For prime fields,
78    /// extension degree should be set to 1.
79    const EXTENSION_DEGREE: usize;
80
81    /// Number of bytes needed to encode an element
82    const ELEMENT_BYTES: usize;
83
84    /// True if internal representation of the element is the same as its canonical representation.
85    const IS_CANONICAL: bool;
86
87    /// The additive identity.
88    const ZERO: Self;
89
90    /// The multiplicative identity.
91    const ONE: Self;
92
93    // ALGEBRA
94    // --------------------------------------------------------------------------------------------
95
96    /// Returns this field element added to itself.
97    #[inline]
98    #[must_use]
99    fn double(self) -> Self {
100        self + self
101    }
102
103    /// Returns this field element raised to power 2.
104    #[inline]
105    #[must_use]
106    fn square(self) -> Self {
107        self * self
108    }
109
110    /// Returns this field element raised to power 3.
111    #[inline]
112    #[must_use]
113    fn cube(self) -> Self {
114        self * self * self
115    }
116
117    /// Exponentiates this field element by `power` parameter.
118    #[must_use]
119    fn exp(self, power: Self::PositiveInteger) -> Self {
120        self.exp_vartime(power)
121    }
122
123    /// Exponentiates this field element by `power` parameter.
124    /// This function is expressly variable time, to speed-up verifier computations.
125    #[must_use]
126    fn exp_vartime(self, power: Self::PositiveInteger) -> Self {
127        let mut r = Self::ONE;
128        let mut b = self;
129        let mut p = power;
130
131        let int_zero = Self::PositiveInteger::from(0u32);
132        let int_one = Self::PositiveInteger::from(1u32);
133
134        if p == int_zero {
135            return Self::ONE;
136        } else if b == Self::ZERO {
137            return Self::ZERO;
138        }
139
140        while p > int_zero {
141            if p & int_one == int_one {
142                r *= b;
143            }
144            p >>= int_one;
145            b = b.square();
146        }
147
148        r
149    }
150
151    /// Returns a multiplicative inverse of this field element. If this element is ZERO, ZERO is
152    /// returned.
153    #[must_use]
154    fn inv(self) -> Self;
155
156    /// Returns a conjugate of this field element.
157    #[must_use]
158    fn conjugate(&self) -> Self;
159
160    // BASE ELEMENT CONVERSIONS
161    // --------------------------------------------------------------------------------------------
162
163    /// Return base filed element component of this field element at the specified index `i`.
164    ///
165    /// # Panics
166    /// Panics if the specified index is greater than or equal to `Self::EXTENSION_DEGREE`.
167    fn base_element(&self, i: usize) -> Self::BaseField;
168
169    /// Converts a slice of field elements into a slice of elements in the underlying base field.
170    ///
171    /// For base STARK fields, the input and output slices are the same. For extension fields, the
172    /// output slice will contain decompositions of each extension element into underlying base
173    /// field elements.
174    fn slice_as_base_elements(elements: &[Self]) -> &[Self::BaseField];
175
176    /// Convert a slice of base field elements into a slice of field elements.
177    ///
178    /// For base STARK fields, the input and output slices are the same. For extension fields, the
179    /// output slice will contain a composition of base field elements into extension field
180    /// elements.
181    ///
182    /// # Panics
183    /// Panics if the the length of the provided slice is not divisible by `Self::EXTENSION_DEGREE`.
184    fn slice_from_base_elements(elements: &[Self::BaseField]) -> &[Self];
185
186    // SERIALIZATION / DESERIALIZATION
187    // --------------------------------------------------------------------------------------------
188
189    /// Converts a list of elements into a list of bytes.
190    ///
191    /// The elements may be in the internal representation rather than in the canonical
192    /// representation. This conversion is intended to be zero-copy (i.e. by re-interpreting the
193    /// underlying memory).
194    fn elements_as_bytes(elements: &[Self]) -> &[u8];
195
196    /// Converts a list of bytes into a list of field elements.
197    ///
198    /// The elements are assumed to encoded in the internal representation rather than in the
199    /// canonical representation. The conversion is intended to be zero-copy (i.e. by
200    /// re-interpreting the underlying memory).
201    ///
202    /// # Errors
203    /// An error is returned if:
204    /// * Memory alignment of `bytes` does not match memory alignment of field element data.
205    /// * Length of `bytes` does not divide into whole number of elements.
206    ///
207    /// # Safety
208    /// This function is unsafe because it does not check whether underlying bytes represent valid
209    /// field elements according to their internal representation.
210    unsafe fn bytes_as_elements(bytes: &[u8]) -> Result<&[Self], DeserializationError>;
211}
212
213// STARK FIELD
214// ================================================================================================
215
216/// Defines an element in a STARK-friendly finite field.
217///
218/// A STARK-friendly field is defined as a prime field with high two-addicity. That is, the
219/// the modulus of the field should be a prime number of the form `k` * 2^`n` + 1 (a Proth prime),
220/// where `n` is relatively large (e.g., greater than 32).
221pub trait StarkField: FieldElement<BaseField = Self> {
222    // CONSTANTS
223    //----------------------------------------------------------------------------------------------
224
225    /// Prime modulus of the field. Must be of the form `k` * 2^`n` + 1 (a Proth prime).
226    /// This ensures that the field has high 2-adicity.
227    const MODULUS: Self::PositiveInteger;
228
229    /// The number of bits needed to represents `Self::MODULUS`.
230    const MODULUS_BITS: u32;
231
232    /// A multiplicative generator of the field.
233    const GENERATOR: Self;
234
235    /// Let Self::MODULUS = `k` * 2^`n` + 1; then, TWO_ADICITY is `n`.
236    const TWO_ADICITY: u32;
237
238    /// Let Self::MODULUS = `k` * 2^`n` + 1; then, TWO_ADIC_ROOT_OF_UNITY is 2^`n` root of unity
239    /// computed as Self::GENERATOR^`k`.
240    const TWO_ADIC_ROOT_OF_UNITY: Self;
241
242    // REQUIRED METHODS
243    //----------------------------------------------------------------------------------------------
244
245    /// Returns byte representation of the field modulus in little-endian byte order.
246    fn get_modulus_le_bytes() -> Vec<u8>;
247
248    /// Returns a canonical integer representation of this field element.
249    fn as_int(&self) -> Self::PositiveInteger;
250
251    // PROVIDED METHODS
252    //----------------------------------------------------------------------------------------------
253
254    /// Returns the root of unity of order 2^`n`.
255    ///
256    /// # Panics
257    /// Panics if the root of unity for the specified order does not exist in this field.
258    fn get_root_of_unity(n: u32) -> Self {
259        assert!(n != 0, "cannot get root of unity for n = 0");
260        assert!(n <= Self::TWO_ADICITY, "order cannot exceed 2^{}", Self::TWO_ADICITY);
261        let power = Self::PositiveInteger::from(1u32) << (Self::TWO_ADICITY - n);
262        Self::TWO_ADIC_ROOT_OF_UNITY.exp(power)
263    }
264
265    /// Converts a slice of bytes into a field element. Pads the slice if it is smaller than the
266    /// number of bytes needed to represent an element.
267    ///
268    /// # Panics
269    /// Panics if
270    /// - the length of `bytes` is greater than the number of bytes needed to encode an element.
271    /// - the value of the bytes is not a valid field element after padding
272    fn from_bytes_with_padding(bytes: &[u8]) -> Self {
273        assert!(bytes.len() < Self::ELEMENT_BYTES);
274
275        let mut buf = bytes.to_vec();
276        buf.resize(Self::ELEMENT_BYTES, 0);
277
278        let element = match Self::try_from(buf.as_slice()) {
279            Ok(element) => element,
280            Err(_) => panic!("element deserialization failed"),
281        };
282
283        element
284    }
285}
286
287// EXTENSIBLE FIELD
288// ================================================================================================
289
290/// Defines basic arithmetic in an extension of a [StarkField] of a given degree.
291///
292/// This trait defines how to perform multiplication and compute a Frobenius automorphisms of an
293/// element in an extension of degree N for a given [StarkField]. It as assumed that an element in
294/// degree N extension field can be represented by N field elements in the base field.
295///
296/// Implementation of this trait implicitly defines the irreducible polynomial over which the
297/// extension field is defined.
298pub trait ExtensibleField<const N: usize>: StarkField {
299    /// Returns a product of `a` and `b` in the field defined by this extension.
300    fn mul(a: [Self; N], b: [Self; N]) -> [Self; N];
301
302    /// Returns the square of `a` in the field defined by this extension.
303    fn square(a: [Self; N]) -> [Self; N] {
304        <Self as ExtensibleField<N>>::mul(a, a)
305    }
306
307    /// Returns a product of `a` and `b` in the field defined by this extension. `b` represents
308    /// an element in the base field.
309    fn mul_base(a: [Self; N], b: Self) -> [Self; N];
310
311    /// Returns Frobenius automorphisms for `x` in the field defined by this extension.
312    fn frobenius(x: [Self; N]) -> [Self; N];
313
314    /// Returns true if this extension is supported for the underlying base field.
315    fn is_supported() -> bool {
316        true
317    }
318}
319
320// EXTENSION OF
321// ================================================================================================
322
323/// Specifies that a field is an extension of another field.
324///
325/// Currently, this implies the following:
326/// - An element in the base field can be converted into an element in the extension field.
327/// - An element in the extension field can be multiplied by a base field element directly. This can
328///   be used for optimization purposes as such multiplication could be much more efficient than
329///   multiplication of two extension field elements.
330pub trait ExtensionOf<E: FieldElement>: From<E> {
331    fn mul_base(self, other: E) -> Self;
332}
333
334/// A field is always an extension of itself.
335impl<E: FieldElement> ExtensionOf<E> for E {
336    #[inline(always)]
337    fn mul_base(self, other: E) -> Self {
338        self * other
339    }
340}
341
342// TO ELEMENTS
343// ================================================================================================
344
345/// Defines how to convert a struct to a vector of field elements.
346pub trait ToElements<E: FieldElement> {
347    fn to_elements(&self) -> Vec<E>;
348}
349
350impl<E: FieldElement> ToElements<E> for () {
351    fn to_elements(&self) -> Vec<E> {
352        Vec::new()
353    }
354}
355
356impl<E: FieldElement> ToElements<E> for E {
357    fn to_elements(&self) -> Vec<E> {
358        vec![*self]
359    }
360}