From facbe117fbd966c17ed7fdddc0086d8ae81bd990 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Fri, 2 Apr 2021 19:04:26 -0700 Subject: [PATCH] Move some stuff into Field --- src/field/crandall_field.rs | 24 ++++-------------------- src/field/field.rs | 23 ++++++++++++++++++++--- src/field/field_testing.rs | 2 +- src/polynomial/division.rs | 2 +- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/field/crandall_field.rs b/src/field/crandall_field.rs index 8b9dc9e3..4fc839bf 100644 --- a/src/field/crandall_field.rs +++ b/src/field/crandall_field.rs @@ -9,9 +9,6 @@ use crate::field::field::Field; /// EPSILON = 9 * 2**28 - 1 const EPSILON: u64 = 2415919103; -const TWO_ADICITY: usize = 28; -const POWER_OF_TWO_GENERATOR: CrandallField = CrandallField(10281950781551402419); - /// A field designed for use with the Crandall reduction algorithm. /// /// Its order is @@ -51,7 +48,10 @@ impl Field for CrandallField { const NEG_ONE: Self = Self(Self::ORDER - 1); const ORDER: u64 = 18446744071293632513; - const MULTIPLICATIVE_SUBGROUP_GENERATOR: Self = Self(5); + const TWO_ADICITY: usize = 28; + + const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self(5); + const POWER_OF_TWO_GENERATOR: Self = Self(10281950781551402419); #[inline] fn square(&self) -> Self { @@ -119,22 +119,6 @@ impl Field for CrandallField { })) } - fn primitive_root_of_unity(n_power: usize) -> Self { - assert!(n_power <= TWO_ADICITY); - let base = POWER_OF_TWO_GENERATOR; - base.exp(CrandallField(1u64 << (TWO_ADICITY - n_power))) - } - - fn cyclic_subgroup_known_order(generator: Self, order: usize) -> Vec { - let mut subgroup = Vec::new(); - let mut current = Self::ONE; - for _i in 0..order { - subgroup.push(current); - current = current * generator; - } - subgroup - } - #[inline] fn to_canonical_u64(&self) -> u64 { let mut c = self.0; diff --git a/src/field/field.rs b/src/field/field.rs index 239b0160..7cffab50 100644 --- a/src/field/field.rs +++ b/src/field/field.rs @@ -27,7 +27,12 @@ pub trait Field: 'static const NEG_ONE: Self; const ORDER: u64; - const MULTIPLICATIVE_SUBGROUP_GENERATOR: Self; + const TWO_ADICITY: usize; + + /// Generator of the entire multiplicative group, i.e. all non-zero elements. + const MULTIPLICATIVE_GROUP_GENERATOR: Self; + /// Generator of a multiplicative subgroup of order `2^TWO_ADICITY`. + const POWER_OF_TWO_GENERATOR: Self; fn is_zero(&self) -> bool { *self == Self::ZERO @@ -81,9 +86,21 @@ pub trait Field: 'static x_inv } - fn primitive_root_of_unity(n_power: usize) -> Self; + fn primitive_root_of_unity(n_power: usize) -> Self { + assert!(n_power <= Self::TWO_ADICITY); + let base = Self::POWER_OF_TWO_GENERATOR; + base.exp(Self::from_canonical_u64(1u64 << (Self::TWO_ADICITY - n_power))) + } - fn cyclic_subgroup_known_order(generator: Self, order: usize) -> Vec; + fn cyclic_subgroup_known_order(generator: Self, order: usize) -> Vec { + let mut subgroup = Vec::new(); + let mut current = Self::ONE; + for _i in 0..order { + subgroup.push(current); + current = current * generator; + } + subgroup + } fn to_canonical_u64(&self) -> u64; diff --git a/src/field/field_testing.rs b/src/field/field_testing.rs index c5a7d259..ca42a4c2 100644 --- a/src/field/field_testing.rs +++ b/src/field/field_testing.rs @@ -137,7 +137,7 @@ macro_rules! test_arithmetic { ($field:ty) => { mod arithmetic { use crate::{Field}; - use std::ops::{Add, Div, Mul, Neg, Sub}; + use std::ops::{Add, Mul, Neg, Sub}; // Can be 32 or 64; doesn't have to be computer's actual word // bits. Choosing 32 gives more tests... diff --git a/src/polynomial/division.rs b/src/polynomial/division.rs index 68c78612..9ee72d04 100644 --- a/src/polynomial/division.rs +++ b/src/polynomial/division.rs @@ -12,7 +12,7 @@ pub(crate) fn divide_by_z_h(mut a: PolynomialCoeffs, n: usize) -> P return a.clone(); } - let g = F::MULTIPLICATIVE_SUBGROUP_GENERATOR; + let g = F::MULTIPLICATIVE_GROUP_GENERATOR; let mut g_pow = F::ONE; // Multiply the i-th coefficient of `a` by `g^i`. Then `new_a(w^j) = old_a(g.w^j)`. a.coeffs.iter_mut().for_each(|x| {