From 445ea3771da8e791dc3efd1594d04ec73030bf75 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 14 Jun 2021 10:28:15 +0200 Subject: [PATCH] Remove `Frobeniable trait` --- src/field/crandall_field.rs | 13 ++------ src/field/extension_field/mod.rs | 45 +++++++------------------- src/field/extension_field/quadratic.rs | 2 +- src/field/extension_field/quartic.rs | 16 +++++---- src/field/extension_field/target.rs | 15 +++++---- src/field/field.rs | 6 ++-- src/gadgets/rotate.rs | 2 +- 7 files changed, 35 insertions(+), 64 deletions(-) diff --git a/src/field/crandall_field.rs b/src/field/crandall_field.rs index 34d67b65..81a2c9e6 100644 --- a/src/field/crandall_field.rs +++ b/src/field/crandall_field.rs @@ -6,7 +6,7 @@ use num::Integer; use crate::field::extension_field::quadratic::QuadraticCrandallField; use crate::field::extension_field::quartic::QuarticCrandallField; -use crate::field::extension_field::{Extendable, Frobeniable}; +use crate::field::extension_field::{Extendable, Frobenius}; use crate::field::field::Field; use std::hash::{Hash, Hasher}; use std::iter::{Product, Sum}; @@ -444,16 +444,7 @@ fn split(x: u128) -> (u64, u64) { (x as u64, (x >> 64) as u64) } -impl Frobeniable for CrandallField { - const FROBENIUS_CONSTANTS_2: [u64; 1] = [9223372035646816256]; - /// Placeholder since there's no OEF of degree 3 for `CrandallField`. - const FROBENIUS_CONSTANTS_3: [u64; 2] = [0, 0]; - const FROBENIUS_CONSTANTS_4: [u64; 3] = [ - 4611686017823408128, - 9223372035646816256, - 13835058053470224384, - ]; -} +impl Frobenius<1> for CrandallField {} #[cfg(test)] mod tests { diff --git a/src/field/extension_field/mod.rs b/src/field/extension_field/mod.rs index d9ae3387..9caa7dc8 100644 --- a/src/field/extension_field/mod.rs +++ b/src/field/extension_field/mod.rs @@ -19,59 +19,36 @@ impl OEF<1> for F { const W: Self::BaseField = F::ZERO; } -pub trait Frobenius: OEF { +pub trait Frobenius: OEF { /// FrobeniusField automorphisms: x -> x^p, where p is the order of BaseField. fn frobenius(&self) -> Self { self.repeated_frobenius(1) } /// Repeated Frobenius automorphisms: x -> x^(p^k). - fn repeated_frobenius(&self, k: usize) -> Self { - if k == 0 { + fn repeated_frobenius(&self, count: usize) -> Self { + if count == 0 { return *self; - } else if k >= D { - return self.repeated_frobenius(k % D); + } else if count >= D { + return self.repeated_frobenius(count % D); } let arr = self.to_basefield_array(); - let z0 = match D { - 2 => Self::W.exp(BF::FROBENIUS_CONSTANTS_2[k - 1]), - 3 => Self::W.exp(BF::FROBENIUS_CONSTANTS_3[k - 1]), - 4 => Self::W.exp(BF::FROBENIUS_CONSTANTS_4[k - 1]), - _ => unimplemented!("Only extensions of degree 2, 3, or 4 are allowed for now."), - }; - let mut z = Self::BaseField::ONE; + let k = (Self::BaseField::ORDER - 1) / (D as u64); + let z0 = Self::W.exp(k * count as u64); let mut res = [Self::BaseField::ZERO; D]; - for i in 0..D { + for (i, z) in z0.powers().take(D).enumerate() { res[i] = arr[i] * z; - z *= z0; } Self::from_basefield_array(res) } } -impl Frobenius for F { - fn frobenius(&self) -> Self { - *self - } - fn repeated_frobenius(&self, _k: usize) -> Self { - *self - } +pub trait Extendable: Field + Sized { + type Extension: Field + OEF + Frobenius + From; } -/// Trait to hardcode constants used in the Frobenius automorphism. -pub trait Frobeniable: Field { - //! `FROBENIUS_CONSTANTS_D[i-1] = floor( p^i / D) mod p-1` - const FROBENIUS_CONSTANTS_2: [u64; 1]; - const FROBENIUS_CONSTANTS_3: [u64; 2]; - const FROBENIUS_CONSTANTS_4: [u64; 3]; -} - -pub trait Extendable: Frobeniable + Sized { - type Extension: Field + OEF + Frobenius + From; -} - -impl> Extendable<1> for F { +impl + FieldExtension<1, BaseField = F>> Extendable<1> for F { type Extension = F; } diff --git a/src/field/extension_field/quadratic.rs b/src/field/extension_field/quadratic.rs index f0fd2ac9..4bf0c08d 100644 --- a/src/field/extension_field/quadratic.rs +++ b/src/field/extension_field/quadratic.rs @@ -16,7 +16,7 @@ impl OEF<2> for QuadraticCrandallField { const W: CrandallField = CrandallField(3); } -impl Frobenius for QuadraticCrandallField {} +impl Frobenius<2> for QuadraticCrandallField {} impl FieldExtension<2> for QuadraticCrandallField { type BaseField = CrandallField; diff --git a/src/field/extension_field/quartic.rs b/src/field/extension_field/quartic.rs index f0e8bed4..b93cbb56 100644 --- a/src/field/extension_field/quartic.rs +++ b/src/field/extension_field/quartic.rs @@ -20,7 +20,7 @@ impl OEF<4> for QuarticCrandallField { const W: CrandallField = CrandallField(3); } -impl Frobenius for QuarticCrandallField {} +impl Frobenius<4> for QuarticCrandallField {} impl FieldExtension<4> for QuarticCrandallField { type BaseField = CrandallField; @@ -294,16 +294,18 @@ mod tests { #[test] fn test_frobenius() { type F = QuarticCrandallField; + const D: usize = 4; let x = F::rand(); assert_eq!( - exp_naive(x, >::BaseField::ORDER as u128), + exp_naive(x, >::BaseField::ORDER as u128), x.frobenius() ); - assert_eq!(x.repeated_frobenius(2), x.frobenius().frobenius()); - assert_eq!( - x.repeated_frobenius(3), - x.frobenius().frobenius().frobenius() - ); + for count in 2..D { + assert_eq!( + x.repeated_frobenius(count), + (0..count).fold(x, |acc, _| acc.frobenius()) + ); + } } #[test] diff --git a/src/field/extension_field/target.rs b/src/field/extension_field/target.rs index 5a3cd403..20bcd382 100644 --- a/src/field/extension_field/target.rs +++ b/src/field/extension_field/target.rs @@ -34,16 +34,17 @@ impl ExtensionTarget { pub fn repeated_frobenius>( &self, - k: usize, + count: usize, builder: &mut CircuitBuilder, ) -> Self { + if count == 0 { + return *self; + } else if count >= D { + return self.repeated_frobenius(count % D, builder); + } let arr = self.to_target_array(); - let z0 = match D { - 2 => F::Extension::W.exp(F::FROBENIUS_CONSTANTS_2[k - 1]), - 3 => F::Extension::W.exp(F::FROBENIUS_CONSTANTS_3[k - 1]), - 4 => F::Extension::W.exp(F::FROBENIUS_CONSTANTS_4[k - 1]), - _ => unimplemented!("Only extensions of degree 2, 3, or 4 are allowed for now."), - }; + let k = (F::ORDER - 1) / (D as u64); + let z0 = F::W.exp(k * count as u64); let zs = z0 .powers() .take(D) diff --git a/src/field/field.rs b/src/field/field.rs index 88c12dae..f28dc004 100644 --- a/src/field/field.rs +++ b/src/field/field.rs @@ -7,7 +7,7 @@ use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssi use num::Integer; use rand::Rng; -use crate::field::extension_field::{Extendable, FieldExtension, Frobeniable, Frobenius, OEF}; +use crate::field::extension_field::{Extendable, FieldExtension, Frobenius, OEF}; use crate::util::bits_u64; /// A finite field with prime order less than 2^64. @@ -287,9 +287,9 @@ impl Iterator for Powers { impl Powers { /// Apply the Frobenius automorphism `k` times. - pub fn repeated_frobenius(self, k: usize) -> Self + pub fn repeated_frobenius(self, k: usize) -> Self where - F: Frobenius, + F: Frobenius, { let Self { base, current } = self; Self { diff --git a/src/gadgets/rotate.rs b/src/gadgets/rotate.rs index 7afbdfa3..6e5d6dfb 100644 --- a/src/gadgets/rotate.rs +++ b/src/gadgets/rotate.rs @@ -119,7 +119,7 @@ mod tests { #[test] fn test_rotate() { - for len_log in 1..4 { + for len_log in 1..3 { test_rotate_given_len(len_log); } }