Skip to main content

trident/field/
babybear.rs

1//! BabyBear prime field: p = 2^31 - 2^27 + 1 = 0x7800_0001.
2//!
3//! Used by: SP1, RISC Zero, Jolt.
4//!
5//! A 31-bit prime with efficient NTT (multiplicative group order 2^27).
6
7use super::PrimeField;
8
9/// BabyBear prime: p = 2^31 - 2^27 + 1 = 2013265921.
10pub const MODULUS: u64 = 0x7800_0001;
11
12/// A BabyBear field element (u64 in [0, p), stored in lower 31 bits).
13#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
14pub struct BabyBear(pub u64);
15
16impl PrimeField for BabyBear {
17    const MODULUS: u128 = MODULUS as u128;
18    const BITS: u32 = 31;
19    const ZERO: Self = Self(0);
20    const ONE: Self = Self(1);
21
22    #[inline]
23    fn from_u64(v: u64) -> Self {
24        Self(v % MODULUS)
25    }
26
27    #[inline]
28    fn to_u64(self) -> u64 {
29        self.0
30    }
31
32    #[inline]
33    fn add(self, rhs: Self) -> Self {
34        let sum = self.0 + rhs.0;
35        Self(if sum >= MODULUS { sum - MODULUS } else { sum })
36    }
37
38    #[inline]
39    fn sub(self, rhs: Self) -> Self {
40        if self.0 >= rhs.0 {
41            Self(self.0 - rhs.0)
42        } else {
43            Self(MODULUS - rhs.0 + self.0)
44        }
45    }
46
47    #[inline]
48    fn mul(self, rhs: Self) -> Self {
49        Self(((self.0 as u128 * rhs.0 as u128) % MODULUS as u128) as u64)
50    }
51
52    #[inline]
53    fn neg(self) -> Self {
54        if self.0 == 0 {
55            Self(0)
56        } else {
57            Self(MODULUS - self.0)
58        }
59    }
60}