mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-16 20:53:10 +00:00
Remove useless Qua(d)r(a)ticFieldExtension traits
This commit is contained in:
parent
84e9573c84
commit
66d6f3c338
@ -12,7 +12,7 @@ type F = CrandallField;
|
||||
// from wire polynomials which "store" the outputs of S-boxes in our Poseidon gate.
|
||||
const NUM_LDES: usize = 8 + 8 + 3 + 86 + 3 + 8;
|
||||
|
||||
const DEGREE: usize = 1 << 14;
|
||||
const DEGREE: usize = 1 << 13;
|
||||
|
||||
const RATE_BITS: usize = 3;
|
||||
|
||||
|
||||
@ -1,10 +1,31 @@
|
||||
use crate::field::extension_field::quadratic::QuadraticFieldExtension;
|
||||
use crate::field::extension_field::quartic::QuarticFieldExtension;
|
||||
use crate::field::field::Field;
|
||||
|
||||
pub mod quadratic;
|
||||
pub mod quartic;
|
||||
|
||||
/// Optimal extension field trait.
|
||||
/// A degree `d` field extension is optimal if there exists a base field element `W`,
|
||||
/// such that the extension is `F[X]/(X^d-W)`.
|
||||
pub trait OEF<const D: usize>: FieldExtension<D> {
|
||||
// Element W of BaseField, such that `X^d - W` is irreducible over BaseField.
|
||||
const W: Self::BaseField;
|
||||
|
||||
/// Frobenius automorphisms: x -> x^p, where p is the order of BaseField.
|
||||
fn frobenius(&self) -> Self {
|
||||
let arr = self.to_basefield_array();
|
||||
let k = (Self::BaseField::ORDER - 1) / (D as u64);
|
||||
let z0 = Self::W.exp(k);
|
||||
let mut z = Self::BaseField::ONE;
|
||||
let mut res = [Self::BaseField::ZERO; D];
|
||||
for i in 0..D {
|
||||
res[i] = arr[i] * z;
|
||||
z *= z0;
|
||||
}
|
||||
|
||||
Self::from_basefield_array(res)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Extendable<const D: usize>: Sized {
|
||||
type Extension: Field + FieldExtension<D, BaseField = Self> + From<Self>;
|
||||
}
|
||||
@ -21,6 +42,10 @@ pub trait FieldExtension<const D: usize>: Field {
|
||||
fn from_basefield_array(arr: [Self::BaseField; D]) -> Self;
|
||||
|
||||
fn from_basefield(x: Self::BaseField) -> Self;
|
||||
|
||||
fn is_in_basefield(&self) -> bool {
|
||||
self.to_basefield_array()[1..].iter().all(|x| x.is_zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> FieldExtension<1> for F {
|
||||
@ -39,38 +64,6 @@ impl<F: Field> FieldExtension<1> for F {
|
||||
}
|
||||
}
|
||||
|
||||
impl<FE: QuadraticFieldExtension> FieldExtension<2> for FE {
|
||||
type BaseField = FE::BaseField;
|
||||
|
||||
fn to_basefield_array(&self) -> [Self::BaseField; 2] {
|
||||
self.to_canonical_representation()
|
||||
}
|
||||
|
||||
fn from_basefield_array(arr: [Self::BaseField; 2]) -> Self {
|
||||
Self::from_canonical_representation(arr)
|
||||
}
|
||||
|
||||
fn from_basefield(x: Self::BaseField) -> Self {
|
||||
x.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<FE: QuarticFieldExtension> FieldExtension<4> for FE {
|
||||
type BaseField = FE::BaseField;
|
||||
|
||||
fn to_basefield_array(&self) -> [Self::BaseField; 4] {
|
||||
self.to_canonical_representation()
|
||||
}
|
||||
|
||||
fn from_basefield_array(arr: [Self::BaseField; 4]) -> Self {
|
||||
Self::from_canonical_representation(arr)
|
||||
}
|
||||
|
||||
fn from_basefield(x: Self::BaseField) -> Self {
|
||||
x.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Flatten the slice by sending every extension field element to its D-sized canonical representation.
|
||||
pub fn flatten<F: Field, const D: usize>(l: &[F::Extension]) -> Vec<F>
|
||||
where
|
||||
|
||||
@ -1,66 +1,49 @@
|
||||
use crate::circuit_builder::CircuitBuilder;
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::extension_field::{FieldExtension, OEF};
|
||||
use crate::field::field::Field;
|
||||
use crate::target::Target;
|
||||
use rand::Rng;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::iter::{Product, Sum};
|
||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||
|
||||
pub trait QuadraticFieldExtension:
|
||||
Field + From<<Self as QuadraticFieldExtension>::BaseField>
|
||||
{
|
||||
type BaseField: Field;
|
||||
|
||||
// Element W of BaseField, such that `X^2 - W` is irreducible over BaseField.
|
||||
const W: Self::BaseField;
|
||||
|
||||
fn to_canonical_representation(&self) -> [Self::BaseField; 2];
|
||||
|
||||
fn from_canonical_representation(v: [Self::BaseField; 2]) -> Self;
|
||||
|
||||
fn is_in_basefield(&self) -> bool {
|
||||
self.to_canonical_representation()[1..]
|
||||
.iter()
|
||||
.all(|x| x.is_zero())
|
||||
}
|
||||
|
||||
/// Frobenius automorphisms: x -> x^p, where p is the order of BaseField.
|
||||
fn frobenius(&self) -> Self {
|
||||
let [a0, a1] = self.to_canonical_representation();
|
||||
let k = (Self::BaseField::ORDER - 1) / 2;
|
||||
let z = Self::W.exp(k);
|
||||
|
||||
Self::from_canonical_representation([a0, a1 * z])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct QuadraticCrandallField([CrandallField; 2]);
|
||||
|
||||
impl QuadraticFieldExtension for QuadraticCrandallField {
|
||||
type BaseField = CrandallField;
|
||||
impl OEF<2> for QuadraticCrandallField {
|
||||
// Verifiable in Sage with
|
||||
// ``R.<x> = GF(p)[]; assert (x^2 -3).is_irreducible()`.
|
||||
const W: Self::BaseField = CrandallField(3);
|
||||
const W: CrandallField = CrandallField(3);
|
||||
}
|
||||
|
||||
fn to_canonical_representation(&self) -> [Self::BaseField; 2] {
|
||||
impl FieldExtension<2> for QuadraticCrandallField {
|
||||
type BaseField = CrandallField;
|
||||
|
||||
fn to_basefield_array(&self) -> [Self::BaseField; 2] {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn from_canonical_representation(v: [Self::BaseField; 2]) -> Self {
|
||||
Self(v)
|
||||
fn from_basefield_array(arr: [Self::BaseField; 2]) -> Self {
|
||||
Self(arr)
|
||||
}
|
||||
|
||||
fn from_basefield(x: Self::BaseField) -> Self {
|
||||
x.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<<Self as QuadraticFieldExtension>::BaseField> for QuadraticCrandallField {
|
||||
fn from(x: <Self as QuadraticFieldExtension>::BaseField) -> Self {
|
||||
Self([x, <Self as QuadraticFieldExtension>::BaseField::ZERO])
|
||||
impl From<<Self as FieldExtension<2>>::BaseField> for QuadraticCrandallField {
|
||||
fn from(x: <Self as FieldExtension<2>>::BaseField) -> Self {
|
||||
Self([x, <Self as FieldExtension<2>>::BaseField::ZERO])
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for QuadraticCrandallField {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.to_canonical_representation() == other.to_canonical_representation()
|
||||
FieldExtension::<2>::to_basefield_array(self)
|
||||
== FieldExtension::<2>::to_basefield_array(other)
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +51,7 @@ impl Eq for QuadraticCrandallField {}
|
||||
|
||||
impl Hash for QuadraticCrandallField {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
for l in &self.to_canonical_representation() {
|
||||
for l in &FieldExtension::<2>::to_basefield_array(self) {
|
||||
Hash::hash(l, state);
|
||||
}
|
||||
}
|
||||
@ -101,7 +84,7 @@ impl Field for QuadraticCrandallField {
|
||||
|
||||
let a_pow_r_minus_1 = self.frobenius();
|
||||
let a_pow_r = a_pow_r_minus_1 * *self;
|
||||
debug_assert!(a_pow_r.is_in_basefield());
|
||||
debug_assert!(FieldExtension::<2>::is_in_basefield(&a_pow_r));
|
||||
|
||||
Some(a_pow_r_minus_1 * a_pow_r.0[0].inverse().into())
|
||||
}
|
||||
@ -111,16 +94,13 @@ impl Field for QuadraticCrandallField {
|
||||
}
|
||||
|
||||
fn from_canonical_u64(n: u64) -> Self {
|
||||
Self([
|
||||
<Self as QuadraticFieldExtension>::BaseField::from_canonical_u64(n),
|
||||
<Self as QuadraticFieldExtension>::BaseField::ZERO,
|
||||
])
|
||||
<Self as FieldExtension<2>>::BaseField::from_canonical_u64(n).into()
|
||||
}
|
||||
|
||||
fn rand_from_rng<R: Rng>(rng: &mut R) -> Self {
|
||||
Self([
|
||||
<Self as QuadraticFieldExtension>::BaseField::rand_from_rng(rng),
|
||||
<Self as QuadraticFieldExtension>::BaseField::rand_from_rng(rng),
|
||||
<Self as FieldExtension<2>>::BaseField::rand_from_rng(rng),
|
||||
<Self as FieldExtension<2>>::BaseField::rand_from_rng(rng),
|
||||
])
|
||||
}
|
||||
}
|
||||
@ -226,11 +206,16 @@ impl DivAssign for QuadraticCrandallField {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExtensionTarget(pub [Target; 2]);
|
||||
|
||||
// impl<F: Field> CircuitBuilder<F> {
|
||||
// fn mul
|
||||
// }
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::field::extension_field::quadratic::{
|
||||
QuadraticCrandallField, QuadraticFieldExtension,
|
||||
};
|
||||
use crate::field::extension_field::quadratic::QuadraticCrandallField;
|
||||
use crate::field::extension_field::{FieldExtension, OEF};
|
||||
use crate::field::field::Field;
|
||||
|
||||
#[test]
|
||||
@ -241,10 +226,7 @@ mod tests {
|
||||
let z = F::rand();
|
||||
assert_eq!(x + (-x), F::ZERO);
|
||||
assert_eq!(-x, F::ZERO - x);
|
||||
assert_eq!(
|
||||
x + x,
|
||||
x * <F as QuadraticFieldExtension>::BaseField::TWO.into()
|
||||
);
|
||||
assert_eq!(x + x, x * <F as FieldExtension<2>>::BaseField::TWO.into());
|
||||
assert_eq!(x * (-x), -x.square());
|
||||
assert_eq!(x + y, y + x);
|
||||
assert_eq!(x * y, y * x);
|
||||
@ -273,7 +255,7 @@ mod tests {
|
||||
type F = QuadraticCrandallField;
|
||||
let x = F::rand();
|
||||
assert_eq!(
|
||||
x.exp(<F as QuadraticFieldExtension>::BaseField::ORDER),
|
||||
x.exp(<F as FieldExtension<2>>::BaseField::ORDER),
|
||||
x.frobenius()
|
||||
);
|
||||
}
|
||||
@ -300,10 +282,9 @@ mod tests {
|
||||
F::POWER_OF_TWO_GENERATOR
|
||||
);
|
||||
assert_eq!(
|
||||
F::POWER_OF_TWO_GENERATOR.exp(
|
||||
1 << (F::TWO_ADICITY - <F as QuadraticFieldExtension>::BaseField::TWO_ADICITY)
|
||||
),
|
||||
<F as QuadraticFieldExtension>::BaseField::POWER_OF_TWO_GENERATOR.into()
|
||||
F::POWER_OF_TWO_GENERATOR
|
||||
.exp(1 << (F::TWO_ADICITY - <F as FieldExtension<2>>::BaseField::TWO_ADICITY)),
|
||||
<F as FieldExtension<2>>::BaseField::POWER_OF_TWO_GENERATOR.into()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::extension_field::{FieldExtension, OEF};
|
||||
use crate::field::field::Field;
|
||||
use rand::Rng;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
@ -6,72 +7,46 @@ use std::hash::{Hash, Hasher};
|
||||
use std::iter::{Product, Sum};
|
||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||
|
||||
pub trait QuarticFieldExtension: Field + From<<Self as QuarticFieldExtension>::BaseField> {
|
||||
type BaseField: Field;
|
||||
|
||||
// Element W of BaseField, such that `X^4 - W` is irreducible over BaseField.
|
||||
const W: Self::BaseField;
|
||||
|
||||
fn to_canonical_representation(&self) -> [Self::BaseField; 4];
|
||||
|
||||
fn from_canonical_representation(v: [Self::BaseField; 4]) -> Self;
|
||||
|
||||
fn is_in_basefield(&self) -> bool {
|
||||
self.to_canonical_representation()[1..]
|
||||
.iter()
|
||||
.all(|x| x.is_zero())
|
||||
}
|
||||
|
||||
/// Frobenius automorphisms: x -> x^p, where p is the order of BaseField.
|
||||
fn frobenius(&self) -> Self {
|
||||
let [a0, a1, a2, a3] = self.to_canonical_representation();
|
||||
let k = (Self::BaseField::ORDER - 1) / 4;
|
||||
let z0 = Self::W.exp(k);
|
||||
let mut z = Self::BaseField::ONE;
|
||||
let b0 = a0 * z;
|
||||
z *= z0;
|
||||
let b1 = a1 * z;
|
||||
z *= z0;
|
||||
let b2 = a2 * z;
|
||||
z *= z0;
|
||||
let b3 = a3 * z;
|
||||
|
||||
Self::from_canonical_representation([b0, b1, b2, b3])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct QuarticCrandallField([CrandallField; 4]);
|
||||
|
||||
impl QuarticFieldExtension for QuarticCrandallField {
|
||||
type BaseField = CrandallField;
|
||||
impl OEF<4> for QuarticCrandallField {
|
||||
// Verifiable in Sage with
|
||||
// ``R.<x> = GF(p)[]; assert (x^4 -3).is_irreducible()`.
|
||||
const W: Self::BaseField = CrandallField(3);
|
||||
const W: CrandallField = CrandallField(3);
|
||||
}
|
||||
|
||||
fn to_canonical_representation(&self) -> [Self::BaseField; 4] {
|
||||
impl FieldExtension<4> for QuarticCrandallField {
|
||||
type BaseField = CrandallField;
|
||||
|
||||
fn to_basefield_array(&self) -> [Self::BaseField; 4] {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn from_canonical_representation(v: [Self::BaseField; 4]) -> Self {
|
||||
Self(v)
|
||||
fn from_basefield_array(arr: [Self::BaseField; 4]) -> Self {
|
||||
Self(arr)
|
||||
}
|
||||
|
||||
fn from_basefield(x: Self::BaseField) -> Self {
|
||||
x.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<<Self as QuarticFieldExtension>::BaseField> for QuarticCrandallField {
|
||||
fn from(x: <Self as QuarticFieldExtension>::BaseField) -> Self {
|
||||
impl From<<Self as FieldExtension<4>>::BaseField> for QuarticCrandallField {
|
||||
fn from(x: <Self as FieldExtension<4>>::BaseField) -> Self {
|
||||
Self([
|
||||
x,
|
||||
<Self as QuarticFieldExtension>::BaseField::ZERO,
|
||||
<Self as QuarticFieldExtension>::BaseField::ZERO,
|
||||
<Self as QuarticFieldExtension>::BaseField::ZERO,
|
||||
<Self as FieldExtension<4>>::BaseField::ZERO,
|
||||
<Self as FieldExtension<4>>::BaseField::ZERO,
|
||||
<Self as FieldExtension<4>>::BaseField::ZERO,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for QuarticCrandallField {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.to_canonical_representation() == other.to_canonical_representation()
|
||||
FieldExtension::<4>::to_basefield_array(self)
|
||||
== FieldExtension::<4>::to_basefield_array(other)
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +54,7 @@ impl Eq for QuarticCrandallField {}
|
||||
|
||||
impl Hash for QuarticCrandallField {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
for l in &self.to_canonical_representation() {
|
||||
for l in &FieldExtension::<4>::to_basefield_array(self) {
|
||||
Hash::hash(l, state);
|
||||
}
|
||||
}
|
||||
@ -136,7 +111,7 @@ impl Field for QuarticCrandallField {
|
||||
let a_pow_p3_plus_p2 = a_pow_p_plus_1.frobenius().frobenius();
|
||||
let a_pow_r_minus_1 = a_pow_p3_plus_p2 * a_pow_p;
|
||||
let a_pow_r = a_pow_r_minus_1 * *self;
|
||||
debug_assert!(a_pow_r.is_in_basefield());
|
||||
debug_assert!(FieldExtension::<4>::is_in_basefield(&a_pow_r));
|
||||
|
||||
Some(a_pow_r_minus_1 * a_pow_r.0[0].inverse().into())
|
||||
}
|
||||
@ -146,20 +121,15 @@ impl Field for QuarticCrandallField {
|
||||
}
|
||||
|
||||
fn from_canonical_u64(n: u64) -> Self {
|
||||
Self([
|
||||
<Self as QuarticFieldExtension>::BaseField::from_canonical_u64(n),
|
||||
<Self as QuarticFieldExtension>::BaseField::ZERO,
|
||||
<Self as QuarticFieldExtension>::BaseField::ZERO,
|
||||
<Self as QuarticFieldExtension>::BaseField::ZERO,
|
||||
])
|
||||
<Self as FieldExtension<4>>::BaseField::from_canonical_u64(n).into()
|
||||
}
|
||||
|
||||
fn rand_from_rng<R: Rng>(rng: &mut R) -> Self {
|
||||
Self([
|
||||
<Self as QuarticFieldExtension>::BaseField::rand_from_rng(rng),
|
||||
<Self as QuarticFieldExtension>::BaseField::rand_from_rng(rng),
|
||||
<Self as QuarticFieldExtension>::BaseField::rand_from_rng(rng),
|
||||
<Self as QuarticFieldExtension>::BaseField::rand_from_rng(rng),
|
||||
<Self as FieldExtension<4>>::BaseField::rand_from_rng(rng),
|
||||
<Self as FieldExtension<4>>::BaseField::rand_from_rng(rng),
|
||||
<Self as FieldExtension<4>>::BaseField::rand_from_rng(rng),
|
||||
<Self as FieldExtension<4>>::BaseField::rand_from_rng(rng),
|
||||
])
|
||||
}
|
||||
}
|
||||
@ -283,7 +253,8 @@ impl DivAssign for QuarticCrandallField {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::field::extension_field::quartic::{QuarticCrandallField, QuarticFieldExtension};
|
||||
use crate::field::extension_field::quartic::QuarticCrandallField;
|
||||
use crate::field::extension_field::{FieldExtension, OEF};
|
||||
use crate::field::field::Field;
|
||||
|
||||
fn exp_naive<F: Field>(x: F, power: u128) -> F {
|
||||
@ -307,10 +278,7 @@ mod tests {
|
||||
let z = F::rand();
|
||||
assert_eq!(x + (-x), F::ZERO);
|
||||
assert_eq!(-x, F::ZERO - x);
|
||||
assert_eq!(
|
||||
x + x,
|
||||
x * <F as QuarticFieldExtension>::BaseField::TWO.into()
|
||||
);
|
||||
assert_eq!(x + x, x * <F as FieldExtension<4>>::BaseField::TWO.into());
|
||||
assert_eq!(x * (-x), -x.square());
|
||||
assert_eq!(x + y, y + x);
|
||||
assert_eq!(x * y, y * x);
|
||||
@ -339,7 +307,7 @@ mod tests {
|
||||
type F = QuarticCrandallField;
|
||||
let x = F::rand();
|
||||
assert_eq!(
|
||||
exp_naive(x, <F as QuarticFieldExtension>::BaseField::ORDER as u128),
|
||||
exp_naive(x, <F as FieldExtension<4>>::BaseField::ORDER as u128),
|
||||
x.frobenius()
|
||||
);
|
||||
}
|
||||
@ -374,8 +342,8 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
F::POWER_OF_TWO_GENERATOR
|
||||
.exp(1 << (F::TWO_ADICITY - <F as QuarticFieldExtension>::BaseField::TWO_ADICITY)),
|
||||
<F as QuarticFieldExtension>::BaseField::POWER_OF_TWO_GENERATOR.into()
|
||||
.exp(1 << (F::TWO_ADICITY - <F as FieldExtension<4>>::BaseField::TWO_ADICITY)),
|
||||
<F as FieldExtension<4>>::BaseField::POWER_OF_TWO_GENERATOR.into()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user