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

plonky2_field/
types.rs

1use alloc::vec;
2use alloc::vec::Vec;
3use core::fmt::{Debug, Display};
4use core::hash::Hash;
5use core::iter::{Product, Sum};
6use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
7
8use num::bigint::BigUint;
9use num::{Integer, One, ToPrimitive, Zero};
10use plonky2_util::bits_u64;
11use rand::rngs::OsRng;
12use serde::de::DeserializeOwned;
13use serde::Serialize;
14
15use crate::extension::Frobenius;
16use crate::ops::Square;
17
18/// Sampling
19pub trait Sample: Sized {
20    /// Samples a single value using `rng`.
21    fn sample<R>(rng: &mut R) -> Self
22    where
23        R: rand::RngCore + ?Sized;
24
25    /// Samples a single value using the [`OsRng`].
26    #[inline]
27    fn rand() -> Self {
28        Self::sample(&mut OsRng)
29    }
30
31    /// Samples a [`Vec`] of values of length `n` using [`OsRng`].
32    #[inline]
33    fn rand_vec(n: usize) -> Vec<Self> {
34        (0..n).map(|_| Self::rand()).collect()
35    }
36
37    /// Samples an array of values of length `N` using [`OsRng`].
38    #[inline]
39    fn rand_array<const N: usize>() -> [Self; N] {
40        Self::rand_vec(N)
41            .try_into()
42            .ok()
43            .expect("This conversion can never fail.")
44    }
45}
46
47/// A finite field.
48pub trait Field:
49    'static
50    + Copy
51    + Eq
52    + Hash
53    + Neg<Output = Self>
54    + Add<Self, Output = Self>
55    + AddAssign<Self>
56    + Sum
57    + Sub<Self, Output = Self>
58    + SubAssign<Self>
59    + Mul<Self, Output = Self>
60    + MulAssign<Self>
61    + Square
62    + Product
63    + Div<Self, Output = Self>
64    + DivAssign<Self>
65    + Debug
66    + Default
67    + Display
68    + Sample
69    + Send
70    + Sync
71    + Serialize
72    + DeserializeOwned
73{
74    const ZERO: Self;
75    const ONE: Self;
76    const TWO: Self;
77    const NEG_ONE: Self;
78
79    /// The 2-adicity of this field's multiplicative group.
80    const TWO_ADICITY: usize;
81
82    /// The field's characteristic and it's 2-adicity.
83    /// Set to `None` when the characteristic doesn't fit in a u64.
84    const CHARACTERISTIC_TWO_ADICITY: usize;
85
86    /// Generator of the entire multiplicative group, i.e. all non-zero elements.
87    const MULTIPLICATIVE_GROUP_GENERATOR: Self;
88    /// Generator of a multiplicative subgroup of order `2^TWO_ADICITY`.
89    const POWER_OF_TWO_GENERATOR: Self;
90
91    /// The bit length of the field order.
92    const BITS: usize;
93
94    fn order() -> BigUint;
95    fn characteristic() -> BigUint;
96
97    #[inline]
98    fn is_zero(&self) -> bool {
99        *self == Self::ZERO
100    }
101
102    #[inline]
103    fn is_nonzero(&self) -> bool {
104        *self != Self::ZERO
105    }
106
107    #[inline]
108    fn is_one(&self) -> bool {
109        *self == Self::ONE
110    }
111
112    #[inline]
113    fn double(&self) -> Self {
114        *self + *self
115    }
116
117    #[inline]
118    fn cube(&self) -> Self {
119        self.square() * *self
120    }
121
122    fn triple(&self) -> Self {
123        *self * (Self::ONE + Self::TWO)
124    }
125
126    /// Compute the multiplicative inverse of this field element.
127    fn try_inverse(&self) -> Option<Self>;
128
129    fn inverse(&self) -> Self {
130        self.try_inverse().expect("Tried to invert zero")
131    }
132
133    fn batch_multiplicative_inverse(x: &[Self]) -> Vec<Self> {
134        // This is Montgomery's trick. At a high level, we invert the product of the given field
135        // elements, then derive the individual inverses from that via multiplication.
136
137        // The usual Montgomery trick involves calculating an array of cumulative products,
138        // resulting in a long dependency chain. To increase instruction-level parallelism, we
139        // compute WIDTH separate cumulative product arrays that only meet at the end.
140
141        // Higher WIDTH increases instruction-level parallelism, but too high a value will cause us
142        // to run out of registers.
143        const WIDTH: usize = 4;
144        // JN note: WIDTH is 4. The code is specialized to this value and will need
145        // modification if it is changed. I tried to make it more generic, but Rust's const
146        // generics are not yet good enough.
147
148        // Handle special cases. Paradoxically, below is repetitive but concise.
149        // The branches should be very predictable.
150        let n = x.len();
151        if n == 0 {
152            return Vec::new();
153        } else if n == 1 {
154            return vec![x[0].inverse()];
155        } else if n == 2 {
156            let x01 = x[0] * x[1];
157            let x01inv = x01.inverse();
158            return vec![x01inv * x[1], x01inv * x[0]];
159        } else if n == 3 {
160            let x01 = x[0] * x[1];
161            let x012 = x01 * x[2];
162            let x012inv = x012.inverse();
163            let x01inv = x012inv * x[2];
164            return vec![x01inv * x[1], x01inv * x[0], x012inv * x01];
165        }
166        debug_assert!(n >= WIDTH);
167
168        // Buf is reused for a few things to save allocations.
169        // Fill buf with cumulative product of x, only taking every 4th value. Concretely, buf will
170        // be [
171        //   x[0], x[1], x[2], x[3],
172        //   x[0] * x[4], x[1] * x[5], x[2] * x[6], x[3] * x[7],
173        //   x[0] * x[4] * x[8], x[1] * x[5] * x[9], x[2] * x[6] * x[10], x[3] * x[7] * x[11],
174        //   ...
175        // ].
176        // If n is not a multiple of WIDTH, the result is truncated from the end. For example,
177        // for n == 5, we get [x[0], x[1], x[2], x[3], x[0] * x[4]].
178        let mut buf: Vec<Self> = Vec::with_capacity(n);
179        // cumul_prod holds the last WIDTH elements of buf. This is redundant, but it's how we
180        // convince LLVM to keep the values in the registers.
181        let mut cumul_prod: [Self; WIDTH] = x[..WIDTH].try_into().unwrap();
182        buf.extend(cumul_prod);
183        for (i, &xi) in x[WIDTH..].iter().enumerate() {
184            cumul_prod[i % WIDTH] *= xi;
185            buf.push(cumul_prod[i % WIDTH]);
186        }
187        debug_assert_eq!(buf.len(), n);
188
189        let mut a_inv = {
190            // This is where the four dependency chains meet.
191            // Take the last four elements of buf and invert them all.
192            let c01 = cumul_prod[0] * cumul_prod[1];
193            let c23 = cumul_prod[2] * cumul_prod[3];
194            let c0123 = c01 * c23;
195            let c0123inv = c0123.inverse();
196            let c01inv = c0123inv * c23;
197            let c23inv = c0123inv * c01;
198            [
199                c01inv * cumul_prod[1],
200                c01inv * cumul_prod[0],
201                c23inv * cumul_prod[3],
202                c23inv * cumul_prod[2],
203            ]
204        };
205
206        for i in (WIDTH..n).rev() {
207            // buf[i - WIDTH] has not been written to by this loop, so it equals
208            // x[i % WIDTH] * x[i % WIDTH + WIDTH] * ... * x[i - WIDTH].
209            buf[i] = buf[i - WIDTH] * a_inv[i % WIDTH];
210            // buf[i] now holds the inverse of x[i].
211            a_inv[i % WIDTH] *= x[i];
212        }
213        for i in (0..WIDTH).rev() {
214            buf[i] = a_inv[i];
215        }
216
217        for (&bi, &xi) in buf.iter().zip(x) {
218            // Sanity check only.
219            debug_assert_eq!(bi * xi, Self::ONE);
220        }
221
222        buf
223    }
224
225    /// Compute the inverse of 2^exp in this field.
226    #[inline]
227    fn inverse_2exp(exp: usize) -> Self {
228        // Let p = char(F). Since 2^exp is in the prime subfield, i.e. an
229        // element of GF_p, its inverse must be as well. Thus we may add
230        // multiples of p without changing the result. In particular,
231        // 2^-exp = 2^-exp - p 2^-exp
232        //        = 2^-exp (1 - p)
233        //        = p - (p - 1) / 2^exp
234
235        // If this field's two adicity, t, is at least exp, then 2^exp divides
236        // p - 1, so this division can be done with a simple bit shift. If
237        // exp > t, we repeatedly multiply by 2^-t and reduce exp until it's in
238        // the right range.
239
240        if let Some(p) = Self::characteristic().to_u64() {
241            // NB: The only reason this is split into two cases is to save
242            // the multiplication (and possible calculation of
243            // inverse_2_pow_adicity) in the usual case that exp <=
244            // TWO_ADICITY. Can remove the branch and simplify if that
245            // saving isn't worth it.
246
247            if exp > Self::CHARACTERISTIC_TWO_ADICITY {
248                // NB: This should be a compile-time constant
249                let inverse_2_pow_adicity: Self =
250                    Self::from_canonical_u64(p - ((p - 1) >> Self::CHARACTERISTIC_TWO_ADICITY));
251
252                let mut res = inverse_2_pow_adicity;
253                let mut e = exp - Self::CHARACTERISTIC_TWO_ADICITY;
254
255                while e > Self::CHARACTERISTIC_TWO_ADICITY {
256                    res *= inverse_2_pow_adicity;
257                    e -= Self::CHARACTERISTIC_TWO_ADICITY;
258                }
259                res * Self::from_canonical_u64(p - ((p - 1) >> e))
260            } else {
261                Self::from_canonical_u64(p - ((p - 1) >> exp))
262            }
263        } else {
264            Self::TWO.inverse().exp_u64(exp as u64)
265        }
266    }
267
268    fn primitive_root_of_unity(n_log: usize) -> Self {
269        assert!(n_log <= Self::TWO_ADICITY);
270        let base = Self::POWER_OF_TWO_GENERATOR;
271        base.exp_power_of_2(Self::TWO_ADICITY - n_log)
272    }
273
274    /// Computes a multiplicative subgroup whose order is known in advance.
275    fn cyclic_subgroup_known_order(generator: Self, order: usize) -> Vec<Self> {
276        generator.powers().take(order).collect()
277    }
278
279    /// Computes the subgroup generated by the root of unity of a given order generated by `Self::primitive_root_of_unity`.
280    fn two_adic_subgroup(n_log: usize) -> Vec<Self> {
281        let generator = Self::primitive_root_of_unity(n_log);
282        generator.powers().take(1 << n_log).collect()
283    }
284
285    fn cyclic_subgroup_unknown_order(generator: Self) -> Vec<Self> {
286        let mut subgroup = Vec::new();
287        for power in generator.powers() {
288            if power.is_one() && !subgroup.is_empty() {
289                break;
290            }
291            subgroup.push(power);
292        }
293        subgroup
294    }
295
296    fn generator_order(generator: Self) -> usize {
297        generator.powers().skip(1).position(|y| y.is_one()).unwrap() + 1
298    }
299
300    /// Computes a coset of a multiplicative subgroup whose order is known in advance.
301    fn cyclic_subgroup_coset_known_order(generator: Self, shift: Self, order: usize) -> Vec<Self> {
302        let subgroup = Self::cyclic_subgroup_known_order(generator, order);
303        subgroup.into_iter().map(|x| x * shift).collect()
304    }
305
306    /// Returns `n % Self::characteristic()`.
307    fn from_noncanonical_biguint(n: BigUint) -> Self;
308
309    /// Returns `n`. Assumes that `n` is already in canonical form, i.e. `n < Self::order()`.
310    // TODO: Should probably be unsafe.
311    fn from_canonical_u64(n: u64) -> Self;
312
313    /// Returns `n`. Assumes that `n` is already in canonical form, i.e. `n < Self::order()`.
314    // TODO: Should probably be unsafe.
315    fn from_canonical_u32(n: u32) -> Self {
316        Self::from_canonical_u64(n as u64)
317    }
318
319    /// Returns `n`. Assumes that `n` is already in canonical form, i.e. `n < Self::order()`.
320    // TODO: Should probably be unsafe.
321    fn from_canonical_u16(n: u16) -> Self {
322        Self::from_canonical_u64(n as u64)
323    }
324
325    /// Returns `n`. Assumes that `n` is already in canonical form, i.e. `n < Self::order()`.
326    // TODO: Should probably be unsafe.
327    fn from_canonical_u8(n: u8) -> Self {
328        Self::from_canonical_u64(n as u64)
329    }
330
331    /// Returns `n`. Assumes that `n` is already in canonical form, i.e. `n < Self::order()`.
332    // TODO: Should probably be unsafe.
333    fn from_canonical_usize(n: usize) -> Self {
334        Self::from_canonical_u64(n as u64)
335    }
336
337    fn from_bool(b: bool) -> Self {
338        Self::from_canonical_u64(b as u64)
339    }
340
341    /// Returns `n % Self::characteristic()`.
342    fn from_noncanonical_u128(n: u128) -> Self;
343
344    /// Returns `x % Self::CHARACTERISTIC`.
345    fn from_noncanonical_u64(n: u64) -> Self;
346
347    /// Returns `n` as an element of this field.
348    fn from_noncanonical_i64(n: i64) -> Self;
349
350    /// Returns `n % Self::characteristic()`. May be cheaper than from_noncanonical_u128 when we know
351    /// that `n < 2 ** 96`.
352    #[inline]
353    fn from_noncanonical_u96((n_lo, n_hi): (u64, u32)) -> Self {
354        // Default implementation.
355        let n: u128 = ((n_hi as u128) << 64) + (n_lo as u128);
356        Self::from_noncanonical_u128(n)
357    }
358
359    fn exp_power_of_2(&self, power_log: usize) -> Self {
360        let mut res = *self;
361        for _ in 0..power_log {
362            res = res.square();
363        }
364        res
365    }
366
367    fn exp_u64(&self, power: u64) -> Self {
368        let mut current = *self;
369        let mut product = Self::ONE;
370
371        for j in 0..bits_u64(power) {
372            if (power >> j & 1) != 0 {
373                product *= current;
374            }
375            current = current.square();
376        }
377        product
378    }
379
380    fn exp_biguint(&self, power: &BigUint) -> Self {
381        let mut result = Self::ONE;
382        for &digit in power.to_u64_digits().iter().rev() {
383            result = result.exp_power_of_2(64);
384            result *= self.exp_u64(digit);
385        }
386        result
387    }
388
389    /// Returns whether `x^power` is a permutation of this field.
390    fn is_monomial_permutation_u64(power: u64) -> bool {
391        match power {
392            0 => false,
393            1 => true,
394            _ => (Self::order() - 1u32).gcd(&BigUint::from(power)).is_one(),
395        }
396    }
397
398    fn kth_root_u64(&self, k: u64) -> Self {
399        let p = Self::order();
400        let p_minus_1 = &p - 1u32;
401        debug_assert!(
402            Self::is_monomial_permutation_u64(k),
403            "Not a permutation of this field"
404        );
405
406        // By Fermat's little theorem, x^p = x and x^(p - 1) = 1, so x^(p + n(p - 1)) = x for any n.
407        // Our assumption that the k'th root operation is a permutation implies gcd(p - 1, k) = 1,
408        // so there exists some n such that p + n(p - 1) is a multiple of k. Once we find such an n,
409        // we can rewrite the above as
410        //    x^((p + n(p - 1))/k)^k = x,
411        // implying that x^((p + n(p - 1))/k) is a k'th root of x.
412        for n in 0..k {
413            let numerator = &p + &p_minus_1 * n;
414            if (&numerator % k).is_zero() {
415                let power = (numerator / k) % p_minus_1;
416                return self.exp_biguint(&power);
417            }
418        }
419        panic!(
420            "x^{} and x^(1/{}) are not permutations of this field, or we have a bug!",
421            k, k
422        );
423    }
424
425    fn cube_root(&self) -> Self {
426        self.kth_root_u64(3)
427    }
428
429    fn powers(&self) -> Powers<Self> {
430        self.shifted_powers(Self::ONE)
431    }
432
433    fn shifted_powers(&self, start: Self) -> Powers<Self> {
434        Powers {
435            base: *self,
436            current: start,
437        }
438    }
439
440    /// Representative `g` of the coset used in FRI, so that LDEs in FRI are done over `gH`.
441    fn coset_shift() -> Self {
442        Self::MULTIPLICATIVE_GROUP_GENERATOR
443    }
444
445    /// Equivalent to *self + x * y, but may be cheaper.
446    #[inline]
447    fn multiply_accumulate(&self, x: Self, y: Self) -> Self {
448        // Default implementation.
449        *self + x * y
450    }
451}
452
453pub trait PrimeField: Field {
454    fn to_canonical_biguint(&self) -> BigUint;
455
456    fn is_quadratic_residue(&self) -> bool {
457        if self.is_zero() {
458            return true;
459        }
460        // This is based on Euler's criterion.
461        let power = Self::NEG_ONE.to_canonical_biguint() / 2u8;
462        let exp = self.exp_biguint(&power);
463        if exp == Self::ONE {
464            return true;
465        }
466        if exp == Self::NEG_ONE {
467            return false;
468        }
469        panic!("Unreachable")
470    }
471
472    fn sqrt(&self) -> Option<Self> {
473        if self.is_zero() {
474            Some(*self)
475        } else if self.is_quadratic_residue() {
476            let t = (Self::order() - BigUint::from(1u32))
477                / (BigUint::from(2u32).pow(Self::TWO_ADICITY as u32));
478            let mut z = Self::POWER_OF_TWO_GENERATOR;
479            let mut w = self.exp_biguint(&((t - BigUint::from(1u32)) / BigUint::from(2u32)));
480            let mut x = w * *self;
481            let mut b = x * w;
482
483            let mut v = Self::TWO_ADICITY;
484
485            while !b.is_one() {
486                let mut k = 0usize;
487                let mut b2k = b;
488                while !b2k.is_one() {
489                    b2k = b2k * b2k;
490                    k += 1;
491                }
492                let j = v - k - 1;
493                w = z;
494                for _ in 0..j {
495                    w = w * w;
496                }
497
498                z = w * w;
499                b *= z;
500                x *= w;
501                v = k;
502            }
503            Some(x)
504        } else {
505            None
506        }
507    }
508}
509
510/// A finite field of order less than 2^64.
511pub trait Field64: Field {
512    const ORDER: u64;
513
514    /// Returns `n` as an element of this field. Assumes that `0 <= n < Self::ORDER`.
515    // TODO: Move to `Field`.
516    // TODO: Should probably be unsafe.
517    #[inline]
518    fn from_canonical_i64(n: i64) -> Self {
519        Self::from_canonical_u64(n as u64)
520    }
521
522    #[inline]
523    // TODO: Move to `Field`.
524    fn add_one(&self) -> Self {
525        unsafe { self.add_canonical_u64(1) }
526    }
527
528    #[inline]
529    // TODO: Move to `Field`.
530    fn sub_one(&self) -> Self {
531        unsafe { self.sub_canonical_u64(1) }
532    }
533
534    /// # Safety
535    /// Equivalent to *self + Self::from_canonical_u64(rhs), but may be cheaper. The caller must
536    /// ensure that 0 <= rhs < Self::ORDER. The function may return incorrect results if this
537    /// precondition is not met. It is marked unsafe for this reason.
538    // TODO: Move to `Field`.
539    #[inline]
540    unsafe fn add_canonical_u64(&self, rhs: u64) -> Self {
541        // Default implementation.
542        *self + Self::from_canonical_u64(rhs)
543    }
544
545    /// # Safety
546    /// Equivalent to *self - Self::from_canonical_u64(rhs), but may be cheaper. The caller must
547    /// ensure that 0 <= rhs < Self::ORDER. The function may return incorrect results if this
548    /// precondition is not met. It is marked unsafe for this reason.
549    // TODO: Move to `Field`.
550    #[inline]
551    unsafe fn sub_canonical_u64(&self, rhs: u64) -> Self {
552        // Default implementation.
553        *self - Self::from_canonical_u64(rhs)
554    }
555}
556
557/// A finite field of prime order less than 2^64.
558pub trait PrimeField64: PrimeField + Field64 {
559    fn to_canonical_u64(&self) -> u64;
560
561    fn to_noncanonical_u64(&self) -> u64;
562
563    #[inline(always)]
564    fn to_canonical(&self) -> Self {
565        Self::from_canonical_u64(self.to_canonical_u64())
566    }
567}
568
569/// An iterator over the powers of a certain base element `b`: `b^0, b^1, b^2, ...`.
570#[must_use = "iterators are lazy and do nothing unless consumed"]
571#[derive(Clone, Debug)]
572pub struct Powers<F: Field> {
573    base: F,
574    current: F,
575}
576
577impl<F: Field> Iterator for Powers<F> {
578    type Item = F;
579
580    fn next(&mut self) -> Option<F> {
581        let result = self.current;
582        self.current *= self.base;
583        Some(result)
584    }
585
586    fn size_hint(&self) -> (usize, Option<usize>) {
587        (usize::MAX, None)
588    }
589
590    fn nth(&mut self, n: usize) -> Option<F> {
591        let result = self.current * self.base.exp_u64(n.try_into().unwrap());
592        self.current = result * self.base;
593        Some(result)
594    }
595
596    fn last(self) -> Option<F> {
597        panic!("called `Iterator::last()` on an infinite sequence")
598    }
599
600    fn count(self) -> usize {
601        panic!("called `Iterator::count()` on an infinite sequence")
602    }
603}
604
605impl<F: Field> Powers<F> {
606    /// Apply the Frobenius automorphism `k` times.
607    pub fn repeated_frobenius<const D: usize>(self, k: usize) -> Self
608    where
609        F: Frobenius<D>,
610    {
611        let Self { base, current } = self;
612        Self {
613            base: base.repeated_frobenius(k),
614            current: current.repeated_frobenius(k),
615        }
616    }
617}
618
619#[cfg(test)]
620mod tests {
621    use super::Field;
622    use crate::goldilocks_field::GoldilocksField;
623
624    #[test]
625    fn test_powers_nth() {
626        type F = GoldilocksField;
627
628        const N: usize = 10;
629        let powers_of_two: Vec<F> = F::TWO.powers().take(N).collect();
630
631        for (n, &expect) in powers_of_two.iter().enumerate() {
632            let mut iter = F::TWO.powers();
633            assert_eq!(iter.nth(n), Some(expect));
634
635            for &expect_next in &powers_of_two[n + 1..] {
636                assert_eq!(iter.next(), Some(expect_next));
637            }
638        }
639    }
640}