mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-11 10:13:09 +00:00
Merge pull request #391 from mir-protocol/prime_field
Remove `PrimeField` type from the `Field` trait
This commit is contained in:
commit
68e3befc08
@ -50,19 +50,16 @@ impl<F: Extendable<2>> From<F> for QuadraticExtension<F> {
|
||||
}
|
||||
|
||||
impl<F: Extendable<2>> Field for QuadraticExtension<F> {
|
||||
type PrimeField = F;
|
||||
|
||||
const ZERO: Self = Self([F::ZERO; 2]);
|
||||
const ONE: Self = Self([F::ONE, F::ZERO]);
|
||||
const TWO: Self = Self([F::TWO, F::ZERO]);
|
||||
const NEG_ONE: Self = Self([F::NEG_ONE, F::ZERO]);
|
||||
|
||||
const CHARACTERISTIC: u64 = F::CHARACTERISTIC;
|
||||
|
||||
// `p^2 - 1 = (p - 1)(p + 1)`. The `p - 1` term has a two-adicity of `F::TWO_ADICITY`. As
|
||||
// long as `F::TWO_ADICITY >= 2`, `p` can be written as `4n + 1`, so `p + 1` can be written as
|
||||
// `2(2n + 1)`, which has a 2-adicity of 1.
|
||||
const TWO_ADICITY: usize = F::TWO_ADICITY + 1;
|
||||
const CHARACTERISTIC_TWO_ADICITY: usize = F::CHARACTERISTIC_TWO_ADICITY;
|
||||
|
||||
const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self(F::EXT_MULTIPLICATIVE_GROUP_GENERATOR);
|
||||
const POWER_OF_TWO_GENERATOR: Self = Self(F::EXT_POWER_OF_TWO_GENERATOR);
|
||||
@ -72,6 +69,9 @@ impl<F: Extendable<2>> Field for QuadraticExtension<F> {
|
||||
fn order() -> BigUint {
|
||||
F::order() * F::order()
|
||||
}
|
||||
fn characteristic() -> BigUint {
|
||||
F::characteristic()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn square(&self) -> Self {
|
||||
|
||||
@ -51,20 +51,17 @@ impl<F: Extendable<4>> From<F> for QuarticExtension<F> {
|
||||
}
|
||||
|
||||
impl<F: Extendable<4>> Field for QuarticExtension<F> {
|
||||
type PrimeField = F;
|
||||
|
||||
const ZERO: Self = Self([F::ZERO; 4]);
|
||||
const ONE: Self = Self([F::ONE, F::ZERO, F::ZERO, F::ZERO]);
|
||||
const TWO: Self = Self([F::TWO, F::ZERO, F::ZERO, F::ZERO]);
|
||||
const NEG_ONE: Self = Self([F::NEG_ONE, F::ZERO, F::ZERO, F::ZERO]);
|
||||
|
||||
const CHARACTERISTIC: u64 = F::ORDER;
|
||||
|
||||
// `p^4 - 1 = (p - 1)(p + 1)(p^2 + 1)`. The `p - 1` term has a two-adicity of `F::TWO_ADICITY`.
|
||||
// As long as `F::TWO_ADICITY >= 2`, `p` can be written as `4n + 1`, so `p + 1` can be written as
|
||||
// `2(2n + 1)`, which has a 2-adicity of 1. A similar argument can show that `p^2 + 1` also has
|
||||
// a 2-adicity of 1.
|
||||
const TWO_ADICITY: usize = F::TWO_ADICITY + 2;
|
||||
const CHARACTERISTIC_TWO_ADICITY: usize = F::CHARACTERISTIC_TWO_ADICITY;
|
||||
|
||||
const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self(F::EXT_MULTIPLICATIVE_GROUP_GENERATOR);
|
||||
const POWER_OF_TWO_GENERATOR: Self = Self(F::EXT_POWER_OF_TWO_GENERATOR);
|
||||
@ -74,6 +71,9 @@ impl<F: Extendable<4>> Field for QuarticExtension<F> {
|
||||
fn order() -> BigUint {
|
||||
F::order().pow(4u32)
|
||||
}
|
||||
fn characteristic() -> BigUint {
|
||||
F::characteristic()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn square(&self) -> Self {
|
||||
|
||||
@ -4,7 +4,7 @@ use std::iter::{Product, Sum};
|
||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||
|
||||
use num::bigint::BigUint;
|
||||
use num::{Integer, One, Zero};
|
||||
use num::{Integer, One, ToPrimitive, Zero};
|
||||
use rand::Rng;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
@ -42,18 +42,18 @@ pub trait Field:
|
||||
+ Serialize
|
||||
+ DeserializeOwned
|
||||
{
|
||||
type PrimeField: PrimeField;
|
||||
|
||||
const ZERO: Self;
|
||||
const ONE: Self;
|
||||
const TWO: Self;
|
||||
const NEG_ONE: Self;
|
||||
|
||||
const CHARACTERISTIC: u64;
|
||||
|
||||
/// The 2-adicity of this field's multiplicative group.
|
||||
const TWO_ADICITY: usize;
|
||||
|
||||
/// The field's characteristic and it's 2-adicity.
|
||||
/// Set to `None` when the characteristic doesn't fit in a u64.
|
||||
const CHARACTERISTIC_TWO_ADICITY: usize;
|
||||
|
||||
/// Generator of the entire multiplicative group, i.e. all non-zero elements.
|
||||
const MULTIPLICATIVE_GROUP_GENERATOR: Self;
|
||||
/// Generator of a multiplicative subgroup of order `2^TWO_ADICITY`.
|
||||
@ -63,6 +63,7 @@ pub trait Field:
|
||||
const BITS: usize;
|
||||
|
||||
fn order() -> BigUint;
|
||||
fn characteristic() -> BigUint;
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
@ -205,29 +206,31 @@ pub trait Field:
|
||||
// exp exceeds t, we repeatedly multiply by 2^-t and reduce
|
||||
// exp until it's in the right range.
|
||||
|
||||
let p = Self::CHARACTERISTIC;
|
||||
if let Some(p) = Self::characteristic().to_u64() {
|
||||
// NB: The only reason this is split into two cases is to save
|
||||
// the multiplication (and possible calculation of
|
||||
// inverse_2_pow_adicity) in the usual case that exp <=
|
||||
// TWO_ADICITY. Can remove the branch and simplify if that
|
||||
// saving isn't worth it.
|
||||
|
||||
// NB: The only reason this is split into two cases is to save
|
||||
// the multiplication (and possible calculation of
|
||||
// inverse_2_pow_adicity) in the usual case that exp <=
|
||||
// TWO_ADICITY. Can remove the branch and simplify if that
|
||||
// saving isn't worth it.
|
||||
if exp > Self::CHARACTERISTIC_TWO_ADICITY {
|
||||
// NB: This should be a compile-time constant
|
||||
let inverse_2_pow_adicity: Self =
|
||||
Self::from_canonical_u64(p - ((p - 1) >> Self::CHARACTERISTIC_TWO_ADICITY));
|
||||
|
||||
if exp > Self::PrimeField::TWO_ADICITY {
|
||||
// NB: This should be a compile-time constant
|
||||
let inverse_2_pow_adicity: Self =
|
||||
Self::from_canonical_u64(p - ((p - 1) >> Self::PrimeField::TWO_ADICITY));
|
||||
let mut res = inverse_2_pow_adicity;
|
||||
let mut e = exp - Self::CHARACTERISTIC_TWO_ADICITY;
|
||||
|
||||
let mut res = inverse_2_pow_adicity;
|
||||
let mut e = exp - Self::PrimeField::TWO_ADICITY;
|
||||
|
||||
while e > Self::PrimeField::TWO_ADICITY {
|
||||
res *= inverse_2_pow_adicity;
|
||||
e -= Self::PrimeField::TWO_ADICITY;
|
||||
while e > Self::CHARACTERISTIC_TWO_ADICITY {
|
||||
res *= inverse_2_pow_adicity;
|
||||
e -= Self::CHARACTERISTIC_TWO_ADICITY;
|
||||
}
|
||||
res * Self::from_canonical_u64(p - ((p - 1) >> e))
|
||||
} else {
|
||||
Self::from_canonical_u64(p - ((p - 1) >> exp))
|
||||
}
|
||||
res * Self::from_canonical_u64(p - ((p - 1) >> e))
|
||||
} else {
|
||||
Self::from_canonical_u64(p - ((p - 1) >> exp))
|
||||
Self::TWO.inverse().exp_u64(exp as u64)
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,7 +408,7 @@ pub trait Field:
|
||||
}
|
||||
|
||||
/// A finite field of prime order less than 2^64.
|
||||
pub trait PrimeField: Field<PrimeField = Self> {
|
||||
pub trait PrimeField: Field {
|
||||
const ORDER: u64;
|
||||
|
||||
fn to_canonical_u64(&self) -> u64;
|
||||
|
||||
@ -62,15 +62,13 @@ impl Debug for GoldilocksField {
|
||||
}
|
||||
|
||||
impl Field for GoldilocksField {
|
||||
type PrimeField = Self;
|
||||
|
||||
const ZERO: Self = Self(0);
|
||||
const ONE: Self = Self(1);
|
||||
const TWO: Self = Self(2);
|
||||
const NEG_ONE: Self = Self(Self::ORDER - 1);
|
||||
const CHARACTERISTIC: u64 = Self::ORDER;
|
||||
|
||||
const TWO_ADICITY: usize = 32;
|
||||
const CHARACTERISTIC_TWO_ADICITY: usize = Self::TWO_ADICITY;
|
||||
|
||||
// Sage: `g = GF(p).multiplicative_generator()`
|
||||
const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self(7);
|
||||
@ -87,6 +85,9 @@ impl Field for GoldilocksField {
|
||||
fn order() -> BigUint {
|
||||
Self::ORDER.into()
|
||||
}
|
||||
fn characteristic() -> BigUint {
|
||||
Self::order()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn try_inverse(&self) -> Option<Self> {
|
||||
|
||||
@ -39,7 +39,6 @@ where
|
||||
Self::Scalar: Sub<Self, Output = Self>,
|
||||
{
|
||||
type Scalar: Field;
|
||||
type PackedPrimeField: PackedField<Scalar = <Self::Scalar as Field>::PrimeField>;
|
||||
|
||||
const WIDTH: usize;
|
||||
const ZERO: Self;
|
||||
@ -102,7 +101,6 @@ where
|
||||
|
||||
unsafe impl<F: Field> PackedField for F {
|
||||
type Scalar = Self;
|
||||
type PackedPrimeField = F::PrimeField;
|
||||
|
||||
const WIDTH: usize = 1;
|
||||
const ZERO: Self = <F as Field>::ZERO;
|
||||
|
||||
@ -144,7 +144,7 @@ macro_rules! test_prime_field_arithmetic {
|
||||
fn inverse_2exp() {
|
||||
type F = $field;
|
||||
|
||||
let v = <F as Field>::PrimeField::TWO_ADICITY;
|
||||
let v = <F as Field>::TWO_ADICITY;
|
||||
|
||||
for e in [0, 1, 2, 3, 4, v - 2, v - 1, v, v + 1, v + 2, 123 * v] {
|
||||
let x = F::TWO.exp_u64(e as u64);
|
||||
|
||||
@ -11,7 +11,6 @@ use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::field::field_types::Field;
|
||||
use crate::field::goldilocks_field::GoldilocksField;
|
||||
|
||||
/// The base field of the secp256k1 elliptic curve.
|
||||
///
|
||||
@ -68,9 +67,6 @@ impl Debug for Secp256K1Base {
|
||||
}
|
||||
|
||||
impl Field for Secp256K1Base {
|
||||
// TODO: fix
|
||||
type PrimeField = GoldilocksField;
|
||||
|
||||
const ZERO: Self = Self([0; 4]);
|
||||
const ONE: Self = Self([1, 0, 0, 0]);
|
||||
const TWO: Self = Self([2, 0, 0, 0]);
|
||||
@ -81,9 +77,8 @@ impl Field for Secp256K1Base {
|
||||
0xFFFFFFFFFFFFFFFF,
|
||||
]);
|
||||
|
||||
// TODO: fix
|
||||
const CHARACTERISTIC: u64 = 0;
|
||||
const TWO_ADICITY: usize = 1;
|
||||
const CHARACTERISTIC_TWO_ADICITY: usize = Self::TWO_ADICITY;
|
||||
|
||||
// Sage: `g = GF(p).multiplicative_generator()`
|
||||
const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self([5, 0, 0, 0]);
|
||||
@ -99,6 +94,9 @@ impl Field for Secp256K1Base {
|
||||
0xFFFFFFFF,
|
||||
])
|
||||
}
|
||||
fn characteristic() -> BigUint {
|
||||
Self::order()
|
||||
}
|
||||
|
||||
fn try_inverse(&self) -> Option<Self> {
|
||||
if self.is_zero() {
|
||||
|
||||
@ -12,7 +12,6 @@ use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::field::field_types::Field;
|
||||
use crate::field::goldilocks_field::GoldilocksField;
|
||||
|
||||
/// The base field of the secp256k1 elliptic curve.
|
||||
///
|
||||
@ -71,9 +70,6 @@ impl Debug for Secp256K1Scalar {
|
||||
}
|
||||
|
||||
impl Field for Secp256K1Scalar {
|
||||
// TODO: fix
|
||||
type PrimeField = GoldilocksField;
|
||||
|
||||
const ZERO: Self = Self([0; 4]);
|
||||
const ONE: Self = Self([1, 0, 0, 0]);
|
||||
const TWO: Self = Self([2, 0, 0, 0]);
|
||||
@ -84,10 +80,8 @@ impl Field for Secp256K1Scalar {
|
||||
0xFFFFFFFFFFFFFFFF,
|
||||
]);
|
||||
|
||||
// TODO: fix
|
||||
const CHARACTERISTIC: u64 = 0;
|
||||
|
||||
const TWO_ADICITY: usize = 6;
|
||||
const CHARACTERISTIC_TWO_ADICITY: usize = Self::TWO_ADICITY;
|
||||
|
||||
// Sage: `g = GF(p).multiplicative_generator()`
|
||||
const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self([7, 0, 0, 0]);
|
||||
@ -109,6 +103,9 @@ impl Field for Secp256K1Scalar {
|
||||
0xFFFFFFFF,
|
||||
])
|
||||
}
|
||||
fn characteristic() -> BigUint {
|
||||
Self::order()
|
||||
}
|
||||
|
||||
fn try_inverse(&self) -> Option<Self> {
|
||||
if self.is_zero() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user