diff --git a/src/field/extension_field/quadratic.rs b/src/field/extension_field/quadratic.rs index 3382a487..25b42e49 100644 --- a/src/field/extension_field/quadratic.rs +++ b/src/field/extension_field/quadratic.rs @@ -28,7 +28,7 @@ pub trait QuadraticFieldExtension: fn frobenius(&self) -> Self { let [a0, a1] = self.to_canonical_representation(); let k = (Self::BaseField::ORDER - 1) / 2; - let z = Self::W.exp_usize(k as usize); + let z = Self::W.exp(k); Self::from_canonical_representation([a0, a1 * z]) } @@ -233,19 +233,6 @@ mod tests { }; use crate::field::field::Field; - fn exp_naive(x: F, power: u64) -> F { - let mut current = x; - let mut product = F::ONE; - - for j in 0..64 { - if (power >> j & 1) != 0 { - product *= current; - } - current = current.square(); - } - product - } - #[test] fn test_add_neg_sub_mul() { type F = QuadraticCrandallField; @@ -286,7 +273,7 @@ mod tests { type F = QuadraticCrandallField; let x = F::rand(); assert_eq!( - exp_naive(x, ::BaseField::ORDER), + x.exp(::BaseField::ORDER), x.frobenius() ); } @@ -297,7 +284,7 @@ mod tests { type F = QuadraticCrandallField; let x = F::rand(); assert_eq!( - exp_naive(exp_naive(x, 18446744071293632512), 18446744071293632514), + x.exp(18446744071293632512).exp(18446744071293632514), F::ONE ); } @@ -308,12 +295,12 @@ mod tests { // F::ORDER = 2^29 * 2762315674048163 * 229454332791453 + 1 assert_eq!( F::MULTIPLICATIVE_GROUP_GENERATOR - .exp_usize(2762315674048163) - .exp_usize(229454332791453), + .exp(2762315674048163) + .exp(229454332791453), F::POWER_OF_TWO_GENERATOR ); assert_eq!( - F::POWER_OF_TWO_GENERATOR.exp_usize( + F::POWER_OF_TWO_GENERATOR.exp( 1 << (F::TWO_ADICITY - ::BaseField::TWO_ADICITY) ), ::BaseField::POWER_OF_TWO_GENERATOR.into() diff --git a/src/field/extension_field/quartic.rs b/src/field/extension_field/quartic.rs index 41a49a26..121e4c67 100644 --- a/src/field/extension_field/quartic.rs +++ b/src/field/extension_field/quartic.rs @@ -26,7 +26,7 @@ pub trait QuarticFieldExtension: Field + From<::B 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_usize(k as usize); + let z0 = Self::W.exp(k); let mut z = Self::BaseField::ONE; let b0 = a0 * z; z *= z0; @@ -373,9 +373,8 @@ mod tests { F::POWER_OF_TWO_GENERATOR ); assert_eq!( - F::POWER_OF_TWO_GENERATOR.exp_usize( - 1 << (F::TWO_ADICITY - ::BaseField::TWO_ADICITY) - ), + F::POWER_OF_TWO_GENERATOR + .exp(1 << (F::TWO_ADICITY - ::BaseField::TWO_ADICITY)), ::BaseField::POWER_OF_TWO_GENERATOR.into() ); } diff --git a/src/field/field.rs b/src/field/field.rs index 3521edf8..a6e6f7cc 100644 --- a/src/field/field.rs +++ b/src/field/field.rs @@ -157,12 +157,12 @@ pub trait Field: bits_u64(self.to_canonical_u64()) } - fn exp(&self, power: Self) -> Self { + fn exp(&self, power: u64) -> Self { let mut current = *self; let mut product = Self::ONE; - for j in 0..power.bits() { - if (power.to_canonical_u64() >> j & 1) != 0 { + for j in 0..64 { + if (power >> j & 1) != 0 { product *= current; } current = current.square(); @@ -171,32 +171,25 @@ pub trait Field: } fn exp_u32(&self, power: u32) -> Self { - self.exp(Self::from_canonical_u32(power)) - } - - fn exp_usize(&self, power: usize) -> Self { - self.exp(Self::from_canonical_usize(power)) + self.exp(power as u64) } /// Returns whether `x^power` is a permutation of this field. - fn is_monomial_permutation(power: Self) -> bool { - if power.is_zero() { - return false; + fn is_monomial_permutation(power: u64) -> bool { + match power { + 0 => false, + 1 => true, + _ => (Self::ORDER - 1).gcd(&power) == 1, } - if power.is_one() { - return true; - } - (Self::ORDER - 1).gcd(&power.to_canonical_u64()) == 1 } - fn kth_root(&self, k: Self) -> Self { + fn kth_root(&self, k: u64) -> Self { let p = Self::ORDER; let p_minus_1 = p - 1; debug_assert!( Self::is_monomial_permutation(k), "Not a permutation of this field" ); - let k = k.to_canonical_u64(); // By Fermat's little theorem, x^p = x and x^(p - 1) = 1, so x^(p + n(p - 1)) = x for any n. // Our assumption that the k'th root operation is a permutation implies gcd(p - 1, k) = 1, @@ -208,7 +201,7 @@ pub trait Field: let numerator = p as u128 + n as u128 * p_minus_1 as u128; if numerator % k as u128 == 0 { let power = (numerator / k as u128) as u64 % p_minus_1; - return self.exp(Self::from_canonical_u64(power)); + return self.exp(power); } } panic!( @@ -218,11 +211,11 @@ pub trait Field: } fn kth_root_u32(&self, k: u32) -> Self { - self.kth_root(Self::from_canonical_u32(k)) + self.kth_root(k as u64) } fn cube_root(&self) -> Self { - self.kth_root_u32(3) + self.kth_root(3) } fn powers(&self) -> Powers { diff --git a/src/field/field_testing.rs b/src/field/field_testing.rs index 77b23ea3..7d2339af 100644 --- a/src/field/field_testing.rs +++ b/src/field/field_testing.rs @@ -298,7 +298,6 @@ macro_rules! test_arithmetic { assert_eq!(F::TWO.kth_root_u32(1), ::TWO); for power in 1..10 { - let power = F::from_canonical_u32(power); if F::is_monomial_permutation(power) { let x = F::rand(); assert_eq!(x.exp(power).kth_root(power), x); diff --git a/src/fri/verifier.rs b/src/fri/verifier.rs index 351f119c..80997956 100644 --- a/src/fri/verifier.rs +++ b/src/fri/verifier.rs @@ -187,7 +187,7 @@ fn fri_verifier_query_round, const D: usize>( // `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain. let log_n = log2_strict(n); let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR - * F::primitive_root_of_unity(log_n).exp_usize(reverse_bits(x_index, log_n)); + * F::primitive_root_of_unity(log_n).exp(reverse_bits(x_index, log_n) as u64); for (i, &arity_bits) in config.reduction_arity_bits.iter().enumerate() { let arity = 1 << arity_bits; let next_domain_size = domain_size >> arity_bits; diff --git a/src/permutation_argument.rs b/src/permutation_argument.rs index af74aed2..62ee63d4 100644 --- a/src/permutation_argument.rs +++ b/src/permutation_argument.rs @@ -120,7 +120,7 @@ impl WirePartitions { .map(|chunk| { let values = chunk .par_iter() - .map(|&x| k_is[x / degree] * subgroup_generator.exp_usize(x % degree)) + .map(|&x| k_is[x / degree] * subgroup_generator.exp((x % degree) as u64)) .collect::>(); PolynomialValues::new(values) }) diff --git a/src/plonk_common.rs b/src/plonk_common.rs index e2227e56..ed780817 100644 --- a/src/plonk_common.rs +++ b/src/plonk_common.rs @@ -47,7 +47,7 @@ pub fn evaluate_gate_constraints_recursively( /// Evaluate the polynomial which vanishes on any multiplicative subgroup of a given order `n`. pub(crate) fn eval_zero_poly(n: usize, x: F) -> F { // Z(x) = x^n - 1 - x.exp_usize(n) - F::ONE + x.exp(n as u64) - F::ONE } /// Evaluate the Lagrange basis `L_1` with `L_1(1) = 1`, and `L_1(x) = 0` for other members of an diff --git a/src/polynomial/commitment.rs b/src/polynomial/commitment.rs index 7fc5b96c..aa58c561 100644 --- a/src/polynomial/commitment.rs +++ b/src/polynomial/commitment.rs @@ -90,7 +90,7 @@ impl ListPolynomialCommitment { assert_eq!(self.blinding, config.blinding[0]); for p in points { assert_ne!( - p.exp_usize(self.degree), + p.exp(self.degree as u64), F::Extension::ONE, "Opening point is in the subgroup." ); @@ -175,7 +175,7 @@ impl ListPolynomialCommitment { } for p in points { assert_ne!( - p.exp_usize(degree), + p.exp(degree as u64), F::Extension::ONE, "Opening point is in the subgroup." ); @@ -374,7 +374,7 @@ mod tests { .map(|_| PolynomialCoeffs::new(F::rand_vec(degree))) .collect(); let mut points = F::Extension::rand_vec(num_points); - while points.iter().any(|&x| x.exp_usize(degree).is_one()) { + while points.iter().any(|&x| x.exp(degree as u64).is_one()) { points = F::Extension::rand_vec(num_points); } diff --git a/src/polynomial/division.rs b/src/polynomial/division.rs index 8e3c2676..b74fd00f 100644 --- a/src/polynomial/division.rs +++ b/src/polynomial/division.rs @@ -91,8 +91,8 @@ impl PolynomialCoeffs { // Equals to the evaluation of `a` on `{g.w^i}`. let mut a_eval = fft(a); // Compute the denominators `1/(g^n.w^(n*i) - 1)` using batch inversion. - let denominator_g = g.exp_usize(n); - let root_n = root.exp_usize(n); + let denominator_g = g.exp(n as u64); + let root_n = root.exp(n as u64); let mut root_pow = F::ONE; let denominators = (0..a_eval.len()) .map(|i| { diff --git a/src/polynomial/polynomial.rs b/src/polynomial/polynomial.rs index f0faaf11..1d47dea4 100644 --- a/src/polynomial/polynomial.rs +++ b/src/polynomial/polynomial.rs @@ -434,7 +434,7 @@ mod tests { PolynomialCoeffs::new(xn_min_one_vec) }; - let a = g.exp_usize(rng.gen_range(0, n)); + let a = g.exp(rng.gen_range(0, n as u64)); let denom = PolynomialCoeffs::new(vec![-a, F::ONE]); let now = Instant::now(); xn_minus_one.div_rem(&denom);