diff --git a/field/src/goldilocks_field.rs b/field/src/goldilocks_field.rs index e10d0c74..4432d9c4 100644 --- a/field/src/goldilocks_field.rs +++ b/field/src/goldilocks_field.rs @@ -118,22 +118,6 @@ impl Field for GoldilocksField { reduce128(n) } - #[inline] - fn multiply_accumulate(&self, x: Self, y: Self) -> Self { - // u64 + u64 * u64 cannot overflow. - reduce128((self.0 as u128) + (x.0 as u128) * (y.0 as u128)) - } -} - -impl PrimeField for GoldilocksField { - fn to_canonical_biguint(&self) -> BigUint { - self.to_canonical_u64().into() - } -} - -impl Field64 for GoldilocksField { - const ORDER: u64 = 0xFFFFFFFF00000001; - #[inline] fn from_noncanonical_u64(n: u64) -> Self { Self(n) @@ -151,6 +135,22 @@ impl Field64 for GoldilocksField { }) } + #[inline] + fn multiply_accumulate(&self, x: Self, y: Self) -> Self { + // u64 + u64 * u64 cannot overflow. + reduce128((self.0 as u128) + (x.0 as u128) * (y.0 as u128)) + } +} + +impl PrimeField for GoldilocksField { + fn to_canonical_biguint(&self) -> BigUint { + self.to_canonical_u64().into() + } +} + +impl Field64 for GoldilocksField { + const ORDER: u64 = 0xFFFFFFFF00000001; + #[inline] unsafe fn add_canonical_u64(&self, rhs: u64) -> Self { let (res_wrapped, carry) = self.0.overflowing_add(rhs); diff --git a/field/src/types.rs b/field/src/types.rs index 0ae31847..2c0d15c7 100644 --- a/field/src/types.rs +++ b/field/src/types.rs @@ -341,6 +341,26 @@ pub trait Field: /// Returns `n % Self::characteristic()`. fn from_noncanonical_u128(n: u128) -> Self; + /// Returns `x % Self::CHARACTERISTIC`. + /// + /// Implemented by default via `from_noncanonical_u128` + /// Override, if you have a faster implementation for your field. + fn from_noncanonical_u64(n: u64) -> Self { + Self::from_noncanonical_u128(n as u128) + } + + /// Returns `n` as an element of this field. + /// + /// Implemented by default via `from_noncanonical_u128` and case analysis. + /// Override, if you have a faster implementation for your field. + fn from_noncanonical_i64(n: i64) -> Self { + if n < 0 { + -Self::from_noncanonical_u128((n as i128).unsigned_abs()) + } else { + Self::from_noncanonical_u128(n as u128) + } + } + /// Returns `n % Self::characteristic()`. May be cheaper than from_noncanonical_u128 when we know /// that `n < 2 ** 96`. #[inline] @@ -501,14 +521,6 @@ pub trait PrimeField: Field { pub trait Field64: Field { const ORDER: u64; - /// Returns `x % Self::CHARACTERISTIC`. - // TODO: Move to `Field`. - fn from_noncanonical_u64(n: u64) -> Self; - - /// Returns `n` as an element of this field. - // TODO: Move to `Field`. - fn from_noncanonical_i64(n: i64) -> Self; - /// Returns `n` as an element of this field. Assumes that `0 <= n < Self::ORDER`. // TODO: Move to `Field`. // TODO: Should probably be unsafe.