mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-07 16:23:12 +00:00
Change Field::exp to using a u64 power.
This commit is contained in:
parent
7d302aac34
commit
78f71672a3
@ -28,7 +28,7 @@ pub trait QuadraticFieldExtension:
|
|||||||
fn frobenius(&self) -> Self {
|
fn frobenius(&self) -> Self {
|
||||||
let [a0, a1] = self.to_canonical_representation();
|
let [a0, a1] = self.to_canonical_representation();
|
||||||
let k = (Self::BaseField::ORDER - 1) / 2;
|
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])
|
Self::from_canonical_representation([a0, a1 * z])
|
||||||
}
|
}
|
||||||
@ -233,19 +233,6 @@ mod tests {
|
|||||||
};
|
};
|
||||||
use crate::field::field::Field;
|
use crate::field::field::Field;
|
||||||
|
|
||||||
fn exp_naive<F: Field>(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]
|
#[test]
|
||||||
fn test_add_neg_sub_mul() {
|
fn test_add_neg_sub_mul() {
|
||||||
type F = QuadraticCrandallField;
|
type F = QuadraticCrandallField;
|
||||||
@ -286,7 +273,7 @@ mod tests {
|
|||||||
type F = QuadraticCrandallField;
|
type F = QuadraticCrandallField;
|
||||||
let x = F::rand();
|
let x = F::rand();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
exp_naive(x, <F as QuadraticFieldExtension>::BaseField::ORDER),
|
x.exp(<F as QuadraticFieldExtension>::BaseField::ORDER),
|
||||||
x.frobenius()
|
x.frobenius()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -297,7 +284,7 @@ mod tests {
|
|||||||
type F = QuadraticCrandallField;
|
type F = QuadraticCrandallField;
|
||||||
let x = F::rand();
|
let x = F::rand();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
exp_naive(exp_naive(x, 18446744071293632512), 18446744071293632514),
|
x.exp(18446744071293632512).exp(18446744071293632514),
|
||||||
F::ONE
|
F::ONE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -308,12 +295,12 @@ mod tests {
|
|||||||
// F::ORDER = 2^29 * 2762315674048163 * 229454332791453 + 1
|
// F::ORDER = 2^29 * 2762315674048163 * 229454332791453 + 1
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
F::MULTIPLICATIVE_GROUP_GENERATOR
|
F::MULTIPLICATIVE_GROUP_GENERATOR
|
||||||
.exp_usize(2762315674048163)
|
.exp(2762315674048163)
|
||||||
.exp_usize(229454332791453),
|
.exp(229454332791453),
|
||||||
F::POWER_OF_TWO_GENERATOR
|
F::POWER_OF_TWO_GENERATOR
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
F::POWER_OF_TWO_GENERATOR.exp_usize(
|
F::POWER_OF_TWO_GENERATOR.exp(
|
||||||
1 << (F::TWO_ADICITY - <F as QuadraticFieldExtension>::BaseField::TWO_ADICITY)
|
1 << (F::TWO_ADICITY - <F as QuadraticFieldExtension>::BaseField::TWO_ADICITY)
|
||||||
),
|
),
|
||||||
<F as QuadraticFieldExtension>::BaseField::POWER_OF_TWO_GENERATOR.into()
|
<F as QuadraticFieldExtension>::BaseField::POWER_OF_TWO_GENERATOR.into()
|
||||||
|
|||||||
@ -26,7 +26,7 @@ pub trait QuarticFieldExtension: Field + From<<Self as QuarticFieldExtension>::B
|
|||||||
fn frobenius(&self) -> Self {
|
fn frobenius(&self) -> Self {
|
||||||
let [a0, a1, a2, a3] = self.to_canonical_representation();
|
let [a0, a1, a2, a3] = self.to_canonical_representation();
|
||||||
let k = (Self::BaseField::ORDER - 1) / 4;
|
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 mut z = Self::BaseField::ONE;
|
||||||
let b0 = a0 * z;
|
let b0 = a0 * z;
|
||||||
z *= z0;
|
z *= z0;
|
||||||
@ -373,9 +373,8 @@ mod tests {
|
|||||||
F::POWER_OF_TWO_GENERATOR
|
F::POWER_OF_TWO_GENERATOR
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
F::POWER_OF_TWO_GENERATOR.exp_usize(
|
F::POWER_OF_TWO_GENERATOR
|
||||||
1 << (F::TWO_ADICITY - <F as QuarticFieldExtension>::BaseField::TWO_ADICITY)
|
.exp(1 << (F::TWO_ADICITY - <F as QuarticFieldExtension>::BaseField::TWO_ADICITY)),
|
||||||
),
|
|
||||||
<F as QuarticFieldExtension>::BaseField::POWER_OF_TWO_GENERATOR.into()
|
<F as QuarticFieldExtension>::BaseField::POWER_OF_TWO_GENERATOR.into()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -157,12 +157,12 @@ pub trait Field:
|
|||||||
bits_u64(self.to_canonical_u64())
|
bits_u64(self.to_canonical_u64())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exp(&self, power: Self) -> Self {
|
fn exp(&self, power: u64) -> Self {
|
||||||
let mut current = *self;
|
let mut current = *self;
|
||||||
let mut product = Self::ONE;
|
let mut product = Self::ONE;
|
||||||
|
|
||||||
for j in 0..power.bits() {
|
for j in 0..64 {
|
||||||
if (power.to_canonical_u64() >> j & 1) != 0 {
|
if (power >> j & 1) != 0 {
|
||||||
product *= current;
|
product *= current;
|
||||||
}
|
}
|
||||||
current = current.square();
|
current = current.square();
|
||||||
@ -171,32 +171,25 @@ pub trait Field:
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn exp_u32(&self, power: u32) -> Self {
|
fn exp_u32(&self, power: u32) -> Self {
|
||||||
self.exp(Self::from_canonical_u32(power))
|
self.exp(power as u64)
|
||||||
}
|
|
||||||
|
|
||||||
fn exp_usize(&self, power: usize) -> Self {
|
|
||||||
self.exp(Self::from_canonical_usize(power))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether `x^power` is a permutation of this field.
|
/// Returns whether `x^power` is a permutation of this field.
|
||||||
fn is_monomial_permutation(power: Self) -> bool {
|
fn is_monomial_permutation(power: u64) -> bool {
|
||||||
if power.is_zero() {
|
match power {
|
||||||
return false;
|
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 = Self::ORDER;
|
||||||
let p_minus_1 = p - 1;
|
let p_minus_1 = p - 1;
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
Self::is_monomial_permutation(k),
|
Self::is_monomial_permutation(k),
|
||||||
"Not a permutation of this field"
|
"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.
|
// 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,
|
// 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;
|
let numerator = p as u128 + n as u128 * p_minus_1 as u128;
|
||||||
if numerator % k as u128 == 0 {
|
if numerator % k as u128 == 0 {
|
||||||
let power = (numerator / k as u128) as u64 % p_minus_1;
|
let power = (numerator / k as u128) as u64 % p_minus_1;
|
||||||
return self.exp(Self::from_canonical_u64(power));
|
return self.exp(power);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic!(
|
panic!(
|
||||||
@ -218,11 +211,11 @@ pub trait Field:
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn kth_root_u32(&self, k: u32) -> Self {
|
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 {
|
fn cube_root(&self) -> Self {
|
||||||
self.kth_root_u32(3)
|
self.kth_root(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn powers(&self) -> Powers<Self> {
|
fn powers(&self) -> Powers<Self> {
|
||||||
|
|||||||
@ -298,7 +298,6 @@ macro_rules! test_arithmetic {
|
|||||||
assert_eq!(F::TWO.kth_root_u32(1), <F>::TWO);
|
assert_eq!(F::TWO.kth_root_u32(1), <F>::TWO);
|
||||||
|
|
||||||
for power in 1..10 {
|
for power in 1..10 {
|
||||||
let power = F::from_canonical_u32(power);
|
|
||||||
if F::is_monomial_permutation(power) {
|
if F::is_monomial_permutation(power) {
|
||||||
let x = F::rand();
|
let x = F::rand();
|
||||||
assert_eq!(x.exp(power).kth_root(power), x);
|
assert_eq!(x.exp(power).kth_root(power), x);
|
||||||
|
|||||||
@ -187,7 +187,7 @@ fn fri_verifier_query_round<F: Field + Extendable<D>, const D: usize>(
|
|||||||
// `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain.
|
// `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain.
|
||||||
let log_n = log2_strict(n);
|
let log_n = log2_strict(n);
|
||||||
let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR
|
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() {
|
for (i, &arity_bits) in config.reduction_arity_bits.iter().enumerate() {
|
||||||
let arity = 1 << arity_bits;
|
let arity = 1 << arity_bits;
|
||||||
let next_domain_size = domain_size >> arity_bits;
|
let next_domain_size = domain_size >> arity_bits;
|
||||||
|
|||||||
@ -120,7 +120,7 @@ impl WirePartitions {
|
|||||||
.map(|chunk| {
|
.map(|chunk| {
|
||||||
let values = chunk
|
let values = chunk
|
||||||
.par_iter()
|
.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::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
PolynomialValues::new(values)
|
PolynomialValues::new(values)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -47,7 +47,7 @@ pub fn evaluate_gate_constraints_recursively<F: Field>(
|
|||||||
/// Evaluate the polynomial which vanishes on any multiplicative subgroup of a given order `n`.
|
/// Evaluate the polynomial which vanishes on any multiplicative subgroup of a given order `n`.
|
||||||
pub(crate) fn eval_zero_poly<F: Field>(n: usize, x: F) -> F {
|
pub(crate) fn eval_zero_poly<F: Field>(n: usize, x: F) -> F {
|
||||||
// Z(x) = x^n - 1
|
// 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
|
/// Evaluate the Lagrange basis `L_1` with `L_1(1) = 1`, and `L_1(x) = 0` for other members of an
|
||||||
|
|||||||
@ -90,7 +90,7 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
|||||||
assert_eq!(self.blinding, config.blinding[0]);
|
assert_eq!(self.blinding, config.blinding[0]);
|
||||||
for p in points {
|
for p in points {
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
p.exp_usize(self.degree),
|
p.exp(self.degree as u64),
|
||||||
F::Extension::ONE,
|
F::Extension::ONE,
|
||||||
"Opening point is in the subgroup."
|
"Opening point is in the subgroup."
|
||||||
);
|
);
|
||||||
@ -175,7 +175,7 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
|||||||
}
|
}
|
||||||
for p in points {
|
for p in points {
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
p.exp_usize(degree),
|
p.exp(degree as u64),
|
||||||
F::Extension::ONE,
|
F::Extension::ONE,
|
||||||
"Opening point is in the subgroup."
|
"Opening point is in the subgroup."
|
||||||
);
|
);
|
||||||
@ -374,7 +374,7 @@ mod tests {
|
|||||||
.map(|_| PolynomialCoeffs::new(F::rand_vec(degree)))
|
.map(|_| PolynomialCoeffs::new(F::rand_vec(degree)))
|
||||||
.collect();
|
.collect();
|
||||||
let mut points = F::Extension::rand_vec(num_points);
|
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);
|
points = F::Extension::rand_vec(num_points);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -91,8 +91,8 @@ impl<F: Field> PolynomialCoeffs<F> {
|
|||||||
// Equals to the evaluation of `a` on `{g.w^i}`.
|
// Equals to the evaluation of `a` on `{g.w^i}`.
|
||||||
let mut a_eval = fft(a);
|
let mut a_eval = fft(a);
|
||||||
// Compute the denominators `1/(g^n.w^(n*i) - 1)` using batch inversion.
|
// Compute the denominators `1/(g^n.w^(n*i) - 1)` using batch inversion.
|
||||||
let denominator_g = g.exp_usize(n);
|
let denominator_g = g.exp(n as u64);
|
||||||
let root_n = root.exp_usize(n);
|
let root_n = root.exp(n as u64);
|
||||||
let mut root_pow = F::ONE;
|
let mut root_pow = F::ONE;
|
||||||
let denominators = (0..a_eval.len())
|
let denominators = (0..a_eval.len())
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
|
|||||||
@ -434,7 +434,7 @@ mod tests {
|
|||||||
PolynomialCoeffs::new(xn_min_one_vec)
|
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 denom = PolynomialCoeffs::new(vec![-a, F::ONE]);
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
xn_minus_one.div_rem(&denom);
|
xn_minus_one.div_rem(&denom);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user