Precompute the Dth root of unity. (#296)

This commit is contained in:
Hamish Ivey-Law 2021-10-10 20:42:10 +11:00 committed by GitHub
parent 8f59381c87
commit 41b26e1f56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 3 deletions

View File

@ -322,6 +322,9 @@ impl Extendable<2> for CrandallField {
// `R.<x> = GF(p)[]; assert (x^2 - 3).is_irreducible()`.
const W: Self = Self(3);
// DTH_ROOT = W^((ORDER - 1)/2)
const DTH_ROOT: Self = Self(18446744071293632512);
const EXT_MULTIPLICATIVE_GROUP_GENERATOR: [Self; 2] =
[Self(6483724566312148654), Self(12194665049945415126)];
@ -333,6 +336,9 @@ impl Extendable<4> for CrandallField {
const W: Self = Self(3);
// DTH_ROOT = W^((ORDER - 1)/4)
const DTH_ROOT: Self = Self(6183774639018825925);
const EXT_MULTIPLICATIVE_GROUP_GENERATOR: [Self; 4] = [
Self(12476589904174392631),
Self(896937834427772243),

View File

@ -14,10 +14,16 @@ pub mod target;
pub trait OEF<const D: usize>: FieldExtension<D> {
// Element W of BaseField, such that `X^d - W` is irreducible over BaseField.
const W: Self::BaseField;
// Element of BaseField such that DTH_ROOT^D == 1. Implementors
// should set this to W^((p - 1)/D), where W is as above and p is
// the order of the BaseField.
const DTH_ROOT: Self::BaseField;
}
impl<F: Field> OEF<1> for F {
const W: Self::BaseField = F::ZERO;
const DTH_ROOT: Self::BaseField = F::ZERO;
}
pub trait Frobenius<const D: usize>: OEF<D> {
@ -26,16 +32,26 @@ pub trait Frobenius<const D: usize>: OEF<D> {
self.repeated_frobenius(1)
}
/// Repeated Frobenius automorphisms: x -> x^(p^k).
/// Repeated Frobenius automorphisms: x -> x^(p^count).
///
/// Follows precomputation suggestion in Section 11.3.3 of the
/// Handbook of Elliptic and Hyperelliptic Curve Cryptography.
fn repeated_frobenius(&self, count: usize) -> Self {
if count == 0 {
return *self;
} else if count >= D {
// x |-> x^(p^D) is the identity, so x^(p^count) ==
// x^(p^(count % D))
return self.repeated_frobenius(count % D);
}
let arr = self.to_basefield_array();
let k = (Self::BaseField::order() - 1u32) / (D as u64);
let z0 = Self::W.exp_biguint(&(k * count as u64));
// z0 = DTH_ROOT^count = W^(k * count) where k = floor((p^D-1)/D)
let mut z0 = Self::DTH_ROOT;
for _ in 1..count {
z0 *= Self::DTH_ROOT;
}
let mut res = [Self::BaseField::ZERO; D];
for (i, z) in z0.powers().take(D).enumerate() {
res[i] = arr[i] * z;
@ -50,6 +66,8 @@ pub trait Extendable<const D: usize>: PrimeField + Sized {
const W: Self;
const DTH_ROOT: Self;
const EXT_MULTIPLICATIVE_GROUP_GENERATOR: [Self; D];
/// Chosen so that when raised to the power `1<<(Self::TWO_ADICITY-Self::BaseField::TWO_ADICITY)`,
@ -61,6 +79,7 @@ pub trait Extendable<const D: usize>: PrimeField + Sized {
impl<F: PrimeField + Frobenius<1> + FieldExtension<1, BaseField = F>> Extendable<1> for F {
type Extension = F;
const W: Self = F::ZERO;
const DTH_ROOT: Self = F::ZERO;
const EXT_MULTIPLICATIVE_GROUP_GENERATOR: [Self; 1] = [F::MULTIPLICATIVE_GROUP_GENERATOR];
const EXT_POWER_OF_TWO_GENERATOR: [Self; 1] = [F::POWER_OF_TWO_GENERATOR];
}

View File

@ -21,6 +21,7 @@ impl<F: Extendable<2>> Default for QuadraticExtension<F> {
impl<F: Extendable<2>> OEF<2> for QuadraticExtension<F> {
const W: F = F::W;
const DTH_ROOT: F = F::DTH_ROOT;
}
impl<F: Extendable<2>> Frobenius<2> for QuadraticExtension<F> {}

View File

@ -22,6 +22,7 @@ impl<F: Extendable<4>> Default for QuarticExtension<F> {
impl<F: Extendable<4>> OEF<4> for QuarticExtension<F> {
const W: F = F::W;
const DTH_ROOT: F = F::DTH_ROOT;
}
impl<F: Extendable<4>> Frobenius<4> for QuarticExtension<F> {}

View File

@ -224,6 +224,9 @@ impl Extendable<2> for GoldilocksField {
// `R.<x> = GF(p)[]; assert (x^2 - 7).is_irreducible()`.
const W: Self = Self(7);
// DTH_ROOT = W^((ORDER - 1)/2)
const DTH_ROOT: Self = Self(18446744069414584320);
const EXT_MULTIPLICATIVE_GROUP_GENERATOR: [Self; 2] =
[Self(18081566051660590251), Self(16121475356294670766)];
@ -235,6 +238,9 @@ impl Extendable<4> for GoldilocksField {
const W: Self = Self(7);
// DTH_ROOT = W^((ORDER - 1)/4)
const DTH_ROOT: Self = Self(281474976710656);
const EXT_MULTIPLICATIVE_GROUP_GENERATOR: [Self; 4] = [
Self(5024755240244648895),
Self(13227474371289740625),