diff --git a/field/src/extension/quadratic.rs b/field/src/extension/quadratic.rs index c0c9758b..281369d2 100644 --- a/field/src/extension/quadratic.rs +++ b/field/src/extension/quadratic.rs @@ -109,6 +109,14 @@ impl> Field for QuadraticExtension { fn from_noncanonical_u128(n: u128) -> Self { F::from_noncanonical_u128(n).into() } + + fn from_noncanonical_i64(n: i64) -> Self { + F::from_noncanonical_i64(n).into() + } + + fn from_noncanonical_u64(n: u64) -> Self { + F::from_noncanonical_u64(n).into() + } } impl> Display for QuadraticExtension { diff --git a/field/src/extension/quartic.rs b/field/src/extension/quartic.rs index e7aba63b..8c8a9e7e 100644 --- a/field/src/extension/quartic.rs +++ b/field/src/extension/quartic.rs @@ -119,6 +119,14 @@ impl> Field for QuarticExtension { fn from_noncanonical_u128(n: u128) -> Self { F::from_noncanonical_u128(n).into() } + + fn from_noncanonical_i64(n: i64) -> Self { + F::from_noncanonical_i64(n).into() + } + + fn from_noncanonical_u64(n: u64) -> Self { + F::from_noncanonical_u64(n).into() + } } impl> Display for QuarticExtension { diff --git a/field/src/extension/quintic.rs b/field/src/extension/quintic.rs index d4b605eb..28ec9226 100644 --- a/field/src/extension/quintic.rs +++ b/field/src/extension/quintic.rs @@ -126,6 +126,14 @@ impl> Field for QuinticExtension { fn from_noncanonical_u128(n: u128) -> Self { F::from_noncanonical_u128(n).into() } + + fn from_noncanonical_i64(n: i64) -> Self { + F::from_noncanonical_i64(n).into() + } + + fn from_noncanonical_u64(n: u64) -> Self { + F::from_noncanonical_u64(n).into() + } } impl> Display for QuinticExtension { 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/secp256k1_base.rs b/field/src/secp256k1_base.rs index eaa964f8..6632a7f8 100644 --- a/field/src/secp256k1_base.rs +++ b/field/src/secp256k1_base.rs @@ -142,6 +142,19 @@ impl Field for Secp256K1Base { fn from_noncanonical_u96(n: (u64, u32)) -> Self { Self([n.0, n.1 as u64, 0, 0]) } + + fn from_noncanonical_i64(n: i64) -> Self { + let f = Self::from_canonical_u64(n.unsigned_abs()); + if n < 0 { + -f + } else { + f + } + } + + fn from_noncanonical_u64(n: u64) -> Self { + Self::from_canonical_u64(n) + } } impl PrimeField for Secp256K1Base { diff --git a/field/src/secp256k1_scalar.rs b/field/src/secp256k1_scalar.rs index 1f1de697..3ca5b6ba 100644 --- a/field/src/secp256k1_scalar.rs +++ b/field/src/secp256k1_scalar.rs @@ -150,6 +150,19 @@ impl Field for Secp256K1Scalar { fn from_noncanonical_u96(n: (u64, u32)) -> Self { Self([n.0, n.1 as u64, 0, 0]) } + + fn from_noncanonical_i64(n: i64) -> Self { + let f = Self::from_canonical_u64(n.unsigned_abs()); + if n < 0 { + -f + } else { + f + } + } + + fn from_noncanonical_u64(n: u64) -> Self { + Self::from_canonical_u64(n) + } } impl PrimeField for Secp256K1Scalar { diff --git a/field/src/types.rs b/field/src/types.rs index 0ae31847..646dff73 100644 --- a/field/src/types.rs +++ b/field/src/types.rs @@ -341,6 +341,12 @@ pub trait Field: /// Returns `n % Self::characteristic()`. fn from_noncanonical_u128(n: u128) -> Self; + /// Returns `x % Self::CHARACTERISTIC`. + fn from_noncanonical_u64(n: u64) -> Self; + + /// Returns `n` as an element of this field. + fn from_noncanonical_i64(n: i64) -> Self; + /// Returns `n % Self::characteristic()`. May be cheaper than from_noncanonical_u128 when we know /// that `n < 2 ** 96`. #[inline] @@ -501,14 +507,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.