From 236a143abfea6248fe101e4ef3151a3a050244af Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Sun, 5 Sep 2021 10:27:11 -0700 Subject: [PATCH] Move some Field members to a Field64 subtrait (#213) * Move some Field members to a Field64 subtrait I.e. move anything specific to 64-bit fields. Also, relatedly, - Tweak a bunch of prover code to require `Field64`, since 64-bit stuff is used in a couple places, like the FRI proof-of-work - Remove `bits()`, which was unused and assumed a 64-bit field - Rename a couple methods to reflect that they're u64 variants There are no functional changes. * Field64 -> PrimeField * Remove `exp_u32`, `kth_root_u32` * PrimeField: PrimeField * Move `to_canonical_biguint` as well * Add back from_noncanonical_u128 --- src/bin/bench_recursion.rs | 4 +- src/field/crandall_field.rs | 78 +++++++++++++------------- src/field/extension_field/quadratic.rs | 34 +++-------- src/field/extension_field/quartic.rs | 36 ++---------- src/field/extension_field/target.rs | 11 ++-- src/field/field_testing.rs | 40 +++++-------- src/field/field_types.rs | 65 +++++++++------------ src/fri/commitment.rs | 15 ++--- src/fri/prover.rs | 12 ++-- src/fri/recursive_verifier.rs | 8 +-- src/fri/verifier.rs | 14 ++--- src/gadgets/arithmetic.rs | 3 +- src/gadgets/arithmetic_extension.rs | 14 +++-- src/gadgets/hash.rs | 3 +- src/gadgets/insert.rs | 3 +- src/gadgets/interpolation.rs | 3 +- src/gadgets/polynomial.rs | 9 +-- src/gadgets/random_access.rs | 3 +- src/gadgets/range_check.rs | 6 +- src/gadgets/select.rs | 3 +- src/gadgets/split_base.rs | 4 +- src/gadgets/split_join.rs | 8 +-- src/gates/arithmetic.rs | 9 ++- src/gates/base_sum.rs | 6 +- src/gates/constant.rs | 4 +- src/gates/exponentiation.rs | 14 +++-- src/gates/gate.rs | 24 ++++---- src/gates/gate_testing.rs | 8 ++- src/gates/gate_tree.rs | 3 +- src/gates/gmimc.rs | 14 +++-- src/gates/insertion.rs | 14 +++-- src/gates/interpolation.rs | 13 +++-- src/gates/noop.rs | 3 +- src/gates/public_input.rs | 3 +- src/gates/random_access.rs | 14 +++-- src/gates/reducing.rs | 3 +- src/gates/switch.rs | 15 +++-- src/hash/hashing.rs | 4 +- src/hash/merkle_proofs.rs | 4 +- src/hash/poseidon.rs | 4 +- src/iop/challenger.rs | 14 ++--- src/iop/witness.rs | 12 ++-- src/plonk/circuit_builder.rs | 5 +- src/plonk/circuit_data.rs | 20 +++---- src/plonk/plonk_common.rs | 8 +-- src/plonk/proof.rs | 3 +- src/plonk/prover.rs | 13 +++-- src/plonk/recursive_verifier.rs | 7 ++- src/plonk/vanishing_poly.rs | 14 ++--- src/plonk/verifier.rs | 4 +- src/polynomial/division.rs | 4 +- src/polynomial/polynomial.rs | 2 +- src/util/partial_products.rs | 3 +- src/util/reducing.rs | 12 ++-- 54 files changed, 317 insertions(+), 339 deletions(-) diff --git a/src/bin/bench_recursion.rs b/src/bin/bench_recursion.rs index 7d1b6c57..8995543b 100644 --- a/src/bin/bench_recursion.rs +++ b/src/bin/bench_recursion.rs @@ -3,7 +3,7 @@ use env_logger::Env; use log::info; use plonky2::field::crandall_field::CrandallField; use plonky2::field::extension_field::Extendable; -use plonky2::field::field_types::Field; +use plonky2::field::field_types::PrimeField; use plonky2::fri::FriConfig; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; @@ -19,7 +19,7 @@ fn main() -> Result<()> { bench_prove::() } -fn bench_prove, const D: usize>() -> Result<()> { +fn bench_prove, const D: usize>() -> Result<()> { let config = CircuitConfig { num_wires: 126, num_routed_wires: 33, diff --git a/src/field/crandall_field.rs b/src/field/crandall_field.rs index 98ac92ca..9868336a 100644 --- a/src/field/crandall_field.rs +++ b/src/field/crandall_field.rs @@ -12,9 +12,7 @@ use serde::{Deserialize, Serialize}; use crate::field::extension_field::quadratic::QuadraticCrandallField; use crate::field::extension_field::quartic::QuarticCrandallField; use crate::field::extension_field::{Extendable, Frobenius}; -use crate::field::field_types::Field; - -const FIELD_ORDER: u64 = 18446744071293632513; +use crate::field::field_types::{Field, PrimeField}; /// EPSILON = 9 * 2**28 - 1 const EPSILON: u64 = 2415919103; @@ -152,16 +150,16 @@ impl Field for CrandallField { const ZERO: Self = Self(0); const ONE: Self = Self(1); const TWO: Self = Self(2); - const NEG_ONE: Self = Self(FIELD_ORDER - 1); + const NEG_ONE: Self = Self(Self::ORDER - 1); - const CHARACTERISTIC: u64 = FIELD_ORDER; + const CHARACTERISTIC: u64 = Self::ORDER; const TWO_ADICITY: usize = 28; const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self(5); const POWER_OF_TWO_GENERATOR: Self = Self(10281950781551402419); fn order() -> BigUint { - BigUint::from(FIELD_ORDER) + BigUint::from(Self::ORDER) } #[inline] @@ -183,7 +181,7 @@ impl Field for CrandallField { // Based on Algorithm 16 of "Efficient Software-Implementation of Finite Fields with // Applications to Cryptography". - let p = FIELD_ORDER; + let p = Self::ORDER; let mut u = self.to_canonical_u64(); let mut v = p; let mut b = 1u64; @@ -240,18 +238,12 @@ impl Field for CrandallField { } #[inline] - fn to_noncanonical_u64(&self) -> u64 { - self.0 + fn from_canonical_u64(n: u64) -> Self { + Self(n) } - #[inline] - fn to_canonical_u64(&self) -> u64 { - let mut c = self.0; - // We only need one condition subtraction, since 2 * ORDER would not fit in a u64. - if c >= FIELD_ORDER { - c -= FIELD_ORDER; - } - c + fn from_canonical_biguint(n: BigUint) -> Self { + Self(n.iter_u64_digits().next().unwrap_or(0)) } #[inline] @@ -259,21 +251,8 @@ impl Field for CrandallField { reduce128(n) } - #[inline] - fn from_canonical_u64(n: u64) -> Self { - Self(n) - } - - fn to_canonical_biguint(&self) -> BigUint { - BigUint::from(self.to_canonical_u64()) - } - - fn from_canonical_biguint(n: BigUint) -> Self { - Self(n.iter_u64_digits().next().unwrap_or(0)) - } - fn rand_from_rng(rng: &mut R) -> Self { - Self::from_canonical_u64(rng.gen_range(0..FIELD_ORDER)) + Self::from_canonical_u64(rng.gen_range(0..Self::ORDER)) } fn cube_root(&self) -> Self { @@ -365,6 +344,29 @@ impl Field for CrandallField { } } +impl PrimeField for CrandallField { + const ORDER: u64 = 18446744071293632513; + + #[inline] + fn to_canonical_u64(&self) -> u64 { + let mut c = self.0; + // We only need one condition subtraction, since 2 * ORDER would not fit in a u64. + if c >= Self::ORDER { + c -= Self::ORDER; + } + c + } + + #[inline] + fn to_noncanonical_u64(&self) -> u64 { + self.0 + } + + fn to_canonical_biguint(&self) -> BigUint { + BigUint::from(self.to_canonical_u64()) + } +} + impl Neg for CrandallField { type Output = Self; @@ -373,7 +375,7 @@ impl Neg for CrandallField { if self.is_zero() { Self::ZERO } else { - Self(FIELD_ORDER - self.to_canonical_u64()) + Self(Self::ORDER - self.to_canonical_u64()) } } } @@ -385,7 +387,7 @@ impl Add for CrandallField { #[allow(clippy::suspicious_arithmetic_impl)] fn add(self, rhs: Self) -> Self { let (sum, over) = self.0.overflowing_add(rhs.to_canonical_u64()); - Self(sum.overflowing_sub((over as u64) * FIELD_ORDER).0) + Self(sum.overflowing_sub((over as u64) * Self::ORDER).0) } } @@ -408,7 +410,7 @@ impl Sub for CrandallField { #[allow(clippy::suspicious_arithmetic_impl)] fn sub(self, rhs: Self) -> Self { let (diff, under) = self.0.overflowing_sub(rhs.to_canonical_u64()); - Self(diff.overflowing_add((under as u64) * FIELD_ORDER).0) + Self(diff.overflowing_add((under as u64) * Self::ORDER).0) } } @@ -464,7 +466,7 @@ impl Extendable<4> for CrandallField { type Extension = QuarticCrandallField; } -/// Faster addition for when we know that lhs.0 + rhs.0 < 2^64 + FIELD_ORDER. If this is the case, +/// Faster addition for when we know that lhs.0 + rhs.0 < 2^64 + Self::ORDER. If this is the case, /// then the .to_canonical_u64() that addition usually performs is unnecessary. Omitting it saves /// three instructions. /// This function is marked unsafe because it may yield incorrect result if the condition is not @@ -472,7 +474,7 @@ impl Extendable<4> for CrandallField { #[inline] unsafe fn add_no_canonicalize(lhs: CrandallField, rhs: CrandallField) -> CrandallField { let (sum, over) = lhs.0.overflowing_add(rhs.0); - CrandallField(sum.overflowing_sub((over as u64) * FIELD_ORDER).0) + CrandallField(sum.overflowing_sub((over as u64) * CrandallField::ORDER).0) } /// Reduces to a 64-bit value. The result might not be in canonical form; it could be in between the @@ -489,8 +491,8 @@ fn reduce128(x: u128) -> CrandallField { let lo_3 = hi_2 * EPSILON; unsafe { - // This is safe to do because lo_2 + lo_3 < 2^64 + FIELD_ORDER. Notice that hi_2 <= - // 2^32 - 1. Then lo_3 = hi_2 * EPSILON <= (2^32 - 1) * EPSILON < FIELD_ORDER. + // This is safe to do because lo_2 + lo_3 < 2^64 + Self::ORDER. Notice that hi_2 <= + // 2^32 - 1. Then lo_3 = hi_2 * EPSILON <= (2^32 - 1) * EPSILON < Self::ORDER. // Use of standard addition here would make multiplication 20% more expensive. add_no_canonicalize(CrandallField(lo_2), CrandallField(lo_3)) } diff --git a/src/field/extension_field/quadratic.rs b/src/field/extension_field/quadratic.rs index 1e2ea6a3..2a1fef70 100644 --- a/src/field/extension_field/quadratic.rs +++ b/src/field/extension_field/quadratic.rs @@ -89,31 +89,10 @@ impl Field for QuadraticCrandallField { )) } - fn to_canonical_u64(&self) -> u64 { - //panic!("Can't convert extension field element to a u64."); - self.0[0].to_canonical_u64() - } - - fn to_noncanonical_u64(&self) -> u64 { - panic!("Can't convert extension field element to a u64."); - } - - fn from_noncanonical_u128(n: u128) -> Self { - >::BaseField::from_noncanonical_u128(n).into() - } - fn from_canonical_u64(n: u64) -> Self { >::BaseField::from_canonical_u64(n).into() } - fn to_canonical_biguint(&self) -> BigUint { - let first = self.0[0].to_canonical_biguint(); - let second = self.0[1].to_canonical_biguint(); - let combined = second * Self::CHARACTERISTIC + first; - - combined - } - fn from_canonical_biguint(n: BigUint) -> Self { let smaller = n.clone() % Self::CHARACTERISTIC; let larger = n.clone() / Self::CHARACTERISTIC; @@ -124,6 +103,10 @@ impl Field for QuadraticCrandallField { ]) } + fn from_noncanonical_u128(n: u128) -> Self { + >::BaseField::from_noncanonical_u128(n).into() + } + fn rand_from_rng(rng: &mut R) -> Self { Self([ >::BaseField::rand_from_rng(rng), @@ -288,7 +271,8 @@ mod tests { type F = QuadraticCrandallField; let x = F::rand(); assert_eq!( - x.exp(18446744071293632512).exp(18446744071293632514), + x.exp_u64(18446744071293632512) + .exp_u64(18446744071293632514), F::ONE ); } @@ -299,13 +283,13 @@ mod tests { // F::order() = 2^29 * 2762315674048163 * 229454332791453 + 1 assert_eq!( F::MULTIPLICATIVE_GROUP_GENERATOR - .exp(2762315674048163) - .exp(229454332791453), + .exp_u64(2762315674048163) + .exp_u64(229454332791453), F::POWER_OF_TWO_GENERATOR ); assert_eq!( F::POWER_OF_TWO_GENERATOR - .exp(1 << (F::TWO_ADICITY - >::BaseField::TWO_ADICITY)), + .exp_u64(1 << (F::TWO_ADICITY - >::BaseField::TWO_ADICITY)), >::BaseField::POWER_OF_TWO_GENERATOR.into() ); } diff --git a/src/field/extension_field/quartic.rs b/src/field/extension_field/quartic.rs index 9a58b5eb..f37cfb92 100644 --- a/src/field/extension_field/quartic.rs +++ b/src/field/extension_field/quartic.rs @@ -122,40 +122,10 @@ impl Field for QuarticCrandallField { )) } - fn to_canonical_u64(&self) -> u64 { - //panic!("Can't convert extension field element to a u64."); - self.0[0].to_canonical_u64() - } - - fn to_noncanonical_u64(&self) -> u64 { - panic!("Can't convert extension field element to a u64."); - } - - fn from_noncanonical_u128(n: u128) -> Self { - >::BaseField::from_noncanonical_u128(n).into() - } - fn from_canonical_u64(n: u64) -> Self { >::BaseField::from_canonical_u64(n).into() } - fn to_canonical_biguint(&self) -> BigUint { - let first = self.0[0].to_canonical_biguint(); - let second = self.0[1].to_canonical_biguint(); - let third = self.0[2].to_canonical_biguint(); - let fourth = self.0[3].to_canonical_biguint(); - - let mut combined = fourth; - combined *= Self::CHARACTERISTIC; - combined += third; - combined *= Self::CHARACTERISTIC; - combined += second; - combined *= Self::CHARACTERISTIC; - combined += first; - - combined - } - fn from_canonical_biguint(n: BigUint) -> Self { let first = &n % Self::CHARACTERISTIC; let mut remaining = &n / Self::CHARACTERISTIC; @@ -173,6 +143,10 @@ impl Field for QuarticCrandallField { ]) } + fn from_noncanonical_u128(n: u128) -> Self { + >::BaseField::from_noncanonical_u128(n).into() + } + fn rand_from_rng(rng: &mut R) -> Self { Self([ >::BaseField::rand_from_rng(rng), @@ -399,7 +373,7 @@ mod tests { ); assert_eq!( F::POWER_OF_TWO_GENERATOR - .exp(1 << (F::TWO_ADICITY - >::BaseField::TWO_ADICITY)), + .exp_u64(1 << (F::TWO_ADICITY - >::BaseField::TWO_ADICITY)), >::BaseField::POWER_OF_TWO_GENERATOR.into() ); } diff --git a/src/field/extension_field/target.rs b/src/field/extension_field/target.rs index 683afe0b..0970d65e 100644 --- a/src/field/extension_field/target.rs +++ b/src/field/extension_field/target.rs @@ -3,7 +3,7 @@ use std::ops::Range; use crate::field::extension_field::algebra::ExtensionAlgebra; use crate::field::extension_field::{Extendable, FieldExtension, OEF}; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; @@ -16,11 +16,14 @@ impl ExtensionTarget { self.0 } - pub fn frobenius>(&self, builder: &mut CircuitBuilder) -> Self { + pub fn frobenius>( + &self, + builder: &mut CircuitBuilder, + ) -> Self { self.repeated_frobenius(1, builder) } - pub fn repeated_frobenius>( + pub fn repeated_frobenius>( &self, count: usize, builder: &mut CircuitBuilder, @@ -71,7 +74,7 @@ impl ExtensionAlgebraTarget { } } -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { pub fn constant_extension(&mut self, c: F::Extension) -> ExtensionTarget { let c_parts = c.to_basefield_array(); let mut parts = [self.zero(); D]; diff --git a/src/field/field_testing.rs b/src/field/field_testing.rs index 51275bf4..658fc65a 100644 --- a/src/field/field_testing.rs +++ b/src/field/field_testing.rs @@ -1,6 +1,6 @@ use num::{bigint::BigUint, Zero}; -use crate::field::field_types::Field; +use crate::field::field_types::PrimeField; use crate::util::ceil_div_usize; /// Generates a series of non-negative integers less than @@ -67,7 +67,7 @@ pub fn run_unaryop_test_cases( op: UnaryOp, expected_op: ExpectedOp, ) where - F: Field, + F: PrimeField, UnaryOp: Fn(F) -> F, ExpectedOp: Fn(BigUint) -> BigUint, { @@ -99,7 +99,7 @@ pub fn run_binaryop_test_cases( op: BinaryOp, expected_op: ExpectedOp, ) where - F: Field, + F: PrimeField, BinaryOp: Fn(F, F) -> F, ExpectedOp: Fn(BigUint, BigUint) -> BigUint, { @@ -192,36 +192,26 @@ macro_rules! test_field_arithmetic { } } - #[test] - fn bits() { - assert_eq!(<$field>::ZERO.bits(), 0); - assert_eq!(<$field>::ONE.bits(), 1); - assert_eq!(<$field>::TWO.bits(), 2); - assert_eq!(<$field>::from_canonical_u64(3).bits(), 2); - assert_eq!(<$field>::from_canonical_u64(4).bits(), 3); - assert_eq!(<$field>::from_canonical_u64(5).bits(), 3); - } - #[test] fn exponentiation() { type F = $field; - assert_eq!(F::ZERO.exp_u32(0), ::ONE); - assert_eq!(F::ONE.exp_u32(0), ::ONE); - assert_eq!(F::TWO.exp_u32(0), ::ONE); + assert_eq!(F::ZERO.exp_u64(0), ::ONE); + assert_eq!(F::ONE.exp_u64(0), ::ONE); + assert_eq!(F::TWO.exp_u64(0), ::ONE); - assert_eq!(F::ZERO.exp_u32(1), ::ZERO); - assert_eq!(F::ONE.exp_u32(1), ::ONE); - assert_eq!(F::TWO.exp_u32(1), ::TWO); + assert_eq!(F::ZERO.exp_u64(1), ::ZERO); + assert_eq!(F::ONE.exp_u64(1), ::ONE); + assert_eq!(F::TWO.exp_u64(1), ::TWO); - assert_eq!(F::ZERO.kth_root_u32(1), ::ZERO); - assert_eq!(F::ONE.kth_root_u32(1), ::ONE); - assert_eq!(F::TWO.kth_root_u32(1), ::TWO); + assert_eq!(F::ZERO.kth_root_u64(1), ::ZERO); + assert_eq!(F::ONE.kth_root_u64(1), ::ONE); + assert_eq!(F::TWO.kth_root_u64(1), ::TWO); for power in 1..10 { - if F::is_monomial_permutation(power) { + if F::is_monomial_permutation_u64(power) { let x = F::rand(); - assert_eq!(x.exp(power).kth_root(power), x); + assert_eq!(x.exp_u64(power).kth_root_u64(power), x); } } } @@ -251,7 +241,7 @@ macro_rules! test_field_arithmetic { let v = ::PrimeField::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(e as u64).inverse(); + let x = F::TWO.exp_u64(e as u64).inverse(); let y = F::inverse_2exp(e); assert_eq!(x, y); } diff --git a/src/field/field_types.rs b/src/field/field_types.rs index 1775ca07..d8d54d15 100644 --- a/src/field/field_types.rs +++ b/src/field/field_types.rs @@ -13,7 +13,7 @@ use serde::Serialize; use crate::field::extension_field::Frobenius; use crate::util::bits_u64; -/// A finite field with prime order less than 2^64. +/// A finite field. pub trait Field: 'static + Copy @@ -38,7 +38,7 @@ pub trait Field: + Serialize + DeserializeOwned { - type PrimeField: Field; + type PrimeField: PrimeField; const ZERO: Self; const ONE: Self; @@ -133,7 +133,7 @@ pub trait Field: // In the general case we compute 1/2 = (p+1)/2 and then exponentiate // by exp to get 1/2^exp. Costs about log_2(exp) operations. let half = Self::from_canonical_u64((p + 1) >> 1); - half.exp(exp as u64) + half.exp_u64(exp as u64) // TODO: Faster to combine several high powers of 1/2 using multiple // applications of the trick above. E.g. if the 2-adicity is v, then @@ -180,15 +180,6 @@ pub trait Field: subgroup.into_iter().map(|x| x * shift).collect() } - // Converting to u64 only makes sense in a prime field, not in - // an extension; probably means these two functions don't belong - // the Field trait... - fn to_canonical_u64(&self) -> u64; - - fn to_noncanonical_u64(&self) -> u64; - - fn from_noncanonical_u128(n: u128) -> Self; - fn from_canonical_u64(n: u64) -> Self; fn from_canonical_u32(n: u32) -> Self { @@ -203,15 +194,12 @@ pub trait Field: Self::from_canonical_u64(b as u64) } - fn to_canonical_biguint(&self) -> BigUint; - fn from_canonical_biguint(n: BigUint) -> Self; - fn rand_from_rng(rng: &mut R) -> Self; + /// Returns `n % Self::CHARACTERISTIC`. + fn from_noncanonical_u128(n: u128) -> Self; - fn bits(&self) -> usize { - bits_u64(self.to_canonical_u64()) - } + fn rand_from_rng(rng: &mut R) -> Self; fn exp_power_of_2(&self, power_log: usize) -> Self { let mut res = *self; @@ -221,7 +209,7 @@ pub trait Field: res } - fn exp(&self, power: u64) -> Self { + fn exp_u64(&self, power: u64) -> Self { let mut current = *self; let mut product = Self::ONE; @@ -234,27 +222,17 @@ pub trait Field: product } - fn exp_u32(&self, power: u32) -> Self { - self.exp(power as u64) - } - fn exp_biguint(&self, power: &BigUint) -> Self { - let digits = power.to_u32_digits(); - let radix = 1u64 << 32; - let mut result = Self::ONE; - for (radix_power, &digit) in digits.iter().enumerate() { - let mut current = self.exp_u32(digit); - for _ in 0..radix_power { - current = current.exp(radix); - } - result *= current; + for &digit in power.to_u64_digits().iter().rev() { + result = result.exp_power_of_2(64); + result *= self.exp_u64(digit); } result } /// Returns whether `x^power` is a permutation of this field. - fn is_monomial_permutation(power: u64) -> bool { + fn is_monomial_permutation_u64(power: u64) -> bool { match power { 0 => false, 1 => true, @@ -262,11 +240,11 @@ pub trait Field: } } - fn kth_root(&self, k: u64) -> Self { + fn kth_root_u64(&self, k: u64) -> Self { let p = Self::order().clone(); let p_minus_1 = &p - 1u32; debug_assert!( - Self::is_monomial_permutation(k), + Self::is_monomial_permutation_u64(k), "Not a permutation of this field" ); @@ -289,12 +267,8 @@ pub trait Field: ); } - fn kth_root_u32(&self, k: u32) -> Self { - self.kth_root(k as u64) - } - fn cube_root(&self) -> Self { - self.kth_root(3) + self.kth_root_u64(3) } fn powers(&self) -> Powers { @@ -347,6 +321,17 @@ pub trait Field: } } +/// A finite field of prime order less than 2^64. +pub trait PrimeField: Field { + const ORDER: u64; + + fn to_canonical_u64(&self) -> u64; + + fn to_noncanonical_u64(&self) -> u64; + + fn to_canonical_biguint(&self) -> BigUint; +} + /// An iterator over the powers of a certain base element `b`: `b^0, b^1, b^2, ...`. #[derive(Clone)] pub struct Powers { diff --git a/src/fri/commitment.rs b/src/fri/commitment.rs index ff84a072..10ced5d9 100644 --- a/src/fri/commitment.rs +++ b/src/fri/commitment.rs @@ -2,7 +2,7 @@ use rayon::prelude::*; use crate::field::extension_field::Extendable; use crate::field::fft::DEFAULT_STRATEGY; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::fri::proof::FriProof; use crate::fri::prover::fri_proof; use crate::hash::merkle_tree::MerkleTree; @@ -20,7 +20,7 @@ use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place, transp pub const SALT_SIZE: usize = 2; /// Represents a batch FRI based commitment to a list of polynomials. -pub struct PolynomialBatchCommitment { +pub struct PolynomialBatchCommitment { pub polynomials: Vec>, pub merkle_tree: MerkleTree, pub degree_log: usize, @@ -28,7 +28,7 @@ pub struct PolynomialBatchCommitment { pub blinding: bool, } -impl PolynomialBatchCommitment { +impl PolynomialBatchCommitment { /// Creates a list polynomial commitment for the polynomials interpolating the values in `values`. pub(crate) fn from_values( values: Vec>, @@ -125,7 +125,7 @@ impl PolynomialBatchCommitment { timing: &mut TimingTree, ) -> (FriProof, OpeningSet) where - F: Extendable, + F: PrimeField + Extendable, { let config = &common_data.config; assert!(D > 1, "Not implemented for D=1."); @@ -133,7 +133,7 @@ impl PolynomialBatchCommitment { let g = F::Extension::primitive_root_of_unity(degree_log); for p in &[zeta, g * zeta] { assert_ne!( - p.exp(1 << degree_log as u64), + p.exp_u64(1 << degree_log as u64), F::Extension::ONE, "Opening point is in the subgroup." ); @@ -273,14 +273,15 @@ mod tests { let degree = 1 << degree_log; let mut point = F::Extension::rand(); - while point.exp(degree as u64).is_one() { + while point.exp_u64(degree as u64).is_one() { point = F::Extension::rand(); } point } - fn check_batch_polynomial_commitment, const D: usize>() -> Result<()> { + fn check_batch_polynomial_commitment, const D: usize>( + ) -> Result<()> { let ks = [10, 2, 10, 8]; let degree_bits = 11; let fri_config = FriConfig { diff --git a/src/fri/prover.rs b/src/fri/prover.rs index 0f4ddb9c..eb397b71 100644 --- a/src/fri/prover.rs +++ b/src/fri/prover.rs @@ -1,7 +1,7 @@ use rayon::prelude::*; use crate::field::extension_field::{flatten, unflatten, Extendable}; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::fri::proof::{FriInitialTreeProof, FriProof, FriQueryRound, FriQueryStep}; use crate::fri::FriConfig; use crate::hash::hash_types::HashOut; @@ -16,7 +16,7 @@ use crate::util::reverse_index_bits_in_place; use crate::util::timing::TimingTree; /// Builds a FRI proof. -pub fn fri_proof, const D: usize>( +pub fn fri_proof, const D: usize>( initial_merkle_trees: &[&MerkleTree], // Coefficients of the polynomial on which the LDT is performed. Only the first `1/rate` coefficients are non-zero. lde_polynomial_coeffs: PolynomialCoeffs, @@ -99,7 +99,7 @@ fn fri_committed_trees, const D: usize>( .map(|chunk| reduce_with_powers(chunk, beta)) .collect::>(), ); - shift = shift.exp_u32(arity as u32); + shift = shift.exp_u64(arity as u64); values = coeffs.coset_fft(shift.into()) } @@ -110,7 +110,7 @@ fn fri_committed_trees, const D: usize>( (trees, coeffs) } -fn fri_proof_of_work(current_hash: HashOut, config: &FriConfig) -> F { +fn fri_proof_of_work(current_hash: HashOut, config: &FriConfig) -> F { (0..=F::NEG_ONE.to_canonical_u64()) .into_par_iter() .find_any(|&i| { @@ -131,7 +131,7 @@ fn fri_proof_of_work(current_hash: HashOut, config: &FriConfig) -> .expect("Proof of work failed. This is highly unlikely!") } -fn fri_prover_query_rounds, const D: usize>( +fn fri_prover_query_rounds, const D: usize>( initial_merkle_trees: &[&MerkleTree], trees: &[MerkleTree], challenger: &mut Challenger, @@ -143,7 +143,7 @@ fn fri_prover_query_rounds, const D: usize>( .collect() } -fn fri_prover_query_round, const D: usize>( +fn fri_prover_query_round, const D: usize>( initial_merkle_trees: &[&MerkleTree], trees: &[MerkleTree], challenger: &mut Challenger, diff --git a/src/fri/recursive_verifier.rs b/src/fri/recursive_verifier.rs index eb6cdcaa..ed75d142 100644 --- a/src/fri/recursive_verifier.rs +++ b/src/fri/recursive_verifier.rs @@ -1,6 +1,6 @@ use crate::field::extension_field::target::{flatten_target, ExtensionTarget}; use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::fri::proof::{FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget}; use crate::fri::FriConfig; use crate::hash::hash_types::MerkleCapTarget; @@ -14,7 +14,7 @@ use crate::util::reducing::ReducingFactorTarget; use crate::util::{log2_strict, reverse_index_bits_in_place}; use crate::with_context; -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { /// Computes P'(x^arity) from {P(x*g^i)}_(i=0..arity), where g is a `arity`-th root of unity /// and P' is the FRI reduced polynomial. fn compute_evaluation( @@ -29,7 +29,7 @@ impl, const D: usize> CircuitBuilder { debug_assert_eq!(evals.len(), arity); let g = F::primitive_root_of_unity(arity_bits); - let g_inv = g.exp((arity as u64) - 1); + let g_inv = g.exp_u64((arity as u64) - 1); let g_inv_t = self.constant(g_inv); // The evaluation vector needs to be reordered first. @@ -394,7 +394,7 @@ struct PrecomputedReducedEvalsTarget { } impl PrecomputedReducedEvalsTarget { - fn from_os_and_alpha>( + fn from_os_and_alpha>( os: &OpeningSetTarget, alpha: ExtensionTarget, degree_log: usize, diff --git a/src/fri/verifier.rs b/src/fri/verifier.rs index d5bb7990..4479a65b 100644 --- a/src/fri/verifier.rs +++ b/src/fri/verifier.rs @@ -1,7 +1,7 @@ use anyhow::{ensure, Result}; use crate::field::extension_field::{flatten, Extendable, FieldExtension}; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::field::interpolation::{barycentric_weights, interpolate, interpolate2}; use crate::fri::proof::{FriInitialTreeProof, FriProof, FriQueryRound}; use crate::fri::FriConfig; @@ -33,7 +33,7 @@ fn compute_evaluation, const D: usize>( let mut evals = evals.to_vec(); reverse_index_bits_in_place(&mut evals); let rev_x_index_within_coset = reverse_bits(x_index_within_coset, arity_bits); - let coset_start = x * g.exp((arity - rev_x_index_within_coset) as u64); + let coset_start = x * g.exp_u64((arity - rev_x_index_within_coset) as u64); // The answer is gotten by interpolating {(x*g^i, P(x*g^i))} and evaluating at beta. let points = g .powers() @@ -44,7 +44,7 @@ fn compute_evaluation, const D: usize>( interpolate(&points, beta, &barycentric_weights) } -fn fri_verify_proof_of_work, const D: usize>( +fn fri_verify_proof_of_work, const D: usize>( proof: &FriProof, challenger: &mut Challenger, config: &FriConfig, @@ -68,7 +68,7 @@ fn fri_verify_proof_of_work, const D: usize>( Ok(()) } -pub fn verify_fri_proof, const D: usize>( +pub fn verify_fri_proof, const D: usize>( // Openings of the PLONK polynomials. os: &OpeningSet, // Point at which the PLONK polynomials are opened. @@ -179,7 +179,7 @@ impl, const D: usize> PrecomputedReducedEvals { } } -fn fri_combine_initial, const D: usize>( +fn fri_combine_initial, const D: usize>( proof: &FriInitialTreeProof, alpha: F::Extension, zeta: F::Extension, @@ -244,7 +244,7 @@ fn fri_combine_initial, const D: usize>( sum } -fn fri_verifier_query_round, const D: usize>( +fn fri_verifier_query_round, const D: usize>( zeta: F::Extension, alpha: F::Extension, precomputed_reduced_evals: PrecomputedReducedEvals, @@ -267,7 +267,7 @@ fn fri_verifier_query_round, const D: usize>( // `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain. let log_n = log2_strict(n); let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR - * F::primitive_root_of_unity(log_n).exp(reverse_bits(x_index, log_n) as u64); + * F::primitive_root_of_unity(log_n).exp_u64(reverse_bits(x_index, log_n) as u64); // old_eval is the last derived evaluation; it will be checked for consistency with its // committed "parent" value in the next iteration. diff --git a/src/gadgets/arithmetic.rs b/src/gadgets/arithmetic.rs index 960f139f..1ac6c6f2 100644 --- a/src/gadgets/arithmetic.rs +++ b/src/gadgets/arithmetic.rs @@ -1,11 +1,12 @@ use std::borrow::Borrow; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::gates::exponentiation::ExponentiationGate; use crate::iop::target::{BoolTarget, Target}; use crate::plonk::circuit_builder::CircuitBuilder; -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { /// Computes `-x`. pub fn neg(&mut self, x: Target) -> Target { let neg_one = self.neg_one(); diff --git a/src/gadgets/arithmetic_extension.rs b/src/gadgets/arithmetic_extension.rs index 9f5d7141..9cf24c1d 100644 --- a/src/gadgets/arithmetic_extension.rs +++ b/src/gadgets/arithmetic_extension.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use crate::field::extension_field::target::{ExtensionAlgebraTarget, ExtensionTarget}; use crate::field::extension_field::FieldExtension; use crate::field::extension_field::{Extendable, OEF}; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::arithmetic::{ArithmeticExtensionGate, NUM_ARITHMETIC_OPS}; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::Target; @@ -11,7 +11,7 @@ use crate::iop::witness::{PartitionWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::util::bits_u64; -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { /// Finds the last available arithmetic gate with the given constants or add one if there aren't any. /// Returns `(g,i)` such that there is an arithmetic gate with the given constants at index /// `g` and the gate's `i`-th operation is available. @@ -440,7 +440,9 @@ struct QuotientGeneratorExtension { quotient: ExtensionTarget, } -impl, const D: usize> SimpleGenerator for QuotientGeneratorExtension { +impl, const D: usize> SimpleGenerator + for QuotientGeneratorExtension +{ fn dependencies(&self) -> Vec { let mut deps = self.numerator.to_target_array().to_vec(); deps.extend(&self.denominator.to_target_array()); @@ -463,7 +465,7 @@ pub struct PowersTarget { } impl PowersTarget { - pub fn next>( + pub fn next>( &mut self, builder: &mut CircuitBuilder, ) -> ExtensionTarget { @@ -472,7 +474,7 @@ impl PowersTarget { result } - pub fn repeated_frobenius>( + pub fn repeated_frobenius>( self, k: usize, builder: &mut CircuitBuilder, @@ -485,7 +487,7 @@ impl PowersTarget { } } -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { pub fn powers(&mut self, base: ExtensionTarget) -> PowersTarget { PowersTarget { base, diff --git a/src/gadgets/hash.rs b/src/gadgets/hash.rs index 8bab0b2f..a0502981 100644 --- a/src/gadgets/hash.rs +++ b/src/gadgets/hash.rs @@ -1,6 +1,7 @@ use std::convert::TryInto; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::gates::gmimc::GMiMCGate; use crate::hash::hashing::GMIMC_ROUNDS; use crate::iop::target::Target; @@ -8,7 +9,7 @@ use crate::iop::wire::Wire; use crate::plonk::circuit_builder::CircuitBuilder; // TODO: Move to be next to native `permute`? -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { pub fn permute(&mut self, inputs: [Target; 12]) -> [Target; 12] { let zero = self.zero(); let gate_type = GMiMCGate::::new_automatic_constants(); diff --git a/src/gadgets/insert.rs b/src/gadgets/insert.rs index eb2386c7..9220d822 100644 --- a/src/gadgets/insert.rs +++ b/src/gadgets/insert.rs @@ -1,10 +1,11 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::gates::insertion::InsertionGate; use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { /// Inserts a `Target` in a vector at a non-deterministic index. /// Note: `index` is not range-checked. pub fn insert( diff --git a/src/gadgets/interpolation.rs b/src/gadgets/interpolation.rs index 3ee0afe6..899dbf64 100644 --- a/src/gadgets/interpolation.rs +++ b/src/gadgets/interpolation.rs @@ -1,10 +1,11 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::gates::interpolation::InterpolationGate; use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { /// Interpolate a list of point/evaluation pairs at a given point. /// Returns the evaluation of the interpolated polynomial at `evaluation_point`. pub fn interpolate( diff --git a/src/gadgets/polynomial.rs b/src/gadgets/polynomial.rs index 3d371c53..fb3fe96a 100644 --- a/src/gadgets/polynomial.rs +++ b/src/gadgets/polynomial.rs @@ -1,5 +1,6 @@ use crate::field::extension_field::target::{ExtensionAlgebraTarget, ExtensionTarget}; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; use crate::util::reducing::ReducingFactorTarget; @@ -11,7 +12,7 @@ impl PolynomialCoeffsExtTarget { self.0.len() } - pub fn eval_scalar>( + pub fn eval_scalar>( &self, builder: &mut CircuitBuilder, point: Target, @@ -21,7 +22,7 @@ impl PolynomialCoeffsExtTarget { point.reduce(&self.0, builder) } - pub fn eval>( + pub fn eval>( &self, builder: &mut CircuitBuilder, point: ExtensionTarget, @@ -40,7 +41,7 @@ impl PolynomialCoeffsExtAlgebraTarget { point: ExtensionTarget, ) -> ExtensionAlgebraTarget where - F: Extendable, + F: PrimeField + Extendable, { let mut acc = builder.zero_ext_algebra(); for &c in self.0.iter().rev() { @@ -55,7 +56,7 @@ impl PolynomialCoeffsExtAlgebraTarget { point: ExtensionAlgebraTarget, ) -> ExtensionAlgebraTarget where - F: Extendable, + F: PrimeField + Extendable, { let mut acc = builder.zero_ext_algebra(); for &c in self.0.iter().rev() { diff --git a/src/gadgets/random_access.rs b/src/gadgets/random_access.rs index 8afec2af..6e0a290c 100644 --- a/src/gadgets/random_access.rs +++ b/src/gadgets/random_access.rs @@ -1,10 +1,11 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::gates::random_access::RandomAccessGate; use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { /// Checks that a `Target` matches a vector at a non-deterministic index. /// Note: `index` is not range-checked. pub fn random_access( diff --git a/src/gadgets/range_check.rs b/src/gadgets/range_check.rs index 4f3b7d0d..e669e2da 100644 --- a/src/gadgets/range_check.rs +++ b/src/gadgets/range_check.rs @@ -1,12 +1,12 @@ use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::PrimeField; use crate::gates::base_sum::BaseSumGate; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::{BoolTarget, Target}; use crate::iop::witness::{PartitionWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { /// Checks that `x < 2^n_log` using a `BaseSumGate`. pub fn range_check(&mut self, x: Target, n_log: usize) { let gate = self.add_gate(BaseSumGate::<2>::new(n_log), vec![]); @@ -51,7 +51,7 @@ struct LowHighGenerator { high: Target, } -impl SimpleGenerator for LowHighGenerator { +impl SimpleGenerator for LowHighGenerator { fn dependencies(&self) -> Vec { vec![self.integer] } diff --git a/src/gadgets/select.rs b/src/gadgets/select.rs index c5edbe28..e841d1d0 100644 --- a/src/gadgets/select.rs +++ b/src/gadgets/select.rs @@ -1,9 +1,10 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::iop::target::{BoolTarget, Target}; use crate::plonk::circuit_builder::CircuitBuilder; -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { /// Selects `x` or `y` based on `b`, i.e., this returns `if b { x } else { y }`. pub fn select_ext( &mut self, diff --git a/src/gadgets/split_base.rs b/src/gadgets/split_base.rs index 914269d5..5afbb882 100644 --- a/src/gadgets/split_base.rs +++ b/src/gadgets/split_base.rs @@ -1,14 +1,14 @@ use std::borrow::Borrow; use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::base_sum::BaseSumGate; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::{BoolTarget, Target}; use crate::iop::witness::{PartitionWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { /// Split the given element into a list of targets, where each one represents a /// base-B limb of the element, with little-endian ordering. pub fn split_le_base(&mut self, x: Target, num_limbs: usize) -> Vec { diff --git a/src/gadgets/split_join.rs b/src/gadgets/split_join.rs index 4b6527ca..3b4c3b6e 100644 --- a/src/gadgets/split_join.rs +++ b/src/gadgets/split_join.rs @@ -1,5 +1,5 @@ use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::PrimeField; use crate::gates::base_sum::BaseSumGate; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::{BoolTarget, Target}; @@ -7,7 +7,7 @@ use crate::iop::witness::{PartitionWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::util::ceil_div_usize; -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { /// Split the given integer into a list of wires, where each one represents a /// bit of the integer, with little-endian ordering. /// Verifies that the decomposition is correct by using `k` `BaseSum<2>` gates @@ -63,7 +63,7 @@ struct SplitGenerator { bits: Vec, } -impl SimpleGenerator for SplitGenerator { +impl SimpleGenerator for SplitGenerator { fn dependencies(&self) -> Vec { vec![self.integer] } @@ -91,7 +91,7 @@ struct WireSplitGenerator { num_limbs: usize, } -impl SimpleGenerator for WireSplitGenerator { +impl SimpleGenerator for WireSplitGenerator { fn dependencies(&self) -> Vec { vec![self.integer] } diff --git a/src/gates/arithmetic.rs b/src/gates/arithmetic.rs index 3c9dcb18..da82961f 100644 --- a/src/gates/arithmetic.rs +++ b/src/gates/arithmetic.rs @@ -3,6 +3,7 @@ use std::ops::Range; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; use crate::field::extension_field::FieldExtension; +use crate::field::field_types::PrimeField; use crate::gates::gate::Gate; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; @@ -32,7 +33,7 @@ impl ArithmeticExtensionGate { } } -impl, const D: usize> Gate for ArithmeticExtensionGate { +impl, const D: usize> Gate for ArithmeticExtensionGate { fn id(&self) -> String { format!("{:?}", self) } @@ -139,14 +140,16 @@ impl, const D: usize> Gate for ArithmeticExtensionGate } #[derive(Clone, Debug)] -struct ArithmeticExtensionGenerator, const D: usize> { +struct ArithmeticExtensionGenerator, const D: usize> { gate_index: usize, const_0: F, const_1: F, i: usize, } -impl, const D: usize> SimpleGenerator for ArithmeticExtensionGenerator { +impl, const D: usize> SimpleGenerator + for ArithmeticExtensionGenerator +{ fn dependencies(&self) -> Vec { ArithmeticExtensionGate::::wires_ith_multiplicand_0(self.i) .chain(ArithmeticExtensionGate::::wires_ith_multiplicand_1( diff --git a/src/gates/base_sum.rs b/src/gates/base_sum.rs index 341d0fc1..ef7dbbda 100644 --- a/src/gates/base_sum.rs +++ b/src/gates/base_sum.rs @@ -2,7 +2,7 @@ use std::ops::Range; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::gate::Gate; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; @@ -31,7 +31,7 @@ impl BaseSumGate { } } -impl, const D: usize, const B: usize> Gate for BaseSumGate { +impl, const D: usize, const B: usize> Gate for BaseSumGate { fn id(&self) -> String { format!("{:?} + Base: {}", self, B) } @@ -134,7 +134,7 @@ pub struct BaseSplitGenerator { num_limbs: usize, } -impl SimpleGenerator for BaseSplitGenerator { +impl SimpleGenerator for BaseSplitGenerator { fn dependencies(&self) -> Vec { vec![Target::wire(self.gate_index, BaseSumGate::::WIRE_SUM)] } diff --git a/src/gates/constant.rs b/src/gates/constant.rs index 894016d6..3bf34536 100644 --- a/src/gates/constant.rs +++ b/src/gates/constant.rs @@ -1,6 +1,6 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::gate::Gate; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; @@ -18,7 +18,7 @@ impl ConstantGate { pub const WIRE_OUTPUT: usize = 0; } -impl, const D: usize> Gate for ConstantGate { +impl, const D: usize> Gate for ConstantGate { fn id(&self) -> String { "ConstantGate".into() } diff --git a/src/gates/exponentiation.rs b/src/gates/exponentiation.rs index d57c9001..eeeff2c5 100644 --- a/src/gates/exponentiation.rs +++ b/src/gates/exponentiation.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::gate::Gate; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; @@ -14,12 +14,12 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; /// A gate for raising a value to a power. #[derive(Clone, Debug)] -pub(crate) struct ExponentiationGate, const D: usize> { +pub(crate) struct ExponentiationGate, const D: usize> { pub num_power_bits: usize, pub _phantom: PhantomData, } -impl, const D: usize> ExponentiationGate { +impl, const D: usize> ExponentiationGate { pub fn new(config: CircuitConfig) -> Self { let num_power_bits = Self::max_power_bits(config.num_wires, config.num_routed_wires); Self { @@ -55,7 +55,7 @@ impl, const D: usize> ExponentiationGate { } } -impl, const D: usize> Gate for ExponentiationGate { +impl, const D: usize> Gate for ExponentiationGate { fn id(&self) -> String { format!("{:?}", self, D) } @@ -201,12 +201,14 @@ impl, const D: usize> Gate for ExponentiationGate { } #[derive(Debug)] -struct ExponentiationGenerator, const D: usize> { +struct ExponentiationGenerator, const D: usize> { gate_index: usize, gate: ExponentiationGate, } -impl, const D: usize> SimpleGenerator for ExponentiationGenerator { +impl, const D: usize> SimpleGenerator + for ExponentiationGenerator +{ fn dependencies(&self) -> Vec { let local_target = |input| Target::wire(self.gate_index, input); diff --git a/src/gates/gate.rs b/src/gates/gate.rs index 2ac38d60..0b96b791 100644 --- a/src/gates/gate.rs +++ b/src/gates/gate.rs @@ -4,14 +4,14 @@ use std::sync::Arc; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::{Extendable, FieldExtension}; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::gate_tree::Tree; use crate::iop::generator::WitnessGenerator; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; /// A custom gate. -pub trait Gate, const D: usize>: 'static + Send + Sync { +pub trait Gate, const D: usize>: 'static + Send + Sync { fn id(&self) -> String; fn eval_unfiltered(&self, vars: EvaluationVars) -> Vec; @@ -108,48 +108,48 @@ pub trait Gate, const D: usize>: 'static + Send + Sync { /// A wrapper around an `Rc` which implements `PartialEq`, `Eq` and `Hash` based on gate IDs. #[derive(Clone)] -pub struct GateRef, const D: usize>(pub(crate) Arc>); +pub struct GateRef, const D: usize>(pub(crate) Arc>); -impl, const D: usize> GateRef { +impl, const D: usize> GateRef { pub fn new>(gate: G) -> GateRef { GateRef(Arc::new(gate)) } } -impl, const D: usize> PartialEq for GateRef { +impl, const D: usize> PartialEq for GateRef { fn eq(&self, other: &Self) -> bool { self.0.id() == other.0.id() } } -impl, const D: usize> Hash for GateRef { +impl, const D: usize> Hash for GateRef { fn hash(&self, state: &mut H) { self.0.id().hash(state) } } -impl, const D: usize> Eq for GateRef {} +impl, const D: usize> Eq for GateRef {} -impl, const D: usize> Debug for GateRef { +impl, const D: usize> Debug for GateRef { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { write!(f, "{}", self.0.id()) } } /// A gate along with any constants used to configure it. -pub struct GateInstance, const D: usize> { +pub struct GateInstance, const D: usize> { pub gate_ref: GateRef, pub constants: Vec, } /// Map each gate to a boolean prefix used to construct the gate's selector polynomial. #[derive(Debug, Clone)] -pub struct PrefixedGate, const D: usize> { +pub struct PrefixedGate, const D: usize> { pub gate: GateRef, pub prefix: Vec, } -impl, const D: usize> PrefixedGate { +impl, const D: usize> PrefixedGate { pub fn from_tree(tree: Tree>) -> Vec { tree.traversal() .into_iter() @@ -174,7 +174,7 @@ fn compute_filter(prefix: &[bool], constants: &[K]) -> K { .product() } -fn compute_filter_recursively, const D: usize>( +fn compute_filter_recursively, const D: usize>( builder: &mut CircuitBuilder, prefix: &[bool], constants: &[ExtensionTarget], diff --git a/src/gates/gate_testing.rs b/src/gates/gate_testing.rs index b45cb745..1150464b 100644 --- a/src/gates/gate_testing.rs +++ b/src/gates/gate_testing.rs @@ -1,7 +1,7 @@ use anyhow::{ensure, Result}; use crate::field::extension_field::{Extendable, FieldExtension}; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::gate::Gate; use crate::hash::hash_types::HashOut; use crate::iop::witness::{PartialWitness, Witness}; @@ -17,7 +17,9 @@ const WITNESS_DEGREE: usize = WITNESS_SIZE - 1; /// Tests that the constraints imposed by the given gate are low-degree by applying them to random /// low-degree witness polynomials. -pub(crate) fn test_low_degree, G: Gate, const D: usize>(gate: G) { +pub(crate) fn test_low_degree, G: Gate, const D: usize>( + gate: G, +) { let rate_bits = log2_ceil(gate.degree() + 1); let wire_ldes = random_low_degree_matrix::(gate.num_wires(), rate_bits); @@ -82,7 +84,7 @@ fn random_low_degree_values(rate_bits: usize) -> Vec { .values } -pub(crate) fn test_eval_fns, G: Gate, const D: usize>( +pub(crate) fn test_eval_fns, G: Gate, const D: usize>( gate: G, ) -> Result<()> { // Test that `eval_unfiltered` and `eval_unfiltered_base` are coherent. diff --git a/src/gates/gate_tree.rs b/src/gates/gate_tree.rs index 1fbc1497..84949e39 100644 --- a/src/gates/gate_tree.rs +++ b/src/gates/gate_tree.rs @@ -1,6 +1,7 @@ use log::info; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::gates::gate::GateRef; /// A binary tree where leaves hold some type `T` and other nodes are empty. @@ -50,7 +51,7 @@ impl Tree { } } -impl, const D: usize> Tree> { +impl, const D: usize> Tree> { /// The binary gate tree influences the degree `D` of the constraint polynomial and the number `C` /// of constant wires in the circuit. We want to construct a tree minimizing both values. To do so /// we iterate over possible values of `(D, C)` and try to construct a tree with these values. diff --git a/src/gates/gmimc.rs b/src/gates/gmimc.rs index 682bd1fa..43113c44 100644 --- a/src/gates/gmimc.rs +++ b/src/gates/gmimc.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::gate::Gate; use crate::hash::gmimc::gmimc_automatic_constants; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; @@ -23,11 +23,11 @@ const W: usize = 12; /// sibling digests. It also has an accumulator that computes the weighted sum of these flags, for /// computing the index of the leaf based on these swap bits. #[derive(Debug)] -pub struct GMiMCGate, const D: usize, const R: usize> { +pub struct GMiMCGate, const D: usize, const R: usize> { constants: Arc<[F; R]>, } -impl, const D: usize, const R: usize> GMiMCGate { +impl, const D: usize, const R: usize> GMiMCGate { pub fn new(constants: Arc<[F; R]>) -> Self { Self { constants } } @@ -62,7 +62,9 @@ impl, const D: usize, const R: usize> GMiMCGate { } } -impl, const D: usize, const R: usize> Gate for GMiMCGate { +impl, const D: usize, const R: usize> Gate + for GMiMCGate +{ fn id(&self) -> String { format!(" {:?}", R, self) } @@ -238,12 +240,12 @@ impl, const D: usize, const R: usize> Gate for GMiMCGate< } #[derive(Debug)] -struct GMiMCGenerator, const D: usize, const R: usize> { +struct GMiMCGenerator, const D: usize, const R: usize> { gate_index: usize, constants: Arc<[F; R]>, } -impl, const D: usize, const R: usize> SimpleGenerator +impl, const D: usize, const R: usize> SimpleGenerator for GMiMCGenerator { fn dependencies(&self) -> Vec { diff --git a/src/gates/insertion.rs b/src/gates/insertion.rs index 4c1e6fdf..383ff69c 100644 --- a/src/gates/insertion.rs +++ b/src/gates/insertion.rs @@ -4,7 +4,7 @@ use std::ops::Range; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::{Extendable, FieldExtension}; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::gate::Gate; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; @@ -15,12 +15,12 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; /// A gate for inserting a value into a list at a non-deterministic location. #[derive(Clone, Debug)] -pub(crate) struct InsertionGate, const D: usize> { +pub(crate) struct InsertionGate, const D: usize> { pub vec_size: usize, _phantom: PhantomData, } -impl, const D: usize> InsertionGate { +impl, const D: usize> InsertionGate { pub fn new(vec_size: usize) -> Self { Self { vec_size, @@ -70,7 +70,7 @@ impl, const D: usize> InsertionGate { } } -impl, const D: usize> Gate for InsertionGate { +impl, const D: usize> Gate for InsertionGate { fn id(&self) -> String { format!("{:?}", self, D) } @@ -241,12 +241,14 @@ impl, const D: usize> Gate for InsertionGate { } #[derive(Debug)] -struct InsertionGenerator, const D: usize> { +struct InsertionGenerator, const D: usize> { gate_index: usize, gate: InsertionGate, } -impl, const D: usize> SimpleGenerator for InsertionGenerator { +impl, const D: usize> SimpleGenerator + for InsertionGenerator +{ fn dependencies(&self) -> Vec { let local_target = |input| Target::wire(self.gate_index, input); diff --git a/src/gates/interpolation.rs b/src/gates/interpolation.rs index 56924742..52bacdac 100644 --- a/src/gates/interpolation.rs +++ b/src/gates/interpolation.rs @@ -5,6 +5,7 @@ use std::ops::Range; use crate::field::extension_field::algebra::PolynomialCoeffsAlgebra; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::{Extendable, FieldExtension}; +use crate::field::field_types::PrimeField; use crate::field::interpolation::interpolant; use crate::gadgets::polynomial::PolynomialCoeffsExtAlgebraTarget; use crate::gates::gate::Gate; @@ -22,12 +23,12 @@ use crate::polynomial::polynomial::PolynomialCoeffs; /// to evaluate the interpolant at. It computes the interpolant and outputs its evaluation at the /// given point. #[derive(Clone, Debug)] -pub(crate) struct InterpolationGate, const D: usize> { +pub(crate) struct InterpolationGate, const D: usize> { pub num_points: usize, _phantom: PhantomData, } -impl, const D: usize> InterpolationGate { +impl, const D: usize> InterpolationGate { pub fn new(num_points: usize) -> Self { Self { num_points, @@ -93,7 +94,7 @@ impl, const D: usize> InterpolationGate { } } -impl, const D: usize> Gate for InterpolationGate { +impl, const D: usize> Gate for InterpolationGate { fn id(&self) -> String { format!("{:?}", self, D) } @@ -214,13 +215,15 @@ impl, const D: usize> Gate for InterpolationGate { } #[derive(Debug)] -struct InterpolationGenerator, const D: usize> { +struct InterpolationGenerator, const D: usize> { gate_index: usize, gate: InterpolationGate, _phantom: PhantomData, } -impl, const D: usize> SimpleGenerator for InterpolationGenerator { +impl, const D: usize> SimpleGenerator + for InterpolationGenerator +{ fn dependencies(&self) -> Vec { let local_target = |input| { Target::Wire(Wire { diff --git a/src/gates/noop.rs b/src/gates/noop.rs index 69c5c1f9..d23360bb 100644 --- a/src/gates/noop.rs +++ b/src/gates/noop.rs @@ -1,5 +1,6 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::gates::gate::Gate; use crate::iop::generator::WitnessGenerator; use crate::plonk::circuit_builder::CircuitBuilder; @@ -8,7 +9,7 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; /// A gate which does nothing. pub struct NoopGate; -impl, const D: usize> Gate for NoopGate { +impl, const D: usize> Gate for NoopGate { fn id(&self) -> String { "NoopGate".into() } diff --git a/src/gates/public_input.rs b/src/gates/public_input.rs index a3f05738..c298511f 100644 --- a/src/gates/public_input.rs +++ b/src/gates/public_input.rs @@ -2,6 +2,7 @@ use std::ops::Range; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::gates::gate::Gate; use crate::iop::generator::WitnessGenerator; use crate::plonk::circuit_builder::CircuitBuilder; @@ -16,7 +17,7 @@ impl PublicInputGate { } } -impl, const D: usize> Gate for PublicInputGate { +impl, const D: usize> Gate for PublicInputGate { fn id(&self) -> String { "PublicInputGate".into() } diff --git a/src/gates/random_access.rs b/src/gates/random_access.rs index 3bba5ad2..f463e487 100644 --- a/src/gates/random_access.rs +++ b/src/gates/random_access.rs @@ -3,7 +3,7 @@ use std::ops::Range; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::{Extendable, FieldExtension}; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::gate::Gate; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; @@ -14,12 +14,12 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; /// A gate for checking that a particular element of a list matches a given value. #[derive(Clone, Debug)] -pub(crate) struct RandomAccessGate, const D: usize> { +pub(crate) struct RandomAccessGate, const D: usize> { pub vec_size: usize, _phantom: PhantomData, } -impl, const D: usize> RandomAccessGate { +impl, const D: usize> RandomAccessGate { pub fn new(vec_size: usize) -> Self { Self { vec_size, @@ -61,7 +61,7 @@ impl, const D: usize> RandomAccessGate { } } -impl, const D: usize> Gate for RandomAccessGate { +impl, const D: usize> Gate for RandomAccessGate { fn id(&self) -> String { format!("{:?}", self, D) } @@ -188,12 +188,14 @@ impl, const D: usize> Gate for RandomAccessGate { } #[derive(Debug)] -struct RandomAccessGenerator, const D: usize> { +struct RandomAccessGenerator, const D: usize> { gate_index: usize, gate: RandomAccessGate, } -impl, const D: usize> SimpleGenerator for RandomAccessGenerator { +impl, const D: usize> SimpleGenerator + for RandomAccessGenerator +{ fn dependencies(&self) -> Vec { let local_target = |input| Target::wire(self.gate_index, input); diff --git a/src/gates/reducing.rs b/src/gates/reducing.rs index ee3232b2..70f290c9 100644 --- a/src/gates/reducing.rs +++ b/src/gates/reducing.rs @@ -3,6 +3,7 @@ use std::ops::Range; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; use crate::field::extension_field::FieldExtension; +use crate::field::field_types::PrimeField; use crate::gates::gate::Gate; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; @@ -50,7 +51,7 @@ impl ReducingGate { } } -impl, const D: usize> Gate for ReducingGate { +impl, const D: usize> Gate for ReducingGate { fn id(&self) -> String { format!("{:?}", self) } diff --git a/src/gates/switch.rs b/src/gates/switch.rs index 6ef29341..939c11e0 100644 --- a/src/gates/switch.rs +++ b/src/gates/switch.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::gate::Gate; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; @@ -14,12 +14,15 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; /// A gate for conditionally swapping input values based on a boolean. #[derive(Clone, Debug)] -pub(crate) struct SwitchGate, const D: usize, const CHUNK_SIZE: usize> { +pub(crate) struct SwitchGate, const D: usize, const CHUNK_SIZE: usize> +{ num_copies: usize, _phantom: PhantomData, } -impl, const D: usize, const CHUNK_SIZE: usize> SwitchGate { +impl, const D: usize, const CHUNK_SIZE: usize> + SwitchGate +{ pub fn new(config: CircuitConfig) -> Self { let num_copies = Self::max_num_copies(config.num_routed_wires); Self { @@ -62,7 +65,7 @@ impl, const D: usize, const CHUNK_SIZE: usize> SwitchGate, const D: usize, const CHUNK_SIZE: usize> Gate +impl, const D: usize, const CHUNK_SIZE: usize> Gate for SwitchGate { fn id(&self) -> String { @@ -187,12 +190,12 @@ impl, const D: usize, const CHUNK_SIZE: usize> Gate } #[derive(Debug)] -struct SwitchGenerator, const D: usize, const CHUNK_SIZE: usize> { +struct SwitchGenerator, const D: usize, const CHUNK_SIZE: usize> { gate_index: usize, gate: SwitchGate, } -impl, const D: usize, const CHUNK_SIZE: usize> SimpleGenerator +impl, const D: usize, const CHUNK_SIZE: usize> SimpleGenerator for SwitchGenerator { fn dependencies(&self) -> Vec { diff --git a/src/hash/hashing.rs b/src/hash/hashing.rs index 4c304a5d..ad3d068b 100644 --- a/src/hash/hashing.rs +++ b/src/hash/hashing.rs @@ -1,7 +1,7 @@ //! Concrete instantiation of a hash function. use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::hash::gmimc::gmimc_permute_array; use crate::hash::hash_types::{HashOut, HashOutTarget}; use crate::iop::target::Target; @@ -127,7 +127,7 @@ pub fn hash_or_noop(inputs: Vec) -> HashOut { } } -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { pub fn hash_or_noop(&mut self, inputs: Vec) -> HashOutTarget { let zero = self.zero(); if inputs.len() <= 4 { diff --git a/src/hash/merkle_proofs.rs b/src/hash/merkle_proofs.rs index 82f15db0..1ccf3547 100644 --- a/src/hash/merkle_proofs.rs +++ b/src/hash/merkle_proofs.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::gmimc::GMiMCGate; use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget}; use crate::hash::hashing::{compress, hash_or_noop, GMIMC_ROUNDS}; @@ -54,7 +54,7 @@ pub(crate) fn verify_merkle_proof( Ok(()) } -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { /// Verifies that the given leaf data is present at the given index in the Merkle tree with the /// given cap. The index is given by it's little-endian bits. /// Note: Works only for D=4. diff --git a/src/hash/poseidon.rs b/src/hash/poseidon.rs index 6d96d355..daf2dfe9 100644 --- a/src/hash/poseidon.rs +++ b/src/hash/poseidon.rs @@ -4,7 +4,7 @@ use unroll::unroll_for_loops; use crate::field::crandall_field::CrandallField; -use crate::field::field_types::Field; +use crate::field::field_types::PrimeField; // The number of full rounds and partial rounds is given by the // calc_round_numbers.py script. They happen to be the same for both @@ -116,7 +116,7 @@ const ALL_ROUND_CONSTANTS: [u64; MAX_WIDTH * N_ROUNDS] = [ 0x4543d9df72c4831d, 0xf172d73e69f20739, 0xdfd1c4ff1eb3d868, 0xbc8dfb62d26376f7, ]; -pub trait PoseidonInterface: Field +pub trait PoseidonInterface: PrimeField where // magic to get const generic expressions to work [(); WIDTH - 1]: , diff --git a/src/iop/challenger.rs b/src/iop/challenger.rs index 3a90f72b..8b270d66 100644 --- a/src/iop/challenger.rs +++ b/src/iop/challenger.rs @@ -2,7 +2,7 @@ use std::convert::TryInto; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::{Extendable, FieldExtension}; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget}; use crate::hash::hashing::{permute, SPONGE_RATE, SPONGE_WIDTH}; use crate::hash::merkle_tree::MerkleCap; @@ -183,7 +183,7 @@ pub struct RecursiveChallenger { } impl RecursiveChallenger { - pub(crate) fn new, const D: usize>( + pub(crate) fn new, const D: usize>( builder: &mut CircuitBuilder, ) -> Self { let zero = builder.zero(); @@ -250,7 +250,7 @@ impl RecursiveChallenger { } } - pub(crate) fn get_challenge, const D: usize>( + pub(crate) fn get_challenge, const D: usize>( &mut self, builder: &mut CircuitBuilder, ) -> Target { @@ -267,7 +267,7 @@ impl RecursiveChallenger { .expect("Output buffer should be non-empty") } - pub(crate) fn get_n_challenges, const D: usize>( + pub(crate) fn get_n_challenges, const D: usize>( &mut self, builder: &mut CircuitBuilder, n: usize, @@ -275,7 +275,7 @@ impl RecursiveChallenger { (0..n).map(|_| self.get_challenge(builder)).collect() } - pub fn get_hash, const D: usize>( + pub fn get_hash, const D: usize>( &mut self, builder: &mut CircuitBuilder, ) -> HashOutTarget { @@ -289,7 +289,7 @@ impl RecursiveChallenger { } } - pub fn get_extension_challenge, const D: usize>( + pub fn get_extension_challenge, const D: usize>( &mut self, builder: &mut CircuitBuilder, ) -> ExtensionTarget { @@ -297,7 +297,7 @@ impl RecursiveChallenger { } /// Absorb any buffered inputs. After calling this, the input buffer will be empty. - fn absorb_buffered_inputs, const D: usize>( + fn absorb_buffered_inputs, const D: usize>( &mut self, builder: &mut CircuitBuilder, ) { diff --git a/src/iop/witness.rs b/src/iop/witness.rs index f1aca8a1..a5ed8ce6 100644 --- a/src/iop/witness.rs +++ b/src/iop/witness.rs @@ -44,12 +44,14 @@ pub trait Witness { } fn get_bool_target(&self, target: BoolTarget) -> bool { - let value = self.get_target(target.target).to_canonical_u64(); - match value { - 0 => false, - 1 => true, - _ => panic!("not a bool"), + let value = self.get_target(target.target); + if value.is_zero() { + return false; } + if value.is_one() { + return true; + } + panic!("not a bool") } fn get_hash_target(&self, ht: HashOutTarget) -> HashOut { diff --git a/src/plonk/circuit_builder.rs b/src/plonk/circuit_builder.rs index 7a5b57bc..6baea86a 100644 --- a/src/plonk/circuit_builder.rs +++ b/src/plonk/circuit_builder.rs @@ -7,6 +7,7 @@ use log::{info, Level}; use crate::field::cosets::get_unique_coset_shifts; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::{Extendable, FieldExtension}; +use crate::field::field_types::PrimeField; use crate::fri::commitment::PolynomialBatchCommitment; use crate::gates::arithmetic::{ArithmeticExtensionGate, NUM_ARITHMETIC_OPS}; use crate::gates::constant::ConstantGate; @@ -33,7 +34,7 @@ use crate::util::partial_products::num_partial_products; use crate::util::timing::TimingTree; use crate::util::{log2_ceil, log2_strict, transpose, transpose_poly_values}; -pub struct CircuitBuilder, const D: usize> { +pub struct CircuitBuilder, const D: usize> { pub(crate) config: CircuitConfig, /// The types of gates used in this circuit. @@ -67,7 +68,7 @@ pub struct CircuitBuilder, const D: usize> { pub(crate) free_arithmetic: HashMap<(F, F), (usize, usize)>, } -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { pub fn new(config: CircuitConfig) -> Self { CircuitBuilder { config, diff --git a/src/plonk/circuit_data.rs b/src/plonk/circuit_data.rs index e6df4ae8..fdc4fe97 100644 --- a/src/plonk/circuit_data.rs +++ b/src/plonk/circuit_data.rs @@ -3,7 +3,7 @@ use std::ops::{Range, RangeFrom}; use anyhow::Result; use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::fri::commitment::PolynomialBatchCommitment; use crate::fri::FriConfig; use crate::gates::gate::{GateInstance, PrefixedGate}; @@ -91,13 +91,13 @@ impl CircuitConfig { } /// Circuit data required by the prover or the verifier. -pub struct CircuitData, const D: usize> { +pub struct CircuitData, const D: usize> { pub(crate) prover_only: ProverOnlyCircuitData, pub(crate) verifier_only: VerifierOnlyCircuitData, pub(crate) common: CommonCircuitData, } -impl, const D: usize> CircuitData { +impl, const D: usize> CircuitData { pub fn prove(&self, inputs: PartialWitness) -> Result> { prove(&self.prover_only, &self.common, inputs) } @@ -114,12 +114,12 @@ impl, const D: usize> CircuitData { /// structure as succinct as we can. Thus we include various precomputed data which isn't strictly /// required, like LDEs of preprocessed polynomials. If more succinctness was desired, we could /// construct a more minimal prover structure and convert back and forth. -pub struct ProverCircuitData, const D: usize> { +pub struct ProverCircuitData, const D: usize> { pub(crate) prover_only: ProverOnlyCircuitData, pub(crate) common: CommonCircuitData, } -impl, const D: usize> ProverCircuitData { +impl, const D: usize> ProverCircuitData { pub fn prove(&self, inputs: PartialWitness) -> Result> { prove(&self.prover_only, &self.common, inputs) } @@ -127,19 +127,19 @@ impl, const D: usize> ProverCircuitData { /// Circuit data required by the prover. #[derive(Debug)] -pub struct VerifierCircuitData, const D: usize> { +pub struct VerifierCircuitData, const D: usize> { pub(crate) verifier_only: VerifierOnlyCircuitData, pub(crate) common: CommonCircuitData, } -impl, const D: usize> VerifierCircuitData { +impl, const D: usize> VerifierCircuitData { pub fn verify(&self, proof_with_pis: ProofWithPublicInputs) -> Result<()> { verify(proof_with_pis, &self.verifier_only, &self.common) } } /// Circuit data required by the prover, but not the verifier. -pub(crate) struct ProverOnlyCircuitData, const D: usize> { +pub(crate) struct ProverOnlyCircuitData, const D: usize> { pub generators: Vec>>, /// Commitments to the constants polynomials and sigma polynomials. pub constants_sigmas_commitment: PolynomialBatchCommitment, @@ -166,7 +166,7 @@ pub(crate) struct VerifierOnlyCircuitData { /// Circuit data required by both the prover and the verifier. #[derive(Debug)] -pub struct CommonCircuitData, const D: usize> { +pub struct CommonCircuitData, const D: usize> { pub(crate) config: CircuitConfig, pub(crate) degree_bits: usize, @@ -195,7 +195,7 @@ pub struct CommonCircuitData, const D: usize> { pub(crate) circuit_digest: HashOut, } -impl, const D: usize> CommonCircuitData { +impl, const D: usize> CommonCircuitData { pub fn degree(&self) -> usize { 1 << self.degree_bits } diff --git a/src/plonk/plonk_common.rs b/src/plonk/plonk_common.rs index 87d9d9bb..4237ac53 100644 --- a/src/plonk/plonk_common.rs +++ b/src/plonk/plonk_common.rs @@ -1,6 +1,6 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::fri::commitment::SALT_SIZE; use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; @@ -58,7 +58,7 @@ impl PlonkPolynomials { /// Evaluate the polynomial which vanishes on any multiplicative subgroup of a given order `n`. pub(crate) fn eval_zero_poly(n: usize, x: F) -> F { // Z(x) = x^n - 1 - x.exp(n as u64) - F::ONE + x.exp_u64(n as u64) - F::ONE } /// Precomputations of the evaluation of `Z_H(X) = X^n - 1` on a coset `gK` with `H <= K`. @@ -125,7 +125,7 @@ pub(crate) fn eval_l_1(n: usize, x: F) -> F { /// the order-`n` subgroup. /// /// Assumes `x != 1`; if `x` could be 1 then this is unsound. -pub(crate) fn eval_l_1_recursively, const D: usize>( +pub(crate) fn eval_l_1_recursively, const D: usize>( builder: &mut CircuitBuilder, n: usize, x: ExtensionTarget, @@ -163,7 +163,7 @@ pub(crate) fn reduce_with_powers(terms: &[F], alpha: F) -> F { sum } -pub(crate) fn reduce_with_powers_ext_recursive, const D: usize>( +pub(crate) fn reduce_with_powers_ext_recursive, const D: usize>( builder: &mut CircuitBuilder, terms: &[ExtensionTarget], alpha: Target, diff --git a/src/plonk/proof.rs b/src/plonk/proof.rs index 2ebe362b..e1ffd60c 100644 --- a/src/plonk/proof.rs +++ b/src/plonk/proof.rs @@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::fri::commitment::PolynomialBatchCommitment; use crate::fri::proof::{FriProof, FriProofTarget}; use crate::hash::hash_types::MerkleCapTarget; @@ -57,7 +58,7 @@ pub struct OpeningSet, const D: usize> { pub quotient_polys: Vec, } -impl, const D: usize> OpeningSet { +impl, const D: usize> OpeningSet { pub fn new( z: F::Extension, g: F::Extension, diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index a7a939bc..a8951897 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -3,6 +3,7 @@ use log::Level; use rayon::prelude::*; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::fri::commitment::PolynomialBatchCommitment; use crate::hash::hash_types::HashOut; use crate::hash::hashing::hash_n_to_hash; @@ -21,7 +22,7 @@ use crate::util::partial_products::partial_products; use crate::util::timing::TimingTree; use crate::util::{log2_ceil, transpose}; -pub(crate) fn prove, const D: usize>( +pub(crate) fn prove, const D: usize>( prover_data: &ProverOnlyCircuitData, common_data: &CommonCircuitData, inputs: PartialWitness, @@ -216,7 +217,7 @@ pub(crate) fn prove, const D: usize>( } /// Compute the partial products used in the `Z` polynomials. -fn all_wires_permutation_partial_products, const D: usize>( +fn all_wires_permutation_partial_products, const D: usize>( witness: &MatrixWitness, betas: &[F], gammas: &[F], @@ -239,7 +240,7 @@ fn all_wires_permutation_partial_products, const D: usize>( /// Compute the partial products used in the `Z` polynomial. /// Returns the polynomials interpolating `partial_products(f / g)` /// where `f, g` are the products in the definition of `Z`: `Z(g^i) = f / g`. -fn wires_permutation_partial_products, const D: usize>( +fn wires_permutation_partial_products, const D: usize>( witness: &MatrixWitness, beta: F, gamma: F, @@ -293,7 +294,7 @@ fn wires_permutation_partial_products, const D: usize>( .collect() } -fn compute_zs, const D: usize>( +fn compute_zs, const D: usize>( partial_products: &[Vec>], common_data: &CommonCircuitData, ) -> Vec> { @@ -303,7 +304,7 @@ fn compute_zs, const D: usize>( } /// Compute the `Z` polynomial by reusing the computations done in `wires_permutation_partial_products`. -fn compute_z, const D: usize>( +fn compute_z, const D: usize>( partial_products: &[PolynomialValues], common_data: &CommonCircuitData, ) -> PolynomialValues { @@ -316,7 +317,7 @@ fn compute_z, const D: usize>( plonk_z_points.into() } -fn compute_quotient_polys<'a, F: Extendable, const D: usize>( +fn compute_quotient_polys<'a, F: PrimeField + Extendable, const D: usize>( common_data: &CommonCircuitData, prover_data: &'a ProverOnlyCircuitData, public_inputs_hash: &HashOut, diff --git a/src/plonk/recursive_verifier.rs b/src/plonk/recursive_verifier.rs index f9e864b3..bdb5f3d5 100644 --- a/src/plonk/recursive_verifier.rs +++ b/src/plonk/recursive_verifier.rs @@ -1,4 +1,5 @@ use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::hash::hash_types::HashOutTarget; use crate::iop::challenger::RecursiveChallenger; use crate::plonk::circuit_builder::CircuitBuilder; @@ -9,7 +10,7 @@ use crate::plonk::vars::EvaluationTargets; use crate::util::reducing::ReducingFactorTarget; use crate::with_context; -impl, const D: usize> CircuitBuilder { +impl, const D: usize> CircuitBuilder { /// Recursively verifies an inner proof. pub fn add_recursive_verifier( &mut self, @@ -139,7 +140,7 @@ mod tests { use crate::util::log2_strict; // Construct a `FriQueryRoundTarget` with the same dimensions as the ones in `proof`. - fn get_fri_query_round, const D: usize>( + fn get_fri_query_round, const D: usize>( proof: &Proof, builder: &mut CircuitBuilder, ) -> FriQueryRoundTarget { @@ -172,7 +173,7 @@ mod tests { } // Construct a `ProofTarget` with the same dimensions as `proof`. - fn proof_to_proof_target, const D: usize>( + fn proof_to_proof_target, const D: usize>( proof_with_pis: &ProofWithPublicInputs, builder: &mut CircuitBuilder, ) -> ProofWithPublicInputsTarget { diff --git a/src/plonk/vanishing_poly.rs b/src/plonk/vanishing_poly.rs index 2562e0bd..0df5055c 100644 --- a/src/plonk/vanishing_poly.rs +++ b/src/plonk/vanishing_poly.rs @@ -1,6 +1,6 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::{Extendable, FieldExtension}; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::gate::PrefixedGate; use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; @@ -15,7 +15,7 @@ use crate::with_context; /// Evaluate the vanishing polynomial at `x`. In this context, the vanishing polynomial is a random /// linear combination of gate constraints, plus some other terms relating to the permutation /// argument. All such terms should vanish on `H`. -pub(crate) fn eval_vanishing_poly, const D: usize>( +pub(crate) fn eval_vanishing_poly, const D: usize>( common_data: &CommonCircuitData, x: F::Extension, vars: EvaluationVars, @@ -102,7 +102,7 @@ pub(crate) fn eval_vanishing_poly, const D: usize>( } /// Like `eval_vanishing_poly`, but specialized for base field points. -pub(crate) fn eval_vanishing_poly_base, const D: usize>( +pub(crate) fn eval_vanishing_poly_base, const D: usize>( common_data: &CommonCircuitData, index: usize, x: F, @@ -200,7 +200,7 @@ pub(crate) fn eval_vanishing_poly_base, const D: usize>( /// `num_gate_constraints` is the largest number of constraints imposed by any gate. It is not /// strictly necessary, but it helps performance by ensuring that we allocate a vector with exactly /// the capacity that we need. -pub fn evaluate_gate_constraints, const D: usize>( +pub fn evaluate_gate_constraints, const D: usize>( gates: &[PrefixedGate], num_gate_constraints: usize, vars: EvaluationVars, @@ -219,7 +219,7 @@ pub fn evaluate_gate_constraints, const D: usize>( constraints } -pub fn evaluate_gate_constraints_base, const D: usize>( +pub fn evaluate_gate_constraints_base, const D: usize>( gates: &[PrefixedGate], num_gate_constraints: usize, vars: EvaluationVarsBase, @@ -238,7 +238,7 @@ pub fn evaluate_gate_constraints_base, const D: usize>( constraints } -pub fn evaluate_gate_constraints_recursively, const D: usize>( +pub fn evaluate_gate_constraints_recursively, const D: usize>( builder: &mut CircuitBuilder, gates: &[PrefixedGate], num_gate_constraints: usize, @@ -270,7 +270,7 @@ pub fn evaluate_gate_constraints_recursively, const D: usize>( /// /// Assumes `x != 1`; if `x` could be 1 then this is unsound. This is fine if `x` is a random /// variable drawn from a sufficiently large domain. -pub(crate) fn eval_vanishing_poly_recursively, const D: usize>( +pub(crate) fn eval_vanishing_poly_recursively, const D: usize>( builder: &mut CircuitBuilder, common_data: &CommonCircuitData, x: ExtensionTarget, diff --git a/src/plonk/verifier.rs b/src/plonk/verifier.rs index cc0da79b..90a2086f 100644 --- a/src/plonk/verifier.rs +++ b/src/plonk/verifier.rs @@ -1,7 +1,7 @@ use anyhow::{ensure, Result}; use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::fri::verifier::verify_fri_proof; use crate::hash::hashing::hash_n_to_hash; use crate::iop::challenger::Challenger; @@ -11,7 +11,7 @@ use crate::plonk::proof::ProofWithPublicInputs; use crate::plonk::vanishing_poly::eval_vanishing_poly; use crate::plonk::vars::EvaluationVars; -pub(crate) fn verify, const D: usize>( +pub(crate) fn verify, const D: usize>( proof_with_pis: ProofWithPublicInputs, verifier_data: &VerifierOnlyCircuitData, common_data: &CommonCircuitData, diff --git a/src/polynomial/division.rs b/src/polynomial/division.rs index bbff96eb..6af6ca1a 100644 --- a/src/polynomial/division.rs +++ b/src/polynomial/division.rs @@ -90,8 +90,8 @@ impl PolynomialCoeffs { // Equals to the evaluation of `a` on `{g.w^i}`. let mut a_eval = fft(&a); // Compute the denominators `1/(g^n.w^(n*i) - 1)` using batch inversion. - let denominator_g = g.exp(n as u64); - let root_n = root.exp(n as u64); + let denominator_g = g.exp_u64(n as u64); + let root_n = root.exp_u64(n as u64); let mut root_pow = F::ONE; let denominators = (0..a_eval.len()) .map(|i| { diff --git a/src/polynomial/polynomial.rs b/src/polynomial/polynomial.rs index a0ba214d..744e2848 100644 --- a/src/polynomial/polynomial.rs +++ b/src/polynomial/polynomial.rs @@ -585,7 +585,7 @@ mod tests { PolynomialCoeffs::new(xn_min_one_vec) }; - let a = g.exp(rng.gen_range(0..(n as u64))); + let a = g.exp_u64(rng.gen_range(0..(n as u64))); let denom = PolynomialCoeffs::new(vec![-a, F::ONE]); let now = Instant::now(); xn_minus_one.div_rem(&denom); diff --git a/src/util/partial_products.rs b/src/util/partial_products.rs index 432fb5c2..64874a1f 100644 --- a/src/util/partial_products.rs +++ b/src/util/partial_products.rs @@ -3,6 +3,7 @@ use std::ops::Sub; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; +use crate::field::field_types::PrimeField; use crate::plonk::circuit_builder::CircuitBuilder; use crate::util::ceil_div_usize; @@ -60,7 +61,7 @@ pub fn check_partial_products>( res } -pub fn check_partial_products_recursively, const D: usize>( +pub fn check_partial_products_recursively, const D: usize>( builder: &mut CircuitBuilder, v: &[ExtensionTarget], partials: &[ExtensionTarget], diff --git a/src/util/reducing.rs b/src/util/reducing.rs index 40e52e01..cd808875 100644 --- a/src/util/reducing.rs +++ b/src/util/reducing.rs @@ -2,7 +2,7 @@ use std::borrow::Borrow; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; -use crate::field::field_types::Field; +use crate::field::field_types::{Field, PrimeField}; use crate::gates::reducing::ReducingGate; use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; @@ -67,13 +67,13 @@ impl ReducingFactor { } pub fn shift(&mut self, x: F) -> F { - let tmp = self.base.exp(self.count) * x; + let tmp = self.base.exp_u64(self.count) * x; self.count = 0; tmp } pub fn shift_poly(&mut self, p: &mut PolynomialCoeffs) { - *p *= self.base.exp(self.count); + *p *= self.base.exp_u64(self.count); self.count = 0; } @@ -100,7 +100,7 @@ impl ReducingFactorTarget { builder: &mut CircuitBuilder, ) -> ExtensionTarget where - F: Extendable, + F: PrimeField + Extendable, { let max_coeffs_len = ReducingGate::::max_coeffs_len( builder.config.num_wires, @@ -149,7 +149,7 @@ impl ReducingFactorTarget { builder: &mut CircuitBuilder, ) -> ExtensionTarget where - F: Extendable, + F: PrimeField + Extendable, { let l = terms.len(); self.count += l as u64; @@ -170,7 +170,7 @@ impl ReducingFactorTarget { builder: &mut CircuitBuilder, ) -> ExtensionTarget where - F: Extendable, + F: PrimeField + Extendable, { let exp = builder.exp_u64_extension(self.base, self.count); self.count = 0;