mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-08 00:33:06 +00:00
Remove custom primitive_root_of_unity in extension fields by modifying the generators.
This commit is contained in:
parent
1cbd12edbd
commit
e806d86f86
@ -83,9 +83,15 @@ impl Field for QuadraticCrandallField {
|
||||
// Does not fit in 64-bits.
|
||||
const ORDER: u64 = 0;
|
||||
const TWO_ADICITY: usize = 29;
|
||||
const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self([CrandallField(3), CrandallField::ONE]);
|
||||
const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self([
|
||||
CrandallField(6483724566312148654),
|
||||
CrandallField(12194665049945415126),
|
||||
]);
|
||||
// Chosen so that when raised to the power `1<<(Self::TWO_ADICITY-Self::BaseField::TWO_ADICITY)`,
|
||||
// we get `Self::BaseField::POWER_OF_TWO_GENERATOR`. This makes `primitive_root_of_unity` coherent
|
||||
// with the base field which implies that the FFT commutes with field inclusion.
|
||||
const POWER_OF_TWO_GENERATOR: Self =
|
||||
Self([CrandallField::ZERO, CrandallField(7889429148549342301)]);
|
||||
Self([CrandallField::ZERO, CrandallField(14420468973723774561)]);
|
||||
|
||||
// Algorithm 11.3.4 in Handbook of Elliptic and Hyperelliptic Curve Cryptography.
|
||||
fn try_inverse(&self) -> Option<Self> {
|
||||
@ -100,22 +106,6 @@ impl Field for QuadraticCrandallField {
|
||||
Some(a_pow_r_minus_1 * a_pow_r.0[0].inverse().into())
|
||||
}
|
||||
|
||||
// It's important that the primitive roots of unity are the same as the ones in the base field,
|
||||
// otherwise the FFT doesn't commute with field inclusion.
|
||||
fn primitive_root_of_unity(n_log: usize) -> Self {
|
||||
if n_log <= CrandallField::TWO_ADICITY {
|
||||
CrandallField::primitive_root_of_unity(n_log).into()
|
||||
} else {
|
||||
// The root of unity isn't in the base field so we need to compute it manually.
|
||||
assert!(n_log <= Self::TWO_ADICITY);
|
||||
let mut base = Self::POWER_OF_TWO_GENERATOR;
|
||||
for _ in n_log..Self::TWO_ADICITY {
|
||||
base = base.square();
|
||||
}
|
||||
base
|
||||
}
|
||||
}
|
||||
|
||||
fn to_canonical_u64(&self) -> u64 {
|
||||
self.0[0].to_canonical_u64()
|
||||
}
|
||||
@ -311,4 +301,22 @@ mod tests {
|
||||
F::ONE
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_power_of_two_gen() {
|
||||
type F = QuadraticCrandallField;
|
||||
// F::ORDER = 2^29 * 2762315674048163 * 229454332791453 + 1
|
||||
assert_eq!(
|
||||
F::MULTIPLICATIVE_GROUP_GENERATOR
|
||||
.exp_usize(2762315674048163)
|
||||
.exp_usize(229454332791453),
|
||||
F::POWER_OF_TWO_GENERATOR
|
||||
);
|
||||
assert_eq!(
|
||||
F::POWER_OF_TWO_GENERATOR.exp_usize(
|
||||
1 << (F::TWO_ADICITY - <F as QuadraticFieldExtension>::BaseField::TWO_ADICITY)
|
||||
),
|
||||
<F as QuadraticFieldExtension>::BaseField::POWER_OF_TWO_GENERATOR.into()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,16 +110,19 @@ impl Field for QuarticCrandallField {
|
||||
const ORDER: u64 = 0;
|
||||
const TWO_ADICITY: usize = 30;
|
||||
const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self([
|
||||
CrandallField(3),
|
||||
CrandallField::ONE,
|
||||
CrandallField::ZERO,
|
||||
CrandallField::ZERO,
|
||||
CrandallField(12476589904174392631),
|
||||
CrandallField(896937834427772243),
|
||||
CrandallField(7795248119019507390),
|
||||
CrandallField(9005769437373554825),
|
||||
]);
|
||||
// Chosen so that when raised to the power `1<<(Self::TWO_ADICITY-Self::BaseField::TWO_ADICITY)`,
|
||||
// we get `Self::BaseField::POWER_OF_TWO_GENERATOR`. This makes `primitive_root_of_unity` coherent
|
||||
// with the base field which implies that the FFT commutes with field inclusion.
|
||||
const POWER_OF_TWO_GENERATOR: Self = Self([
|
||||
CrandallField::ZERO,
|
||||
CrandallField::ZERO,
|
||||
CrandallField::ZERO,
|
||||
CrandallField(14096607364803438105),
|
||||
CrandallField(15170983443234254033),
|
||||
]);
|
||||
|
||||
// Algorithm 11.3.4 in Handbook of Elliptic and Hyperelliptic Curve Cryptography.
|
||||
@ -138,22 +141,6 @@ impl Field for QuarticCrandallField {
|
||||
Some(a_pow_r_minus_1 * a_pow_r.0[0].inverse().into())
|
||||
}
|
||||
|
||||
// It's important that the primitive roots of unity are the same as the ones in the base field,
|
||||
// otherwise the FFT doesn't commute with field inclusion.
|
||||
fn primitive_root_of_unity(n_log: usize) -> Self {
|
||||
if n_log <= CrandallField::TWO_ADICITY {
|
||||
CrandallField::primitive_root_of_unity(n_log).into()
|
||||
} else {
|
||||
// The root of unity isn't in the base field so we need to compute it manually.
|
||||
assert!(n_log <= Self::TWO_ADICITY);
|
||||
let mut base = Self::POWER_OF_TWO_GENERATOR;
|
||||
for _ in n_log..Self::TWO_ADICITY {
|
||||
base = base.square();
|
||||
}
|
||||
base
|
||||
}
|
||||
}
|
||||
|
||||
fn to_canonical_u64(&self) -> u64 {
|
||||
self.0[0].to_canonical_u64()
|
||||
}
|
||||
@ -370,4 +357,26 @@ mod tests {
|
||||
F::ONE
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_power_of_two_gen() {
|
||||
type F = QuarticCrandallField;
|
||||
// F::ORDER = 2^30 * 1090552343587053358839971118999869 * 98885475095492590491252558464653635 + 1
|
||||
assert_eq!(
|
||||
exp_naive(
|
||||
exp_naive(
|
||||
F::MULTIPLICATIVE_GROUP_GENERATOR,
|
||||
1090552343587053358839971118999869
|
||||
),
|
||||
98885475095492590491252558464653635
|
||||
),
|
||||
F::POWER_OF_TWO_GENERATOR
|
||||
);
|
||||
assert_eq!(
|
||||
F::POWER_OF_TWO_GENERATOR.exp_usize(
|
||||
1 << (F::TWO_ADICITY - <F as QuarticFieldExtension>::BaseField::TWO_ADICITY)
|
||||
),
|
||||
<F as QuarticFieldExtension>::BaseField::POWER_OF_TWO_GENERATOR.into()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user