From 91f7b4e300abfe77f4cd3df8d4bfb3dab8999bce Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Mon, 13 Sep 2021 11:45:17 -0700 Subject: [PATCH] Replace `CrandallQuarticField` with a more generic `QuarticExtension` (#232) * Replace `CrandallQuarticField` with a more generic `QuarticExtension` And likewise for `CrandallQuadraticField`. There are a few parameters which we can't automatically derive (in const Rust), so I specified them in a `AutoExtendable` trait. This would make it fairly easy to add extension fields for `GoldilocksField` and any future fields. * Attempt to derive 2-adicity, see Hamish's feedback * Simplify TWO_ADICITY based on chat with Hamish * PR feedback * Merge AutoExtendable into Extendable (#235) --- benches/field_arithmetic.rs | 3 +- src/field/crandall_field.rs | 29 ++++- src/field/extension_field/mod.rs | 18 ++- src/field/extension_field/quadratic.rs | 134 ++++++++++---------- src/field/extension_field/quartic.rs | 169 ++++++++++--------------- src/field/field_types.rs | 2 + src/field/interpolation.rs | 4 +- src/gadgets/arithmetic_extension.rs | 8 +- src/gadgets/insert.rs | 4 +- src/gadgets/interpolation.rs | 4 +- src/gadgets/random_access.rs | 4 +- src/gadgets/select.rs | 4 +- src/gates/exponentiation.rs | 4 +- src/gates/insertion.rs | 4 +- src/gates/interpolation.rs | 4 +- src/gates/random_access.rs | 4 +- src/gates/switch.rs | 4 +- src/polynomial/division.rs | 6 +- src/util/reducing.rs | 6 +- 19 files changed, 206 insertions(+), 209 deletions(-) diff --git a/benches/field_arithmetic.rs b/benches/field_arithmetic.rs index af7c49d2..d3ebc57c 100644 --- a/benches/field_arithmetic.rs +++ b/benches/field_arithmetic.rs @@ -2,7 +2,6 @@ use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use plonky2::field::crandall_field::CrandallField; -use plonky2::field::extension_field::quartic::QuarticCrandallField; use plonky2::field::field_types::Field; use plonky2::field::goldilocks_field::GoldilocksField; use tynm::type_name; @@ -92,7 +91,7 @@ pub(crate) fn bench_field(c: &mut Criterion) { fn criterion_benchmark(c: &mut Criterion) { bench_field::(c); bench_field::(c); - bench_field::(c); + bench_field::>(c); } criterion_group!(benches, criterion_benchmark); diff --git a/src/field/crandall_field.rs b/src/field/crandall_field.rs index d2227d80..fdb39241 100644 --- a/src/field/crandall_field.rs +++ b/src/field/crandall_field.rs @@ -8,8 +8,8 @@ use num::bigint::BigUint; use rand::Rng; use serde::{Deserialize, Serialize}; -use crate::field::extension_field::quadratic::QuadraticCrandallField; -use crate::field::extension_field::quartic::QuarticCrandallField; +use crate::field::extension_field::quadratic::QuadraticExtension; +use crate::field::extension_field::quartic::QuarticExtension; use crate::field::extension_field::{Extendable, Frobenius}; use crate::field::field_types::{Field, PrimeField, RichField}; use crate::field::inversion::try_inverse_u64; @@ -287,11 +287,32 @@ impl DivAssign for CrandallField { } impl Extendable<2> for CrandallField { - type Extension = QuadraticCrandallField; + type Extension = QuadraticExtension; + + // Verifiable in Sage with + // `R. = GF(p)[]; assert (x^2 - 3).is_irreducible()`. + const W: Self = Self(3); + + const EXT_MULTIPLICATIVE_GROUP_GENERATOR: [Self; 2] = + [Self(6483724566312148654), Self(12194665049945415126)]; + + const EXT_POWER_OF_TWO_GENERATOR: [Self; 2] = [Self(0), Self(14420468973723774561)]; } impl Extendable<4> for CrandallField { - type Extension = QuarticCrandallField; + type Extension = QuarticExtension; + + const W: Self = Self(3); + + const EXT_MULTIPLICATIVE_GROUP_GENERATOR: [Self; 4] = [ + Self(12476589904174392631), + Self(896937834427772243), + Self(7795248119019507390), + Self(9005769437373554825), + ]; + + const EXT_POWER_OF_TWO_GENERATOR: [Self; 4] = + [Self(0), Self(0), Self(0), Self(15170983443234254033)]; } impl RichField for CrandallField {} diff --git a/src/field/extension_field/mod.rs b/src/field/extension_field/mod.rs index 8c89227e..7e5ea228 100644 --- a/src/field/extension_field/mod.rs +++ b/src/field/extension_field/mod.rs @@ -1,6 +1,6 @@ use std::convert::TryInto; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; pub mod algebra; pub mod quadratic; @@ -45,12 +45,24 @@ pub trait Frobenius: OEF { } } -pub trait Extendable: Field + Sized { +pub trait Extendable: PrimeField + Sized { type Extension: Field + OEF + Frobenius + From; + + const W: Self; + + const EXT_MULTIPLICATIVE_GROUP_GENERATOR: [Self; D]; + + /// Chosen so that when raised to the power `1<<(Self::TWO_ADICITY-Self::BaseField::TWO_ADICITY)`, + /// we get `Self::BaseField::POWER_OF_TWO_GENERATOR`. This makes `primitive_root_of_unity` coherent + /// with the base field which implies that the FFT commutes with field inclusion. + const EXT_POWER_OF_TWO_GENERATOR: [Self; D]; } -impl + FieldExtension<1, BaseField = F>> Extendable<1> for F { +impl + FieldExtension<1, BaseField = F>> Extendable<1> for F { type Extension = F; + const W: Self = F::ZERO; + const EXT_MULTIPLICATIVE_GROUP_GENERATOR: [Self; 1] = [F::MULTIPLICATIVE_GROUP_GENERATOR]; + const EXT_POWER_OF_TWO_GENERATOR: [Self; 1] = [F::POWER_OF_TWO_GENERATOR]; } pub trait FieldExtension: Field { diff --git a/src/field/extension_field/quadratic.rs b/src/field/extension_field/quadratic.rs index c0febe33..b49a1649 100644 --- a/src/field/extension_field/quadratic.rs +++ b/src/field/extension_field/quadratic.rs @@ -6,71 +6,67 @@ use num::bigint::BigUint; use rand::Rng; use serde::{Deserialize, Serialize}; -use crate::field::crandall_field::CrandallField; -use crate::field::extension_field::{FieldExtension, Frobenius, OEF}; +use crate::field::extension_field::{Extendable, FieldExtension, Frobenius, OEF}; use crate::field::field_types::Field; #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] -pub struct QuadraticCrandallField([CrandallField; 2]); +#[serde(bound = "")] +pub struct QuadraticExtension>(pub(crate) [F; 2]); -impl Default for QuadraticCrandallField { +impl> Default for QuadraticExtension { fn default() -> Self { Self::ZERO } } -impl OEF<2> for QuadraticCrandallField { - // Verifiable in Sage with - // ``R. = GF(p)[]; assert (x^2 -3).is_irreducible()`. - const W: CrandallField = CrandallField(3); +impl> OEF<2> for QuadraticExtension { + const W: F = F::W; } -impl Frobenius<2> for QuadraticCrandallField {} +impl> Frobenius<2> for QuadraticExtension {} -impl FieldExtension<2> for QuadraticCrandallField { - type BaseField = CrandallField; +impl> FieldExtension<2> for QuadraticExtension { + type BaseField = F; - fn to_basefield_array(&self) -> [Self::BaseField; 2] { + fn to_basefield_array(&self) -> [F; 2] { self.0 } - fn from_basefield_array(arr: [Self::BaseField; 2]) -> Self { + fn from_basefield_array(arr: [F; 2]) -> Self { Self(arr) } - fn from_basefield(x: Self::BaseField) -> Self { + fn from_basefield(x: F) -> Self { x.into() } } -impl From<>::BaseField> for QuadraticCrandallField { - fn from(x: >::BaseField) -> Self { - Self([x, >::BaseField::ZERO]) +impl> From for QuadraticExtension { + fn from(x: F) -> Self { + Self([x, F::ZERO]) } } -impl Field for QuadraticCrandallField { - type PrimeField = CrandallField; +impl> Field for QuadraticExtension { + type PrimeField = F; - const ZERO: Self = Self([CrandallField::ZERO; 2]); - const ONE: Self = Self([CrandallField::ONE, CrandallField::ZERO]); - const TWO: Self = Self([CrandallField::TWO, CrandallField::ZERO]); - const NEG_ONE: Self = Self([CrandallField::NEG_ONE, CrandallField::ZERO]); + const ZERO: Self = Self([F::ZERO; 2]); + const ONE: Self = Self([F::ONE, F::ZERO]); + const TWO: Self = Self([F::TWO, F::ZERO]); + const NEG_ONE: Self = Self([F::NEG_ONE, F::ZERO]); - const CHARACTERISTIC: u64 = CrandallField::CHARACTERISTIC; - const TWO_ADICITY: usize = 29; - const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self([ - CrandallField(6483724566312148654), - CrandallField(12194665049945415126), - ]); - // Chosen so that when raised to the power `1<<(Self::TWO_ADICITY-Self::BaseField::TWO_ADICITY)`, - // we get `Self::BaseField::POWER_OF_TWO_GENERATOR`. This makes `primitive_root_of_unity` coherent - // with the base field which implies that the FFT commutes with field inclusion. - const POWER_OF_TWO_GENERATOR: Self = - Self([CrandallField::ZERO, CrandallField(14420468973723774561)]); + const CHARACTERISTIC: u64 = F::CHARACTERISTIC; + + // `p^2 - 1 = (p - 1)(p + 1)`. The `p - 1` term has a two-adicity of `F::TWO_ADICITY`. As + // long as `F::TWO_ADICITY >= 2`, `p` can be written as `4n + 1`, so `p + 1` can be written as + // `2(2n + 1)`, which has a 2-adicity of 1. + const TWO_ADICITY: usize = F::TWO_ADICITY + 1; + + const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self(F::EXT_MULTIPLICATIVE_GROUP_GENERATOR); + const POWER_OF_TWO_GENERATOR: Self = Self(F::EXT_POWER_OF_TWO_GENERATOR); fn order() -> BigUint { - CrandallField::order() * CrandallField::order() + F::order() * F::order() } // Algorithm 11.3.4 in Handbook of Elliptic and Hyperelliptic Curve Cryptography. @@ -90,34 +86,31 @@ impl Field for QuadraticCrandallField { } fn from_canonical_u64(n: u64) -> Self { - >::BaseField::from_canonical_u64(n).into() + F::from_canonical_u64(n).into() } fn from_noncanonical_u128(n: u128) -> Self { - >::BaseField::from_noncanonical_u128(n).into() + F::from_noncanonical_u128(n).into() } fn rand_from_rng(rng: &mut R) -> Self { - Self([ - >::BaseField::rand_from_rng(rng), - >::BaseField::rand_from_rng(rng), - ]) + Self([F::rand_from_rng(rng), F::rand_from_rng(rng)]) } } -impl Display for QuadraticCrandallField { +impl> Display for QuadraticExtension { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{} + {}*a", self.0[0], self.0[1]) } } -impl Debug for QuadraticCrandallField { +impl> Debug for QuadraticExtension { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { Display::fmt(self, f) } } -impl Neg for QuadraticCrandallField { +impl> Neg for QuadraticExtension { type Output = Self; #[inline] @@ -126,7 +119,7 @@ impl Neg for QuadraticCrandallField { } } -impl Add for QuadraticCrandallField { +impl> Add for QuadraticExtension { type Output = Self; #[inline] @@ -135,19 +128,19 @@ impl Add for QuadraticCrandallField { } } -impl AddAssign for QuadraticCrandallField { +impl> AddAssign for QuadraticExtension { fn add_assign(&mut self, rhs: Self) { *self = *self + rhs; } } -impl Sum for QuadraticCrandallField { +impl> Sum for QuadraticExtension { fn sum>(iter: I) -> Self { iter.fold(Self::ZERO, |acc, x| acc + x) } } -impl Sub for QuadraticCrandallField { +impl> Sub for QuadraticExtension { type Output = Self; #[inline] @@ -156,14 +149,14 @@ impl Sub for QuadraticCrandallField { } } -impl SubAssign for QuadraticCrandallField { +impl> SubAssign for QuadraticExtension { #[inline] fn sub_assign(&mut self, rhs: Self) { *self = *self - rhs; } } -impl Mul for QuadraticCrandallField { +impl> Mul for QuadraticExtension { type Output = Self; #[inline] @@ -178,20 +171,20 @@ impl Mul for QuadraticCrandallField { } } -impl MulAssign for QuadraticCrandallField { +impl> MulAssign for QuadraticExtension { #[inline] fn mul_assign(&mut self, rhs: Self) { *self = *self * rhs; } } -impl Product for QuadraticCrandallField { +impl> Product for QuadraticExtension { fn product>(iter: I) -> Self { iter.fold(Self::ONE, |acc, x| acc * x) } } -impl Div for QuadraticCrandallField { +impl> Div for QuadraticExtension { type Output = Self; #[allow(clippy::suspicious_arithmetic_impl)] @@ -200,7 +193,7 @@ impl Div for QuadraticCrandallField { } } -impl DivAssign for QuadraticCrandallField { +impl> DivAssign for QuadraticExtension { fn div_assign(&mut self, rhs: Self) { *self = *self / rhs; } @@ -208,20 +201,21 @@ impl DivAssign for QuadraticCrandallField { #[cfg(test)] mod tests { - use crate::field::extension_field::quadratic::QuadraticCrandallField; - use crate::field::extension_field::{FieldExtension, Frobenius}; + use crate::field::crandall_field::CrandallField; + use crate::field::extension_field::quadratic::QuadraticExtension; + use crate::field::extension_field::Frobenius; use crate::field::field_types::Field; use crate::test_field_arithmetic; #[test] fn test_add_neg_sub_mul() { - type F = QuadraticCrandallField; + type F = QuadraticExtension; let x = F::rand(); let y = F::rand(); let z = F::rand(); assert_eq!(x + (-x), F::ZERO); assert_eq!(-x, F::ZERO - x); - assert_eq!(x + x, x * >::BaseField::TWO.into()); + assert_eq!(x + x, x * F::TWO); assert_eq!(x * (-x), -x.square()); assert_eq!(x + y, y + x); assert_eq!(x * y, y * x); @@ -233,7 +227,7 @@ mod tests { #[test] fn test_inv_div() { - type F = QuadraticCrandallField; + type F = QuadraticExtension; let x = F::rand(); let y = F::rand(); let z = F::rand(); @@ -247,18 +241,15 @@ mod tests { #[test] fn test_frobenius() { - type F = QuadraticCrandallField; + type F = QuadraticExtension; let x = F::rand(); - assert_eq!( - x.exp_biguint(&>::BaseField::order()), - x.frobenius() - ); + assert_eq!(x.exp_biguint(&CrandallField::order()), x.frobenius()); } #[test] fn test_field_order() { // F::order() = 340282366831806780677557380898690695169 = 18446744071293632512 *18446744071293632514 + 1 - type F = QuadraticCrandallField; + type F = QuadraticExtension; let x = F::rand(); assert_eq!( x.exp_u64(18446744071293632512) @@ -269,7 +260,7 @@ mod tests { #[test] fn test_power_of_two_gen() { - type F = QuadraticCrandallField; + type F = QuadraticExtension; // F::order() = 2^29 * 2762315674048163 * 229454332791453 + 1 assert_eq!( F::MULTIPLICATIVE_GROUP_GENERATOR @@ -278,11 +269,14 @@ mod tests { F::POWER_OF_TWO_GENERATOR ); assert_eq!( - F::POWER_OF_TWO_GENERATOR - .exp_u64(1 << (F::TWO_ADICITY - >::BaseField::TWO_ADICITY)), - >::BaseField::POWER_OF_TWO_GENERATOR.into() + F::POWER_OF_TWO_GENERATOR.exp_u64(1 << (F::TWO_ADICITY - CrandallField::TWO_ADICITY)), + CrandallField::POWER_OF_TWO_GENERATOR.into() ); } - test_field_arithmetic!(crate::field::extension_field::quadratic::QuadraticCrandallField); + test_field_arithmetic!( + crate::field::extension_field::quadratic::QuadraticExtension< + crate::field::crandall_field::CrandallField, + > + ); } diff --git a/src/field/extension_field/quartic.rs b/src/field/extension_field/quartic.rs index 1e92a8fa..e89a7be5 100644 --- a/src/field/extension_field/quartic.rs +++ b/src/field/extension_field/quartic.rs @@ -7,100 +7,68 @@ use num::traits::Pow; use rand::Rng; use serde::{Deserialize, Serialize}; -use crate::field::crandall_field::CrandallField; -use crate::field::extension_field::{FieldExtension, Frobenius, OEF}; +use crate::field::extension_field::{Extendable, FieldExtension, Frobenius, OEF}; use crate::field::field_types::Field; -/// A quartic extension of `CrandallField`. #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] -pub struct QuarticCrandallField(pub(crate) [CrandallField; 4]); +#[serde(bound = "")] +pub struct QuarticExtension>(pub(crate) [F; 4]); -impl Default for QuarticCrandallField { +impl> Default for QuarticExtension { fn default() -> Self { Self::ZERO } } -impl OEF<4> for QuarticCrandallField { - // Verifiable in Sage with - // R. = GF(p)[] - // assert (x^4 - 3).is_irreducible() - const W: CrandallField = CrandallField(3); +impl> OEF<4> for QuarticExtension { + const W: F = F::W; } -impl Frobenius<4> for QuarticCrandallField {} +impl> Frobenius<4> for QuarticExtension {} -impl FieldExtension<4> for QuarticCrandallField { - type BaseField = CrandallField; +impl> FieldExtension<4> for QuarticExtension { + type BaseField = F; - fn to_basefield_array(&self) -> [Self::BaseField; 4] { + fn to_basefield_array(&self) -> [F; 4] { self.0 } - fn from_basefield_array(arr: [Self::BaseField; 4]) -> Self { + fn from_basefield_array(arr: [F; 4]) -> Self { Self(arr) } - fn from_basefield(x: Self::BaseField) -> Self { + fn from_basefield(x: F) -> Self { x.into() } } -impl From<>::BaseField> for QuarticCrandallField { - fn from(x: >::BaseField) -> Self { - Self([ - x, - >::BaseField::ZERO, - >::BaseField::ZERO, - >::BaseField::ZERO, - ]) +impl> From for QuarticExtension { + fn from(x: F) -> Self { + Self([x, F::ZERO, F::ZERO, F::ZERO]) } } -impl Field for QuarticCrandallField { - type PrimeField = CrandallField; +impl> Field for QuarticExtension { + type PrimeField = F; - const ZERO: Self = Self([CrandallField::ZERO; 4]); - const ONE: Self = Self([ - CrandallField::ONE, - CrandallField::ZERO, - CrandallField::ZERO, - CrandallField::ZERO, - ]); - const TWO: Self = Self([ - CrandallField::TWO, - CrandallField::ZERO, - CrandallField::ZERO, - CrandallField::ZERO, - ]); - const NEG_ONE: Self = Self([ - CrandallField::NEG_ONE, - CrandallField::ZERO, - CrandallField::ZERO, - CrandallField::ZERO, - ]); + const ZERO: Self = Self([F::ZERO; 4]); + const ONE: Self = Self([F::ONE, F::ZERO, F::ZERO, F::ZERO]); + const TWO: Self = Self([F::TWO, F::ZERO, F::ZERO, F::ZERO]); + const NEG_ONE: Self = Self([F::NEG_ONE, F::ZERO, F::ZERO, F::ZERO]); - const CHARACTERISTIC: u64 = CrandallField::CHARACTERISTIC; - // Does not fit in 64-bits. - const TWO_ADICITY: usize = 30; - const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self([ - CrandallField(12476589904174392631), - CrandallField(896937834427772243), - CrandallField(7795248119019507390), - CrandallField(9005769437373554825), - ]); - // Chosen so that when raised to the power `1<<(Self::TWO_ADICITY-Self::BaseField::TWO_ADICITY)`, - // we get `Self::BaseField::POWER_OF_TWO_GENERATOR`. This makes `primitive_root_of_unity` coherent - // with the base field which implies that the FFT commutes with field inclusion. - const POWER_OF_TWO_GENERATOR: Self = Self([ - CrandallField::ZERO, - CrandallField::ZERO, - CrandallField::ZERO, - CrandallField(15170983443234254033), - ]); + const CHARACTERISTIC: u64 = F::ORDER; + + // `p^4 - 1 = (p - 1)(p + 1)(p^2 + 1)`. The `p - 1` term has a two-adicity of `F::TWO_ADICITY`. + // As long as `F::TWO_ADICITY >= 2`, `p` can be written as `4n + 1`, so `p + 1` can be written as + // `2(2n + 1)`, which has a 2-adicity of 1. A similar argument can show that `p^2 + 1` also has + // a 2-adicity of 1. + const TWO_ADICITY: usize = F::TWO_ADICITY + 2; + + const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self(F::EXT_MULTIPLICATIVE_GROUP_GENERATOR); + const POWER_OF_TWO_GENERATOR: Self = Self(F::EXT_POWER_OF_TWO_GENERATOR); fn order() -> BigUint { - CrandallField::order().pow(4u32) + F::order().pow(4u32) } // Algorithm 11.3.4 in Handbook of Elliptic and Hyperelliptic Curve Cryptography. @@ -123,24 +91,24 @@ impl Field for QuarticCrandallField { } fn from_canonical_u64(n: u64) -> Self { - >::BaseField::from_canonical_u64(n).into() + F::from_canonical_u64(n).into() } fn from_noncanonical_u128(n: u128) -> Self { - >::BaseField::from_noncanonical_u128(n).into() + F::from_noncanonical_u128(n).into() } fn rand_from_rng(rng: &mut R) -> Self { - Self([ - >::BaseField::rand_from_rng(rng), - >::BaseField::rand_from_rng(rng), - >::BaseField::rand_from_rng(rng), - >::BaseField::rand_from_rng(rng), + Self::from_basefield_array([ + F::rand_from_rng(rng), + F::rand_from_rng(rng), + F::rand_from_rng(rng), + F::rand_from_rng(rng), ]) } } -impl Display for QuarticCrandallField { +impl> Display for QuarticExtension { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!( f, @@ -150,13 +118,13 @@ impl Display for QuarticCrandallField { } } -impl Debug for QuarticCrandallField { +impl> Debug for QuarticExtension { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { Display::fmt(self, f) } } -impl Neg for QuarticCrandallField { +impl> Neg for QuarticExtension { type Output = Self; #[inline] @@ -165,7 +133,7 @@ impl Neg for QuarticCrandallField { } } -impl Add for QuarticCrandallField { +impl> Add for QuarticExtension { type Output = Self; #[inline] @@ -179,19 +147,19 @@ impl Add for QuarticCrandallField { } } -impl AddAssign for QuarticCrandallField { +impl> AddAssign for QuarticExtension { fn add_assign(&mut self, rhs: Self) { *self = *self + rhs; } } -impl Sum for QuarticCrandallField { +impl> Sum for QuarticExtension { fn sum>(iter: I) -> Self { iter.fold(Self::ZERO, |acc, x| acc + x) } } -impl Sub for QuarticCrandallField { +impl> Sub for QuarticExtension { type Output = Self; #[inline] @@ -205,14 +173,14 @@ impl Sub for QuarticCrandallField { } } -impl SubAssign for QuarticCrandallField { +impl> SubAssign for QuarticExtension { #[inline] fn sub_assign(&mut self, rhs: Self) { *self = *self - rhs; } } -impl Mul for QuarticCrandallField { +impl> Mul for QuarticExtension { type Output = Self; #[inline] @@ -229,20 +197,20 @@ impl Mul for QuarticCrandallField { } } -impl MulAssign for QuarticCrandallField { +impl> MulAssign for QuarticExtension { #[inline] fn mul_assign(&mut self, rhs: Self) { *self = *self * rhs; } } -impl Product for QuarticCrandallField { +impl> Product for QuarticExtension { fn product>(iter: I) -> Self { iter.fold(Self::ONE, |acc, x| acc * x) } } -impl Div for QuarticCrandallField { +impl> Div for QuarticExtension { type Output = Self; #[allow(clippy::suspicious_arithmetic_impl)] @@ -251,7 +219,7 @@ impl Div for QuarticCrandallField { } } -impl DivAssign for QuarticCrandallField { +impl> DivAssign for QuarticExtension { fn div_assign(&mut self, rhs: Self) { *self = *self / rhs; } @@ -259,8 +227,9 @@ impl DivAssign for QuarticCrandallField { #[cfg(test)] mod tests { - use crate::field::extension_field::quartic::QuarticCrandallField; - use crate::field::extension_field::{FieldExtension, Frobenius}; + use crate::field::crandall_field::CrandallField; + use crate::field::extension_field::quartic::QuarticExtension; + use crate::field::extension_field::Frobenius; use crate::field::field_types::Field; use crate::test_field_arithmetic; @@ -279,13 +248,13 @@ mod tests { #[test] fn test_add_neg_sub_mul() { - type F = QuarticCrandallField; + type F = QuarticExtension; let x = F::rand(); let y = F::rand(); let z = F::rand(); assert_eq!(x + (-x), F::ZERO); assert_eq!(-x, F::ZERO - x); - assert_eq!(x + x, x * >::BaseField::TWO.into()); + assert_eq!(x + x, x * F::TWO.into()); assert_eq!(x * (-x), -x.square()); assert_eq!(x + y, y + x); assert_eq!(x * y, y * x); @@ -297,7 +266,7 @@ mod tests { #[test] fn test_inv_div() { - type F = QuarticCrandallField; + type F = QuarticExtension; let x = F::rand(); let y = F::rand(); let z = F::rand(); @@ -311,13 +280,10 @@ mod tests { #[test] fn test_frobenius() { - type F = QuarticCrandallField; + type F = QuarticExtension; const D: usize = 4; let x = F::rand(); - assert_eq!( - x.exp_biguint(&>::BaseField::order()), - x.frobenius() - ); + assert_eq!(x.exp_biguint(&CrandallField::order()), x.frobenius()); for count in 2..D { assert_eq!( x.repeated_frobenius(count), @@ -329,7 +295,7 @@ mod tests { #[test] fn test_field_order() { // F::order() = 340282366831806780677557380898690695168 * 340282366831806780677557380898690695170 + 1 - type F = QuarticCrandallField; + type F = QuarticExtension; let x = F::rand(); assert_eq!( exp_naive( @@ -342,7 +308,7 @@ mod tests { #[test] fn test_power_of_two_gen() { - type F = QuarticCrandallField; + type F = QuarticExtension; // F::order() = 2^30 * 1090552343587053358839971118999869 * 98885475095492590491252558464653635 + 1 assert_eq!( exp_naive( @@ -355,11 +321,14 @@ mod tests { F::POWER_OF_TWO_GENERATOR ); assert_eq!( - F::POWER_OF_TWO_GENERATOR - .exp_u64(1 << (F::TWO_ADICITY - >::BaseField::TWO_ADICITY)), - >::BaseField::POWER_OF_TWO_GENERATOR.into() + F::POWER_OF_TWO_GENERATOR.exp_u64(1 << (F::TWO_ADICITY - CrandallField::TWO_ADICITY)), + CrandallField::POWER_OF_TWO_GENERATOR.into() ); } - test_field_arithmetic!(crate::field::extension_field::quartic::QuarticCrandallField); + test_field_arithmetic!( + crate::field::extension_field::quartic::QuarticExtension< + crate::field::crandall_field::CrandallField, + > + ); } diff --git a/src/field/field_types.rs b/src/field/field_types.rs index 3fb214e0..0ea24509 100644 --- a/src/field/field_types.rs +++ b/src/field/field_types.rs @@ -51,6 +51,8 @@ pub trait Field: const NEG_ONE: Self; const CHARACTERISTIC: u64; + + /// The 2-adicity of this field's multiplicative group. const TWO_ADICITY: usize; /// Generator of the entire multiplicative group, i.e. all non-zero elements. diff --git a/src/field/interpolation.rs b/src/field/interpolation.rs index 69cb3b53..f4e7c600 100644 --- a/src/field/interpolation.rs +++ b/src/field/interpolation.rs @@ -78,7 +78,7 @@ pub fn interpolate2(points: [(F, F); 2], x: F) -> F { mod tests { use super::*; use crate::field::crandall_field::CrandallField; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::field::field_types::Field; use crate::polynomial::polynomial::PolynomialCoeffs; @@ -132,7 +132,7 @@ mod tests { #[test] fn test_interpolate2() { - type F = QuarticCrandallField; + type F = QuarticExtension; let points = [(F::rand(), F::rand()), (F::rand(), F::rand())]; let x = F::rand(); diff --git a/src/gadgets/arithmetic_extension.rs b/src/gadgets/arithmetic_extension.rs index d7d668a6..af838ab6 100644 --- a/src/gadgets/arithmetic_extension.rs +++ b/src/gadgets/arithmetic_extension.rs @@ -504,7 +504,7 @@ mod tests { use crate::field::crandall_field::CrandallField; use crate::field::extension_field::algebra::ExtensionAlgebra; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::field::field_types::Field; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; @@ -514,7 +514,7 @@ mod tests { #[test] fn test_mul_many() -> Result<()> { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; const D: usize = 4; let config = CircuitConfig::large_config(); @@ -549,7 +549,7 @@ mod tests { #[test] fn test_div_extension() -> Result<()> { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; const D: usize = 4; let config = CircuitConfig::large_zk_config(); @@ -577,7 +577,7 @@ mod tests { #[test] fn test_mul_algebra() -> Result<()> { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; const D: usize = 4; let config = CircuitConfig::large_config(); diff --git a/src/gadgets/insert.rs b/src/gadgets/insert.rs index f7a8d82f..2963d52f 100644 --- a/src/gadgets/insert.rs +++ b/src/gadgets/insert.rs @@ -44,7 +44,7 @@ mod tests { use super::*; use crate::field::crandall_field::CrandallField; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::field::field_types::Field; use crate::iop::witness::PartialWitness; use crate::plonk::circuit_data::CircuitConfig; @@ -62,7 +62,7 @@ mod tests { fn test_insert_given_len(len_log: usize) -> Result<()> { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; let len = 1 << len_log; let config = CircuitConfig::large_config(); let pw = PartialWitness::new(); diff --git a/src/gadgets/interpolation.rs b/src/gadgets/interpolation.rs index 94fa7525..f5a90b0b 100644 --- a/src/gadgets/interpolation.rs +++ b/src/gadgets/interpolation.rs @@ -36,7 +36,7 @@ mod tests { use anyhow::Result; use crate::field::crandall_field::CrandallField; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::field::extension_field::FieldExtension; use crate::field::field_types::Field; use crate::field::interpolation::interpolant; @@ -48,7 +48,7 @@ mod tests { #[test] fn test_interpolate() -> Result<()> { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; let config = CircuitConfig::large_config(); let pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); diff --git a/src/gadgets/random_access.rs b/src/gadgets/random_access.rs index 1cd44db0..13e42ab8 100644 --- a/src/gadgets/random_access.rs +++ b/src/gadgets/random_access.rs @@ -56,7 +56,7 @@ mod tests { use super::*; use crate::field::crandall_field::CrandallField; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::field::field_types::Field; use crate::iop::witness::PartialWitness; use crate::plonk::circuit_data::CircuitConfig; @@ -64,7 +64,7 @@ mod tests { fn test_random_access_given_len(len_log: usize) -> Result<()> { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; let len = 1 << len_log; let config = CircuitConfig::large_config(); let pw = PartialWitness::new(); diff --git a/src/gadgets/select.rs b/src/gadgets/select.rs index 1e76eeb2..844fef25 100644 --- a/src/gadgets/select.rs +++ b/src/gadgets/select.rs @@ -42,7 +42,7 @@ mod tests { use anyhow::Result; use crate::field::crandall_field::CrandallField; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::field::field_types::Field; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; @@ -52,7 +52,7 @@ mod tests { #[test] fn test_select() -> Result<()> { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; let config = CircuitConfig::large_config(); let mut pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); diff --git a/src/gates/exponentiation.rs b/src/gates/exponentiation.rs index 0fc40044..99f94a35 100644 --- a/src/gates/exponentiation.rs +++ b/src/gates/exponentiation.rs @@ -267,7 +267,7 @@ mod tests { use rand::Rng; use crate::field::crandall_field::CrandallField; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::field::field_types::Field; use crate::gates::exponentiation::ExponentiationGate; use crate::gates::gate::Gate; @@ -315,7 +315,7 @@ mod tests { #[test] fn test_gate_constraint() { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; const D: usize = 4; /// Returns the local wires for an exponentiation gate given the base, power, and power bit diff --git a/src/gates/insertion.rs b/src/gates/insertion.rs index 9f1c9ac6..fc33307f 100644 --- a/src/gates/insertion.rs +++ b/src/gates/insertion.rs @@ -325,7 +325,7 @@ mod tests { use anyhow::Result; use crate::field::crandall_field::CrandallField; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::field::field_types::Field; use crate::gates::gate::Gate; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; @@ -365,7 +365,7 @@ mod tests { #[test] fn test_gate_constraint() { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; const D: usize = 4; /// Returns the local wires for an insertion gate given the original vector, element to diff --git a/src/gates/interpolation.rs b/src/gates/interpolation.rs index a51b797d..a67c5287 100644 --- a/src/gates/interpolation.rs +++ b/src/gates/interpolation.rs @@ -290,7 +290,7 @@ mod tests { use anyhow::Result; use crate::field::crandall_field::CrandallField; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::field::field_types::Field; use crate::gates::gate::Gate; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; @@ -332,7 +332,7 @@ mod tests { #[test] fn test_gate_constraint() { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; const D: usize = 4; /// Returns the local wires for an interpolation gate for given coeffs, points and eval point. diff --git a/src/gates/random_access.rs b/src/gates/random_access.rs index 00b189b3..283a6a1b 100644 --- a/src/gates/random_access.rs +++ b/src/gates/random_access.rs @@ -255,7 +255,7 @@ mod tests { use anyhow::Result; use crate::field::crandall_field::CrandallField; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::field::field_types::Field; use crate::gates::gate::Gate; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; @@ -293,7 +293,7 @@ mod tests { #[test] fn test_gate_constraint() { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; const D: usize = 4; /// Returns the local wires for a random access gate given the vector, element to compare, diff --git a/src/gates/switch.rs b/src/gates/switch.rs index 732b6674..1df5fea9 100644 --- a/src/gates/switch.rs +++ b/src/gates/switch.rs @@ -308,7 +308,7 @@ mod tests { use anyhow::Result; use crate::field::crandall_field::CrandallField; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::field::field_types::Field; use crate::gates::gate::Gate; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; @@ -363,7 +363,7 @@ mod tests { #[test] fn test_gate_constraint() { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; const D: usize = 4; const CHUNK_SIZE: usize = 4; let num_copies = 3; diff --git a/src/polynomial/division.rs b/src/polynomial/division.rs index 6af6ca1a..0410bec1 100644 --- a/src/polynomial/division.rs +++ b/src/polynomial/division.rs @@ -185,7 +185,7 @@ mod tests { use std::time::Instant; use crate::field::crandall_field::CrandallField; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::field::field_types::Field; use crate::polynomial::polynomial::PolynomialCoeffs; @@ -220,7 +220,7 @@ mod tests { #[test] #[ignore] fn test_division_by_linear() { - type F = QuarticCrandallField; + type F = QuarticExtension; let n = 1_000_000; let poly = PolynomialCoeffs::new(F::rand_vec(n)); let z = F::rand(); @@ -245,7 +245,7 @@ mod tests { #[test] #[ignore] fn test_division_by_quadratic() { - type F = QuarticCrandallField; + type F = QuarticExtension; let n = 1_000_000; let poly = PolynomialCoeffs::new(F::rand_vec(n)); let quad = PolynomialCoeffs::new(F::rand_vec(2)); diff --git a/src/util/reducing.rs b/src/util/reducing.rs index a0bbafe4..3fc0845c 100644 --- a/src/util/reducing.rs +++ b/src/util/reducing.rs @@ -188,14 +188,14 @@ mod tests { use super::*; use crate::field::crandall_field::CrandallField; - use crate::field::extension_field::quartic::QuarticCrandallField; + use crate::field::extension_field::quartic::QuarticExtension; use crate::iop::witness::PartialWitness; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::verifier::verify; fn test_reduce_gadget_base(n: usize) -> Result<()> { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; const D: usize = 4; let config = CircuitConfig::large_config(); @@ -223,7 +223,7 @@ mod tests { fn test_reduce_gadget(n: usize) -> Result<()> { type F = CrandallField; - type FF = QuarticCrandallField; + type FF = QuarticExtension; const D: usize = 4; let config = CircuitConfig::large_config();