mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-10 17:53:06 +00:00
Merge pull request #246 from mir-protocol/goldilocks_ext
Goldilocks extension fields
This commit is contained in:
commit
b5d35b3582
@ -201,82 +201,25 @@ impl<F: Extendable<2>> DivAssign for QuadraticExtension<F> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::extension_field::quadratic::QuadraticExtension;
|
||||
use crate::field::extension_field::Frobenius;
|
||||
use crate::field::field_types::Field;
|
||||
use crate::test_field_arithmetic;
|
||||
mod crandall {
|
||||
use crate::{test_field_arithmetic, test_field_extension};
|
||||
|
||||
#[test]
|
||||
fn test_add_neg_sub_mul() {
|
||||
type F = QuadraticExtension<CrandallField>;
|
||||
let x = F::rand();
|
||||
let y = F::rand();
|
||||
let z = F::rand();
|
||||
assert_eq!(x + (-x), F::ZERO);
|
||||
assert_eq!(-x, F::ZERO - x);
|
||||
assert_eq!(x + x, x * F::TWO);
|
||||
assert_eq!(x * (-x), -x.square());
|
||||
assert_eq!(x + y, y + x);
|
||||
assert_eq!(x * y, y * x);
|
||||
assert_eq!(x * (y * z), (x * y) * z);
|
||||
assert_eq!(x - (y + z), (x - y) - z);
|
||||
assert_eq!((x + y) - z, x + (y - z));
|
||||
assert_eq!(x * (y + z), x * y + x * z);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_div() {
|
||||
type F = QuadraticExtension<CrandallField>;
|
||||
let x = F::rand();
|
||||
let y = F::rand();
|
||||
let z = F::rand();
|
||||
assert_eq!(x * x.inverse(), F::ONE);
|
||||
assert_eq!(x.inverse() * x, F::ONE);
|
||||
assert_eq!(x.square().inverse(), x.inverse().square());
|
||||
assert_eq!((x / y) * y, x);
|
||||
assert_eq!(x / (y * z), (x / y) / z);
|
||||
assert_eq!((x * y) / z, x * (y / z));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_frobenius() {
|
||||
type F = QuadraticExtension<CrandallField>;
|
||||
let x = F::rand();
|
||||
assert_eq!(x.exp_biguint(&CrandallField::order()), x.frobenius());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_field_order() {
|
||||
// F::order() = 340282366831806780677557380898690695169 = 18446744071293632512 *18446744071293632514 + 1
|
||||
type F = QuadraticExtension<CrandallField>;
|
||||
let x = F::rand();
|
||||
assert_eq!(
|
||||
x.exp_u64(18446744071293632512)
|
||||
.exp_u64(18446744071293632514),
|
||||
F::ONE
|
||||
test_field_extension!(crate::field::crandall_field::CrandallField, 2);
|
||||
test_field_arithmetic!(
|
||||
crate::field::extension_field::quadratic::QuadraticExtension<
|
||||
crate::field::crandall_field::CrandallField,
|
||||
>
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_power_of_two_gen() {
|
||||
type F = QuadraticExtension<CrandallField>;
|
||||
// F::order() = 2^29 * 2762315674048163 * 229454332791453 + 1
|
||||
assert_eq!(
|
||||
F::MULTIPLICATIVE_GROUP_GENERATOR
|
||||
.exp_u64(2762315674048163)
|
||||
.exp_u64(229454332791453),
|
||||
F::POWER_OF_TWO_GENERATOR
|
||||
);
|
||||
assert_eq!(
|
||||
F::POWER_OF_TWO_GENERATOR.exp_u64(1 << (F::TWO_ADICITY - CrandallField::TWO_ADICITY)),
|
||||
CrandallField::POWER_OF_TWO_GENERATOR.into()
|
||||
mod goldilocks {
|
||||
use crate::{test_field_arithmetic, test_field_extension};
|
||||
|
||||
test_field_extension!(crate::field::goldilocks_field::GoldilocksField, 2);
|
||||
test_field_arithmetic!(
|
||||
crate::field::extension_field::quadratic::QuadraticExtension<
|
||||
crate::field::goldilocks_field::GoldilocksField,
|
||||
>
|
||||
);
|
||||
}
|
||||
|
||||
test_field_arithmetic!(
|
||||
crate::field::extension_field::quadratic::QuadraticExtension<
|
||||
crate::field::crandall_field::CrandallField,
|
||||
>
|
||||
);
|
||||
}
|
||||
|
||||
@ -227,108 +227,25 @@ impl<F: Extendable<4>> DivAssign for QuarticExtension<F> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::extension_field::quartic::QuarticExtension;
|
||||
use crate::field::extension_field::Frobenius;
|
||||
use crate::field::field_types::Field;
|
||||
use crate::test_field_arithmetic;
|
||||
mod crandall {
|
||||
use crate::{test_field_arithmetic, test_field_extension};
|
||||
|
||||
fn exp_naive<F: Field>(x: F, power: u128) -> F {
|
||||
let mut current = x;
|
||||
let mut product = F::ONE;
|
||||
|
||||
for j in 0..128 {
|
||||
if (power >> j & 1) != 0 {
|
||||
product *= current;
|
||||
}
|
||||
current = current.square();
|
||||
}
|
||||
product
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_neg_sub_mul() {
|
||||
type F = QuarticExtension<CrandallField>;
|
||||
let x = F::rand();
|
||||
let y = F::rand();
|
||||
let z = F::rand();
|
||||
assert_eq!(x + (-x), F::ZERO);
|
||||
assert_eq!(-x, F::ZERO - x);
|
||||
assert_eq!(x + x, x * F::TWO.into());
|
||||
assert_eq!(x * (-x), -x.square());
|
||||
assert_eq!(x + y, y + x);
|
||||
assert_eq!(x * y, y * x);
|
||||
assert_eq!(x * (y * z), (x * y) * z);
|
||||
assert_eq!(x - (y + z), (x - y) - z);
|
||||
assert_eq!((x + y) - z, x + (y - z));
|
||||
assert_eq!(x * (y + z), x * y + x * z);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_div() {
|
||||
type F = QuarticExtension<CrandallField>;
|
||||
let x = F::rand();
|
||||
let y = F::rand();
|
||||
let z = F::rand();
|
||||
assert_eq!(x * x.inverse(), F::ONE);
|
||||
assert_eq!(x.inverse() * x, F::ONE);
|
||||
assert_eq!(x.square().inverse(), x.inverse().square());
|
||||
assert_eq!((x / y) * y, x);
|
||||
assert_eq!(x / (y * z), (x / y) / z);
|
||||
assert_eq!((x * y) / z, x * (y / z));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_frobenius() {
|
||||
type F = QuarticExtension<CrandallField>;
|
||||
const D: usize = 4;
|
||||
let x = F::rand();
|
||||
assert_eq!(x.exp_biguint(&CrandallField::order()), x.frobenius());
|
||||
for count in 2..D {
|
||||
assert_eq!(
|
||||
x.repeated_frobenius(count),
|
||||
(0..count).fold(x, |acc, _| acc.frobenius())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_field_order() {
|
||||
// F::order() = 340282366831806780677557380898690695168 * 340282366831806780677557380898690695170 + 1
|
||||
type F = QuarticExtension<CrandallField>;
|
||||
let x = F::rand();
|
||||
assert_eq!(
|
||||
exp_naive(
|
||||
exp_naive(x, 340282366831806780677557380898690695168),
|
||||
340282366831806780677557380898690695170
|
||||
),
|
||||
F::ONE
|
||||
test_field_extension!(crate::field::crandall_field::CrandallField, 4);
|
||||
test_field_arithmetic!(
|
||||
crate::field::extension_field::quartic::QuarticExtension<
|
||||
crate::field::crandall_field::CrandallField,
|
||||
>
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_power_of_two_gen() {
|
||||
type F = QuarticExtension<CrandallField>;
|
||||
// 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_u64(1 << (F::TWO_ADICITY - CrandallField::TWO_ADICITY)),
|
||||
CrandallField::POWER_OF_TWO_GENERATOR.into()
|
||||
mod goldilocks {
|
||||
use crate::{test_field_arithmetic, test_field_extension};
|
||||
|
||||
test_field_extension!(crate::field::goldilocks_field::GoldilocksField, 4);
|
||||
test_field_arithmetic!(
|
||||
crate::field::extension_field::quartic::QuarticExtension<
|
||||
crate::field::goldilocks_field::GoldilocksField,
|
||||
>
|
||||
);
|
||||
}
|
||||
|
||||
test_field_arithmetic!(
|
||||
crate::field::extension_field::quartic::QuarticExtension<
|
||||
crate::field::crandall_field::CrandallField,
|
||||
>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::extension_field::Frobenius;
|
||||
use crate::field::field_types::Field;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! test_field_arithmetic {
|
||||
($field:ty) => {
|
||||
@ -93,3 +97,91 @@ macro_rules! test_field_arithmetic {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) fn test_add_neg_sub_mul<BF: Extendable<D>, const D: usize>() {
|
||||
let x = BF::Extension::rand();
|
||||
let y = BF::Extension::rand();
|
||||
let z = BF::Extension::rand();
|
||||
assert_eq!(x + (-x), BF::Extension::ZERO);
|
||||
assert_eq!(-x, BF::Extension::ZERO - x);
|
||||
assert_eq!(x + x, x * BF::Extension::TWO);
|
||||
assert_eq!(x * (-x), -x.square());
|
||||
assert_eq!(x + y, y + x);
|
||||
assert_eq!(x * y, y * x);
|
||||
assert_eq!(x * (y * z), (x * y) * z);
|
||||
assert_eq!(x - (y + z), (x - y) - z);
|
||||
assert_eq!((x + y) - z, x + (y - z));
|
||||
assert_eq!(x * (y + z), x * y + x * z);
|
||||
}
|
||||
|
||||
pub(crate) fn test_inv_div<BF: Extendable<D>, const D: usize>() {
|
||||
let x = BF::Extension::rand();
|
||||
let y = BF::Extension::rand();
|
||||
let z = BF::Extension::rand();
|
||||
assert_eq!(x * x.inverse(), BF::Extension::ONE);
|
||||
assert_eq!(x.inverse() * x, BF::Extension::ONE);
|
||||
assert_eq!(x.square().inverse(), x.inverse().square());
|
||||
assert_eq!((x / y) * y, x);
|
||||
assert_eq!(x / (y * z), (x / y) / z);
|
||||
assert_eq!((x * y) / z, x * (y / z));
|
||||
}
|
||||
|
||||
pub(crate) fn test_frobenius<BF: Extendable<D>, const D: usize>() {
|
||||
let x = BF::Extension::rand();
|
||||
assert_eq!(x.exp_biguint(&BF::order()), x.frobenius());
|
||||
for count in 2..D {
|
||||
assert_eq!(
|
||||
x.repeated_frobenius(count),
|
||||
(0..count).fold(x, |acc, _| acc.frobenius())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn test_field_order<BF: Extendable<D>, const D: usize>() {
|
||||
let x = BF::Extension::rand();
|
||||
assert_eq!(
|
||||
x.exp_biguint(&(BF::Extension::order() - 1u8)),
|
||||
BF::Extension::ONE
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn test_power_of_two_gen<BF: Extendable<D>, const D: usize>() {
|
||||
assert_eq!(
|
||||
BF::Extension::MULTIPLICATIVE_GROUP_GENERATOR
|
||||
.exp_biguint(&(BF::Extension::order() >> BF::Extension::TWO_ADICITY)),
|
||||
BF::Extension::POWER_OF_TWO_GENERATOR,
|
||||
);
|
||||
assert_eq!(
|
||||
BF::Extension::POWER_OF_TWO_GENERATOR
|
||||
.exp_u64(1 << (BF::Extension::TWO_ADICITY - BF::TWO_ADICITY)),
|
||||
BF::POWER_OF_TWO_GENERATOR.into()
|
||||
);
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! test_field_extension {
|
||||
($field:ty, $d:expr) => {
|
||||
mod field_extension {
|
||||
#[test]
|
||||
fn test_add_neg_sub_mul() {
|
||||
crate::field::field_testing::test_add_neg_sub_mul::<$field, $d>();
|
||||
}
|
||||
#[test]
|
||||
fn test_inv_div() {
|
||||
crate::field::field_testing::test_inv_div::<$field, $d>();
|
||||
}
|
||||
#[test]
|
||||
fn test_frobenius() {
|
||||
crate::field::field_testing::test_frobenius::<$field, $d>();
|
||||
}
|
||||
#[test]
|
||||
fn test_field_order() {
|
||||
crate::field::field_testing::test_field_order::<$field, $d>();
|
||||
}
|
||||
#[test]
|
||||
fn test_power_of_two_gen() {
|
||||
crate::field::field_testing::test_power_of_two_gen::<$field, $d>();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -8,6 +8,9 @@ use num::BigUint;
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::field::extension_field::quadratic::QuadraticExtension;
|
||||
use crate::field::extension_field::quartic::QuarticExtension;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::inversion::try_inverse_u64;
|
||||
|
||||
@ -213,6 +216,35 @@ impl DivAssign for GoldilocksField {
|
||||
}
|
||||
}
|
||||
|
||||
impl Extendable<2> for GoldilocksField {
|
||||
type Extension = QuadraticExtension<Self>;
|
||||
|
||||
// Verifiable in Sage with
|
||||
// `R.<x> = GF(p)[]; assert (x^2 - 7).is_irreducible()`.
|
||||
const W: Self = Self(7);
|
||||
|
||||
const EXT_MULTIPLICATIVE_GROUP_GENERATOR: [Self; 2] =
|
||||
[Self(18081566051660590251), Self(16121475356294670766)];
|
||||
|
||||
const EXT_POWER_OF_TWO_GENERATOR: [Self; 2] = [Self(0), Self(15659105665374529263)];
|
||||
}
|
||||
|
||||
impl Extendable<4> for GoldilocksField {
|
||||
type Extension = QuarticExtension<Self>;
|
||||
|
||||
const W: Self = Self(7);
|
||||
|
||||
const EXT_MULTIPLICATIVE_GROUP_GENERATOR: [Self; 4] = [
|
||||
Self(5024755240244648895),
|
||||
Self(13227474371289740625),
|
||||
Self(3912887029498544536),
|
||||
Self(3900057112666848848),
|
||||
];
|
||||
|
||||
const EXT_POWER_OF_TWO_GENERATOR: [Self; 4] =
|
||||
[Self(0), Self(0), Self(0), Self(12587610116473453104)];
|
||||
}
|
||||
|
||||
/// Reduces to a 64-bit value. The result might not be in canonical form; it could be in between the
|
||||
/// field order and `2^64`.
|
||||
#[inline]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user