mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-11 18:23:09 +00:00
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
This commit is contained in:
parent
ba4b03e487
commit
236a143abf
@ -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::<CrandallField, 4>()
|
||||
}
|
||||
|
||||
fn bench_prove<F: Field + Extendable<D>, const D: usize>() -> Result<()> {
|
||||
fn bench_prove<F: PrimeField + Extendable<D>, const D: usize>() -> Result<()> {
|
||||
let config = CircuitConfig {
|
||||
num_wires: 126,
|
||||
num_routed_wires: 33,
|
||||
|
||||
@ -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<R: 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))
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
<Self as FieldExtension<2>>::BaseField::from_noncanonical_u128(n).into()
|
||||
}
|
||||
|
||||
fn from_canonical_u64(n: u64) -> Self {
|
||||
<Self as FieldExtension<2>>::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 {
|
||||
<Self as FieldExtension<2>>::BaseField::from_noncanonical_u128(n).into()
|
||||
}
|
||||
|
||||
fn rand_from_rng<R: Rng>(rng: &mut R) -> Self {
|
||||
Self([
|
||||
<Self as FieldExtension<2>>::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 - <F as FieldExtension<2>>::BaseField::TWO_ADICITY)),
|
||||
.exp_u64(1 << (F::TWO_ADICITY - <F as FieldExtension<2>>::BaseField::TWO_ADICITY)),
|
||||
<F as FieldExtension<2>>::BaseField::POWER_OF_TWO_GENERATOR.into()
|
||||
);
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
<Self as FieldExtension<4>>::BaseField::from_noncanonical_u128(n).into()
|
||||
}
|
||||
|
||||
fn from_canonical_u64(n: u64) -> Self {
|
||||
<Self as FieldExtension<4>>::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 {
|
||||
<Self as FieldExtension<4>>::BaseField::from_noncanonical_u128(n).into()
|
||||
}
|
||||
|
||||
fn rand_from_rng<R: Rng>(rng: &mut R) -> Self {
|
||||
Self([
|
||||
<Self as FieldExtension<4>>::BaseField::rand_from_rng(rng),
|
||||
@ -399,7 +373,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
F::POWER_OF_TWO_GENERATOR
|
||||
.exp(1 << (F::TWO_ADICITY - <F as FieldExtension<4>>::BaseField::TWO_ADICITY)),
|
||||
.exp_u64(1 << (F::TWO_ADICITY - <F as FieldExtension<4>>::BaseField::TWO_ADICITY)),
|
||||
<F as FieldExtension<4>>::BaseField::POWER_OF_TWO_GENERATOR.into()
|
||||
);
|
||||
}
|
||||
|
||||
@ -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<const D: usize> ExtensionTarget<D> {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn frobenius<F: Extendable<D>>(&self, builder: &mut CircuitBuilder<F, D>) -> Self {
|
||||
pub fn frobenius<F: PrimeField + Extendable<D>>(
|
||||
&self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> Self {
|
||||
self.repeated_frobenius(1, builder)
|
||||
}
|
||||
|
||||
pub fn repeated_frobenius<F: Extendable<D>>(
|
||||
pub fn repeated_frobenius<F: PrimeField + Extendable<D>>(
|
||||
&self,
|
||||
count: usize,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
@ -71,7 +74,7 @@ impl<const D: usize> ExtensionAlgebraTarget<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn constant_extension(&mut self, c: F::Extension) -> ExtensionTarget<D> {
|
||||
let c_parts = c.to_basefield_array();
|
||||
let mut parts = [self.zero(); D];
|
||||
|
||||
@ -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<F, UnaryOp, ExpectedOp>(
|
||||
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<F, BinaryOp, ExpectedOp>(
|
||||
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), <F>::ONE);
|
||||
assert_eq!(F::ONE.exp_u32(0), <F>::ONE);
|
||||
assert_eq!(F::TWO.exp_u32(0), <F>::ONE);
|
||||
assert_eq!(F::ZERO.exp_u64(0), <F>::ONE);
|
||||
assert_eq!(F::ONE.exp_u64(0), <F>::ONE);
|
||||
assert_eq!(F::TWO.exp_u64(0), <F>::ONE);
|
||||
|
||||
assert_eq!(F::ZERO.exp_u32(1), <F>::ZERO);
|
||||
assert_eq!(F::ONE.exp_u32(1), <F>::ONE);
|
||||
assert_eq!(F::TWO.exp_u32(1), <F>::TWO);
|
||||
assert_eq!(F::ZERO.exp_u64(1), <F>::ZERO);
|
||||
assert_eq!(F::ONE.exp_u64(1), <F>::ONE);
|
||||
assert_eq!(F::TWO.exp_u64(1), <F>::TWO);
|
||||
|
||||
assert_eq!(F::ZERO.kth_root_u32(1), <F>::ZERO);
|
||||
assert_eq!(F::ONE.kth_root_u32(1), <F>::ONE);
|
||||
assert_eq!(F::TWO.kth_root_u32(1), <F>::TWO);
|
||||
assert_eq!(F::ZERO.kth_root_u64(1), <F>::ZERO);
|
||||
assert_eq!(F::ONE.kth_root_u64(1), <F>::ONE);
|
||||
assert_eq!(F::TWO.kth_root_u64(1), <F>::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 = <F as Field>::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);
|
||||
}
|
||||
|
||||
@ -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<R: 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<R: 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<Self> {
|
||||
@ -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<F: Field> {
|
||||
|
||||
@ -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<F: Field> {
|
||||
pub struct PolynomialBatchCommitment<F: PrimeField> {
|
||||
pub polynomials: Vec<PolynomialCoeffs<F>>,
|
||||
pub merkle_tree: MerkleTree<F>,
|
||||
pub degree_log: usize,
|
||||
@ -28,7 +28,7 @@ pub struct PolynomialBatchCommitment<F: Field> {
|
||||
pub blinding: bool,
|
||||
}
|
||||
|
||||
impl<F: Field> PolynomialBatchCommitment<F> {
|
||||
impl<F: PrimeField> PolynomialBatchCommitment<F> {
|
||||
/// Creates a list polynomial commitment for the polynomials interpolating the values in `values`.
|
||||
pub(crate) fn from_values(
|
||||
values: Vec<PolynomialValues<F>>,
|
||||
@ -125,7 +125,7 @@ impl<F: Field> PolynomialBatchCommitment<F> {
|
||||
timing: &mut TimingTree,
|
||||
) -> (FriProof<F, D>, OpeningSet<F, D>)
|
||||
where
|
||||
F: Extendable<D>,
|
||||
F: PrimeField + Extendable<D>,
|
||||
{
|
||||
let config = &common_data.config;
|
||||
assert!(D > 1, "Not implemented for D=1.");
|
||||
@ -133,7 +133,7 @@ impl<F: Field> PolynomialBatchCommitment<F> {
|
||||
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<F: Field + Extendable<D>, const D: usize>() -> Result<()> {
|
||||
fn check_batch_polynomial_commitment<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
) -> Result<()> {
|
||||
let ks = [10, 2, 10, 8];
|
||||
let degree_bits = 11;
|
||||
let fri_config = FriConfig {
|
||||
|
||||
@ -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<F: Field + Extendable<D>, const D: usize>(
|
||||
pub fn fri_proof<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
initial_merkle_trees: &[&MerkleTree<F>],
|
||||
// Coefficients of the polynomial on which the LDT is performed. Only the first `1/rate` coefficients are non-zero.
|
||||
lde_polynomial_coeffs: PolynomialCoeffs<F::Extension>,
|
||||
@ -99,7 +99,7 @@ fn fri_committed_trees<F: Field + Extendable<D>, const D: usize>(
|
||||
.map(|chunk| reduce_with_powers(chunk, beta))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
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<F: Field + Extendable<D>, const D: usize>(
|
||||
(trees, coeffs)
|
||||
}
|
||||
|
||||
fn fri_proof_of_work<F: Field>(current_hash: HashOut<F>, config: &FriConfig) -> F {
|
||||
fn fri_proof_of_work<F: PrimeField>(current_hash: HashOut<F>, 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<F: Field>(current_hash: HashOut<F>, config: &FriConfig) ->
|
||||
.expect("Proof of work failed. This is highly unlikely!")
|
||||
}
|
||||
|
||||
fn fri_prover_query_rounds<F: Field + Extendable<D>, const D: usize>(
|
||||
fn fri_prover_query_rounds<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
initial_merkle_trees: &[&MerkleTree<F>],
|
||||
trees: &[MerkleTree<F>],
|
||||
challenger: &mut Challenger<F>,
|
||||
@ -143,7 +143,7 @@ fn fri_prover_query_rounds<F: Field + Extendable<D>, const D: usize>(
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn fri_prover_query_round<F: Field + Extendable<D>, const D: usize>(
|
||||
fn fri_prover_query_round<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
initial_merkle_trees: &[&MerkleTree<F>],
|
||||
trees: &[MerkleTree<F>],
|
||||
challenger: &mut Challenger<F>,
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// 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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
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<const D: usize> {
|
||||
}
|
||||
|
||||
impl<const D: usize> PrecomputedReducedEvalsTarget<D> {
|
||||
fn from_os_and_alpha<F: Extendable<D>>(
|
||||
fn from_os_and_alpha<F: PrimeField + Extendable<D>>(
|
||||
os: &OpeningSetTarget<D>,
|
||||
alpha: ExtensionTarget<D>,
|
||||
degree_log: usize,
|
||||
|
||||
@ -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<F: Field + Extendable<D>, 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<F: Field + Extendable<D>, const D: usize>(
|
||||
interpolate(&points, beta, &barycentric_weights)
|
||||
}
|
||||
|
||||
fn fri_verify_proof_of_work<F: Field + Extendable<D>, const D: usize>(
|
||||
fn fri_verify_proof_of_work<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
proof: &FriProof<F, D>,
|
||||
challenger: &mut Challenger<F>,
|
||||
config: &FriConfig,
|
||||
@ -68,7 +68,7 @@ fn fri_verify_proof_of_work<F: Field + Extendable<D>, const D: usize>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn verify_fri_proof<F: Field + Extendable<D>, const D: usize>(
|
||||
pub fn verify_fri_proof<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
// Openings of the PLONK polynomials.
|
||||
os: &OpeningSet<F, D>,
|
||||
// Point at which the PLONK polynomials are opened.
|
||||
@ -179,7 +179,7 @@ impl<F: Extendable<D>, const D: usize> PrecomputedReducedEvals<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
||||
fn fri_combine_initial<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
proof: &FriInitialTreeProof<F>,
|
||||
alpha: F::Extension,
|
||||
zeta: F::Extension,
|
||||
@ -244,7 +244,7 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
||||
sum
|
||||
}
|
||||
|
||||
fn fri_verifier_query_round<F: Field + Extendable<D>, const D: usize>(
|
||||
fn fri_verifier_query_round<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
zeta: F::Extension,
|
||||
alpha: F::Extension,
|
||||
precomputed_reduced_evals: PrecomputedReducedEvals<F, D>,
|
||||
@ -267,7 +267,7 @@ fn fri_verifier_query_round<F: Field + Extendable<D>, 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.
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Computes `-x`.
|
||||
pub fn neg(&mut self, x: Target) -> Target {
|
||||
let neg_one = self.neg_one();
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// 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<const D: usize> {
|
||||
quotient: ExtensionTarget<D>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for QuotientGeneratorExtension<D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for QuotientGeneratorExtension<D>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
let mut deps = self.numerator.to_target_array().to_vec();
|
||||
deps.extend(&self.denominator.to_target_array());
|
||||
@ -463,7 +465,7 @@ pub struct PowersTarget<const D: usize> {
|
||||
}
|
||||
|
||||
impl<const D: usize> PowersTarget<D> {
|
||||
pub fn next<F: Extendable<D>>(
|
||||
pub fn next<F: PrimeField + Extendable<D>>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtensionTarget<D> {
|
||||
@ -472,7 +474,7 @@ impl<const D: usize> PowersTarget<D> {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn repeated_frobenius<F: Extendable<D>>(
|
||||
pub fn repeated_frobenius<F: PrimeField + Extendable<D>>(
|
||||
self,
|
||||
k: usize,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
@ -485,7 +487,7 @@ impl<const D: usize> PowersTarget<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn powers(&mut self, base: ExtensionTarget<D>) -> PowersTarget<D> {
|
||||
PowersTarget {
|
||||
base,
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn permute(&mut self, inputs: [Target; 12]) -> [Target; 12] {
|
||||
let zero = self.zero();
|
||||
let gate_type = GMiMCGate::<F, D, GMIMC_ROUNDS>::new_automatic_constants();
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Inserts a `Target` in a vector at a non-deterministic index.
|
||||
/// Note: `index` is not range-checked.
|
||||
pub fn insert(
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Interpolate a list of point/evaluation pairs at a given point.
|
||||
/// Returns the evaluation of the interpolated polynomial at `evaluation_point`.
|
||||
pub fn interpolate(
|
||||
|
||||
@ -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<const D: usize> PolynomialCoeffsExtTarget<D> {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
pub fn eval_scalar<F: Extendable<D>>(
|
||||
pub fn eval_scalar<F: PrimeField + Extendable<D>>(
|
||||
&self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
point: Target,
|
||||
@ -21,7 +22,7 @@ impl<const D: usize> PolynomialCoeffsExtTarget<D> {
|
||||
point.reduce(&self.0, builder)
|
||||
}
|
||||
|
||||
pub fn eval<F: Extendable<D>>(
|
||||
pub fn eval<F: PrimeField + Extendable<D>>(
|
||||
&self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
point: ExtensionTarget<D>,
|
||||
@ -40,7 +41,7 @@ impl<const D: usize> PolynomialCoeffsExtAlgebraTarget<D> {
|
||||
point: ExtensionTarget<D>,
|
||||
) -> ExtensionAlgebraTarget<D>
|
||||
where
|
||||
F: Extendable<D>,
|
||||
F: PrimeField + Extendable<D>,
|
||||
{
|
||||
let mut acc = builder.zero_ext_algebra();
|
||||
for &c in self.0.iter().rev() {
|
||||
@ -55,7 +56,7 @@ impl<const D: usize> PolynomialCoeffsExtAlgebraTarget<D> {
|
||||
point: ExtensionAlgebraTarget<D>,
|
||||
) -> ExtensionAlgebraTarget<D>
|
||||
where
|
||||
F: Extendable<D>,
|
||||
F: PrimeField + Extendable<D>,
|
||||
{
|
||||
let mut acc = builder.zero_ext_algebra();
|
||||
for &c in self.0.iter().rev() {
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Checks that a `Target` matches a vector at a non-deterministic index.
|
||||
/// Note: `index` is not range-checked.
|
||||
pub fn random_access(
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// 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<F: Field> SimpleGenerator<F> for LowHighGenerator {
|
||||
impl<F: PrimeField> SimpleGenerator<F> for LowHighGenerator {
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
vec![self.integer]
|
||||
}
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Selects `x` or `y` based on `b`, i.e., this returns `if b { x } else { y }`.
|
||||
pub fn select_ext(
|
||||
&mut self,
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// 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<const B: usize>(&mut self, x: Target, num_limbs: usize) -> Vec<Target> {
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// 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<Target>,
|
||||
}
|
||||
|
||||
impl<F: Field> SimpleGenerator<F> for SplitGenerator {
|
||||
impl<F: PrimeField> SimpleGenerator<F> for SplitGenerator {
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
vec![self.integer]
|
||||
}
|
||||
@ -91,7 +91,7 @@ struct WireSplitGenerator {
|
||||
num_limbs: usize,
|
||||
}
|
||||
|
||||
impl<F: Field> SimpleGenerator<F> for WireSplitGenerator {
|
||||
impl<F: PrimeField> SimpleGenerator<F> for WireSplitGenerator {
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
vec![self.integer]
|
||||
}
|
||||
|
||||
@ -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<const D: usize> ArithmeticExtensionGate<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> Gate<F, D> for ArithmeticExtensionGate<D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for ArithmeticExtensionGate<D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}", self)
|
||||
}
|
||||
@ -139,14 +140,16 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for ArithmeticExtensionGate<D>
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct ArithmeticExtensionGenerator<F: Extendable<D>, const D: usize> {
|
||||
struct ArithmeticExtensionGenerator<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
const_0: F,
|
||||
const_1: F,
|
||||
i: usize,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for ArithmeticExtensionGenerator<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for ArithmeticExtensionGenerator<F, D>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
ArithmeticExtensionGate::<D>::wires_ith_multiplicand_0(self.i)
|
||||
.chain(ArithmeticExtensionGate::<D>::wires_ith_multiplicand_1(
|
||||
|
||||
@ -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<const B: usize> BaseSumGate<B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize, const B: usize> Gate<F, D> for BaseSumGate<B> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize, const B: usize> Gate<F, D> for BaseSumGate<B> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?} + Base: {}", self, B)
|
||||
}
|
||||
@ -134,7 +134,7 @@ pub struct BaseSplitGenerator<const B: usize> {
|
||||
num_limbs: usize,
|
||||
}
|
||||
|
||||
impl<F: Field, const B: usize> SimpleGenerator<F> for BaseSplitGenerator<B> {
|
||||
impl<F: PrimeField, const B: usize> SimpleGenerator<F> for BaseSplitGenerator<B> {
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
vec![Target::wire(self.gate_index, BaseSumGate::<B>::WIRE_SUM)]
|
||||
}
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> Gate<F, D> for ConstantGate {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for ConstantGate {
|
||||
fn id(&self) -> String {
|
||||
"ConstantGate".into()
|
||||
}
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> {
|
||||
pub(crate) struct ExponentiationGate<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub num_power_bits: usize,
|
||||
pub _phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> ExponentiationGate<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> ExponentiationGate<F, D> {
|
||||
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<F: Extendable<D>, const D: usize> ExponentiationGate<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> Gate<F, D> for ExponentiationGate<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for ExponentiationGate<F, D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}<D={}>", self, D)
|
||||
}
|
||||
@ -201,12 +201,14 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for ExponentiationGate<F, D> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ExponentiationGenerator<F: Extendable<D>, const D: usize> {
|
||||
struct ExponentiationGenerator<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: ExponentiationGate<F, D>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for ExponentiationGenerator<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for ExponentiationGenerator<F, D>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
let local_target = |input| Target::wire(self.gate_index, input);
|
||||
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize>: 'static + Send + Sync {
|
||||
pub trait Gate<F: PrimeField + Extendable<D>, const D: usize>: 'static + Send + Sync {
|
||||
fn id(&self) -> String;
|
||||
|
||||
fn eval_unfiltered(&self, vars: EvaluationVars<F, D>) -> Vec<F::Extension>;
|
||||
@ -108,48 +108,48 @@ pub trait Gate<F: Extendable<D>, const D: usize>: 'static + Send + Sync {
|
||||
|
||||
/// A wrapper around an `Rc<Gate>` which implements `PartialEq`, `Eq` and `Hash` based on gate IDs.
|
||||
#[derive(Clone)]
|
||||
pub struct GateRef<F: Extendable<D>, const D: usize>(pub(crate) Arc<dyn Gate<F, D>>);
|
||||
pub struct GateRef<F: PrimeField + Extendable<D>, const D: usize>(pub(crate) Arc<dyn Gate<F, D>>);
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> GateRef<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> GateRef<F, D> {
|
||||
pub fn new<G: Gate<F, D>>(gate: G) -> GateRef<F, D> {
|
||||
GateRef(Arc::new(gate))
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> PartialEq for GateRef<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> PartialEq for GateRef<F, D> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.id() == other.0.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> Hash for GateRef<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Hash for GateRef<F, D> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.0.id().hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> Eq for GateRef<F, D> {}
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Eq for GateRef<F, D> {}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> Debug for GateRef<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Debug for GateRef<F, D> {
|
||||
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<F: Extendable<D>, const D: usize> {
|
||||
pub struct GateInstance<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub gate_ref: GateRef<F, D>,
|
||||
pub constants: Vec<F>,
|
||||
}
|
||||
|
||||
/// Map each gate to a boolean prefix used to construct the gate's selector polynomial.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PrefixedGate<F: Extendable<D>, const D: usize> {
|
||||
pub struct PrefixedGate<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub gate: GateRef<F, D>,
|
||||
pub prefix: Vec<bool>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> PrefixedGate<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> PrefixedGate<F, D> {
|
||||
pub fn from_tree(tree: Tree<GateRef<F, D>>) -> Vec<Self> {
|
||||
tree.traversal()
|
||||
.into_iter()
|
||||
@ -174,7 +174,7 @@ fn compute_filter<K: Field>(prefix: &[bool], constants: &[K]) -> K {
|
||||
.product()
|
||||
}
|
||||
|
||||
fn compute_filter_recursively<F: Extendable<D>, const D: usize>(
|
||||
fn compute_filter_recursively<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
prefix: &[bool],
|
||||
constants: &[ExtensionTarget<D>],
|
||||
|
||||
@ -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<F: Extendable<D>, G: Gate<F, D>, const D: usize>(gate: G) {
|
||||
pub(crate) fn test_low_degree<F: PrimeField + Extendable<D>, G: Gate<F, D>, const D: usize>(
|
||||
gate: G,
|
||||
) {
|
||||
let rate_bits = log2_ceil(gate.degree() + 1);
|
||||
|
||||
let wire_ldes = random_low_degree_matrix::<F::Extension>(gate.num_wires(), rate_bits);
|
||||
@ -82,7 +84,7 @@ fn random_low_degree_values<F: Field>(rate_bits: usize) -> Vec<F> {
|
||||
.values
|
||||
}
|
||||
|
||||
pub(crate) fn test_eval_fns<F: Extendable<D>, G: Gate<F, D>, const D: usize>(
|
||||
pub(crate) fn test_eval_fns<F: PrimeField + Extendable<D>, G: Gate<F, D>, const D: usize>(
|
||||
gate: G,
|
||||
) -> Result<()> {
|
||||
// Test that `eval_unfiltered` and `eval_unfiltered_base` are coherent.
|
||||
|
||||
@ -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<T: Clone> Tree<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> Tree<GateRef<F, D>> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Tree<GateRef<F, D>> {
|
||||
/// 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.
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize, const R: usize> {
|
||||
pub struct GMiMCGate<F: PrimeField + Extendable<D>, const D: usize, const R: usize> {
|
||||
constants: Arc<[F; R]>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize, const R: usize> GMiMCGate<F, D, R> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> GMiMCGate<F, D, R> {
|
||||
pub fn new(constants: Arc<[F; R]>) -> Self {
|
||||
Self { constants }
|
||||
}
|
||||
@ -62,7 +62,9 @@ impl<F: Extendable<D>, const D: usize, const R: usize> GMiMCGate<F, D, R> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize, const R: usize> Gate<F, D> for GMiMCGate<F, D, R> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> Gate<F, D>
|
||||
for GMiMCGate<F, D, R>
|
||||
{
|
||||
fn id(&self) -> String {
|
||||
format!("<R={}> {:?}", R, self)
|
||||
}
|
||||
@ -238,12 +240,12 @@ impl<F: Extendable<D>, const D: usize, const R: usize> Gate<F, D> for GMiMCGate<
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct GMiMCGenerator<F: Extendable<D>, const D: usize, const R: usize> {
|
||||
struct GMiMCGenerator<F: PrimeField + Extendable<D>, const D: usize, const R: usize> {
|
||||
gate_index: usize,
|
||||
constants: Arc<[F; R]>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize, const R: usize> SimpleGenerator<F>
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> SimpleGenerator<F>
|
||||
for GMiMCGenerator<F, D, R>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> {
|
||||
pub(crate) struct InsertionGate<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub vec_size: usize,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> InsertionGate<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> InsertionGate<F, D> {
|
||||
pub fn new(vec_size: usize) -> Self {
|
||||
Self {
|
||||
vec_size,
|
||||
@ -70,7 +70,7 @@ impl<F: Extendable<D>, const D: usize> InsertionGate<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> Gate<F, D> for InsertionGate<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for InsertionGate<F, D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}<D={}>", self, D)
|
||||
}
|
||||
@ -241,12 +241,14 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for InsertionGate<F, D> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InsertionGenerator<F: Extendable<D>, const D: usize> {
|
||||
struct InsertionGenerator<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: InsertionGate<F, D>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for InsertionGenerator<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for InsertionGenerator<F, D>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
let local_target = |input| Target::wire(self.gate_index, input);
|
||||
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> {
|
||||
pub(crate) struct InterpolationGate<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub num_points: usize,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> InterpolationGate<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> InterpolationGate<F, D> {
|
||||
pub fn new(num_points: usize) -> Self {
|
||||
Self {
|
||||
num_points,
|
||||
@ -93,7 +94,7 @@ impl<F: Extendable<D>, const D: usize> InterpolationGate<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> Gate<F, D> for InterpolationGate<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for InterpolationGate<F, D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}<D={}>", self, D)
|
||||
}
|
||||
@ -214,13 +215,15 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for InterpolationGate<F, D> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InterpolationGenerator<F: Extendable<D>, const D: usize> {
|
||||
struct InterpolationGenerator<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: InterpolationGate<F, D>,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for InterpolationGenerator<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for InterpolationGenerator<F, D>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
let local_target = |input| {
|
||||
Target::Wire(Wire {
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> Gate<F, D> for NoopGate {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for NoopGate {
|
||||
fn id(&self) -> String {
|
||||
"NoopGate".into()
|
||||
}
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> Gate<F, D> for PublicInputGate {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for PublicInputGate {
|
||||
fn id(&self) -> String {
|
||||
"PublicInputGate".into()
|
||||
}
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> {
|
||||
pub(crate) struct RandomAccessGate<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub vec_size: usize,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> RandomAccessGate<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> RandomAccessGate<F, D> {
|
||||
pub fn new(vec_size: usize) -> Self {
|
||||
Self {
|
||||
vec_size,
|
||||
@ -61,7 +61,7 @@ impl<F: Extendable<D>, const D: usize> RandomAccessGate<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGate<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGate<F, D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}<D={}>", self, D)
|
||||
}
|
||||
@ -188,12 +188,14 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGate<F, D> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct RandomAccessGenerator<F: Extendable<D>, const D: usize> {
|
||||
struct RandomAccessGenerator<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: RandomAccessGate<F, D>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for RandomAccessGenerator<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for RandomAccessGenerator<F, D>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
let local_target = |input| Target::wire(self.gate_index, input);
|
||||
|
||||
|
||||
@ -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<const D: usize> ReducingGate<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> Gate<F, D> for ReducingGate<D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for ReducingGate<D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}", self)
|
||||
}
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize, const CHUNK_SIZE: usize> {
|
||||
pub(crate) struct SwitchGate<F: PrimeField + Extendable<D>, const D: usize, const CHUNK_SIZE: usize>
|
||||
{
|
||||
num_copies: usize,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize, const CHUNK_SIZE: usize> SwitchGate<F, D, CHUNK_SIZE> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize, const CHUNK_SIZE: usize>
|
||||
SwitchGate<F, D, CHUNK_SIZE>
|
||||
{
|
||||
pub fn new(config: CircuitConfig) -> Self {
|
||||
let num_copies = Self::max_num_copies(config.num_routed_wires);
|
||||
Self {
|
||||
@ -62,7 +65,7 @@ impl<F: Extendable<D>, const D: usize, const CHUNK_SIZE: usize> SwitchGate<F, D,
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize, const CHUNK_SIZE: usize> Gate<F, D>
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize, const CHUNK_SIZE: usize> Gate<F, D>
|
||||
for SwitchGate<F, D, CHUNK_SIZE>
|
||||
{
|
||||
fn id(&self) -> String {
|
||||
@ -187,12 +190,12 @@ impl<F: Extendable<D>, const D: usize, const CHUNK_SIZE: usize> Gate<F, D>
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SwitchGenerator<F: Extendable<D>, const D: usize, const CHUNK_SIZE: usize> {
|
||||
struct SwitchGenerator<F: PrimeField + Extendable<D>, const D: usize, const CHUNK_SIZE: usize> {
|
||||
gate_index: usize,
|
||||
gate: SwitchGate<F, D, CHUNK_SIZE>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize, const CHUNK_SIZE: usize> SimpleGenerator<F>
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize, const CHUNK_SIZE: usize> SimpleGenerator<F>
|
||||
for SwitchGenerator<F, D, CHUNK_SIZE>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
|
||||
@ -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<F: Field>(inputs: Vec<F>) -> HashOut<F> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn hash_or_noop(&mut self, inputs: Vec<Target>) -> HashOutTarget {
|
||||
let zero = self.zero();
|
||||
if inputs.len() <= 4 {
|
||||
|
||||
@ -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<F: Field>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// 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.
|
||||
|
||||
@ -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<const WIDTH: usize>: Field
|
||||
pub trait PoseidonInterface<const WIDTH: usize>: PrimeField
|
||||
where
|
||||
// magic to get const generic expressions to work
|
||||
[(); WIDTH - 1]: ,
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize>(
|
||||
pub(crate) fn new<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> Self {
|
||||
let zero = builder.zero();
|
||||
@ -250,7 +250,7 @@ impl RecursiveChallenger {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_challenge<F: Extendable<D>, const D: usize>(
|
||||
pub(crate) fn get_challenge<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> Target {
|
||||
@ -267,7 +267,7 @@ impl RecursiveChallenger {
|
||||
.expect("Output buffer should be non-empty")
|
||||
}
|
||||
|
||||
pub(crate) fn get_n_challenges<F: Extendable<D>, const D: usize>(
|
||||
pub(crate) fn get_n_challenges<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
n: usize,
|
||||
@ -275,7 +275,7 @@ impl RecursiveChallenger {
|
||||
(0..n).map(|_| self.get_challenge(builder)).collect()
|
||||
}
|
||||
|
||||
pub fn get_hash<F: Extendable<D>, const D: usize>(
|
||||
pub fn get_hash<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> HashOutTarget {
|
||||
@ -289,7 +289,7 @@ impl RecursiveChallenger {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_extension_challenge<F: Extendable<D>, const D: usize>(
|
||||
pub fn get_extension_challenge<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtensionTarget<D> {
|
||||
@ -297,7 +297,7 @@ impl RecursiveChallenger {
|
||||
}
|
||||
|
||||
/// Absorb any buffered inputs. After calling this, the input buffer will be empty.
|
||||
fn absorb_buffered_inputs<F: Extendable<D>, const D: usize>(
|
||||
fn absorb_buffered_inputs<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) {
|
||||
|
||||
@ -44,12 +44,14 @@ pub trait Witness<F: Field> {
|
||||
}
|
||||
|
||||
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<F> {
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> {
|
||||
pub struct CircuitBuilder<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) config: CircuitConfig,
|
||||
|
||||
/// The types of gates used in this circuit.
|
||||
@ -67,7 +68,7 @@ pub struct CircuitBuilder<F: Extendable<D>, const D: usize> {
|
||||
pub(crate) free_arithmetic: HashMap<(F, F), (usize, usize)>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn new(config: CircuitConfig) -> Self {
|
||||
CircuitBuilder {
|
||||
config,
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> {
|
||||
pub struct CircuitData<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) prover_only: ProverOnlyCircuitData<F, D>,
|
||||
pub(crate) verifier_only: VerifierOnlyCircuitData<F>,
|
||||
pub(crate) common: CommonCircuitData<F, D>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> CircuitData<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitData<F, D> {
|
||||
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, D>> {
|
||||
prove(&self.prover_only, &self.common, inputs)
|
||||
}
|
||||
@ -114,12 +114,12 @@ impl<F: Extendable<D>, const D: usize> CircuitData<F, D> {
|
||||
/// 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<F: Extendable<D>, const D: usize> {
|
||||
pub struct ProverCircuitData<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) prover_only: ProverOnlyCircuitData<F, D>,
|
||||
pub(crate) common: CommonCircuitData<F, D>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> ProverCircuitData<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> ProverCircuitData<F, D> {
|
||||
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, D>> {
|
||||
prove(&self.prover_only, &self.common, inputs)
|
||||
}
|
||||
@ -127,19 +127,19 @@ impl<F: Extendable<D>, const D: usize> ProverCircuitData<F, D> {
|
||||
|
||||
/// Circuit data required by the prover.
|
||||
#[derive(Debug)]
|
||||
pub struct VerifierCircuitData<F: Extendable<D>, const D: usize> {
|
||||
pub struct VerifierCircuitData<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) verifier_only: VerifierOnlyCircuitData<F>,
|
||||
pub(crate) common: CommonCircuitData<F, D>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> VerifierCircuitData<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> VerifierCircuitData<F, D> {
|
||||
pub fn verify(&self, proof_with_pis: ProofWithPublicInputs<F, D>) -> Result<()> {
|
||||
verify(proof_with_pis, &self.verifier_only, &self.common)
|
||||
}
|
||||
}
|
||||
|
||||
/// Circuit data required by the prover, but not the verifier.
|
||||
pub(crate) struct ProverOnlyCircuitData<F: Extendable<D>, const D: usize> {
|
||||
pub(crate) struct ProverOnlyCircuitData<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub generators: Vec<Box<dyn WitnessGenerator<F>>>,
|
||||
/// Commitments to the constants polynomials and sigma polynomials.
|
||||
pub constants_sigmas_commitment: PolynomialBatchCommitment<F>,
|
||||
@ -166,7 +166,7 @@ pub(crate) struct VerifierOnlyCircuitData<F: Field> {
|
||||
|
||||
/// Circuit data required by both the prover and the verifier.
|
||||
#[derive(Debug)]
|
||||
pub struct CommonCircuitData<F: Extendable<D>, const D: usize> {
|
||||
pub struct CommonCircuitData<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) config: CircuitConfig,
|
||||
|
||||
pub(crate) degree_bits: usize,
|
||||
@ -195,7 +195,7 @@ pub struct CommonCircuitData<F: Extendable<D>, const D: usize> {
|
||||
pub(crate) circuit_digest: HashOut<F>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> CommonCircuitData<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CommonCircuitData<F, D> {
|
||||
pub fn degree(&self) -> usize {
|
||||
1 << self.degree_bits
|
||||
}
|
||||
|
||||
@ -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<F: Field>(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<F: Field>(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<F: Extendable<D>, const D: usize>(
|
||||
pub(crate) fn eval_l_1_recursively<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
n: usize,
|
||||
x: ExtensionTarget<D>,
|
||||
@ -163,7 +163,7 @@ pub(crate) fn reduce_with_powers<F: Field>(terms: &[F], alpha: F) -> F {
|
||||
sum
|
||||
}
|
||||
|
||||
pub(crate) fn reduce_with_powers_ext_recursive<F: Extendable<D>, const D: usize>(
|
||||
pub(crate) fn reduce_with_powers_ext_recursive<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
terms: &[ExtensionTarget<D>],
|
||||
alpha: Target,
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> {
|
||||
pub quotient_polys: Vec<F::Extension>,
|
||||
}
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> OpeningSet<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> OpeningSet<F, D> {
|
||||
pub fn new(
|
||||
z: F::Extension,
|
||||
g: F::Extension,
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize>(
|
||||
pub(crate) fn prove<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
prover_data: &ProverOnlyCircuitData<F, D>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
inputs: PartialWitness<F>,
|
||||
@ -216,7 +217,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
}
|
||||
|
||||
/// Compute the partial products used in the `Z` polynomials.
|
||||
fn all_wires_permutation_partial_products<F: Extendable<D>, const D: usize>(
|
||||
fn all_wires_permutation_partial_products<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
witness: &MatrixWitness<F>,
|
||||
betas: &[F],
|
||||
gammas: &[F],
|
||||
@ -239,7 +240,7 @@ fn all_wires_permutation_partial_products<F: Extendable<D>, 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<F: Extendable<D>, const D: usize>(
|
||||
fn wires_permutation_partial_products<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
witness: &MatrixWitness<F>,
|
||||
beta: F,
|
||||
gamma: F,
|
||||
@ -293,7 +294,7 @@ fn wires_permutation_partial_products<F: Extendable<D>, const D: usize>(
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn compute_zs<F: Extendable<D>, const D: usize>(
|
||||
fn compute_zs<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
partial_products: &[Vec<PolynomialValues<F>>],
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) -> Vec<PolynomialValues<F>> {
|
||||
@ -303,7 +304,7 @@ fn compute_zs<F: Extendable<D>, const D: usize>(
|
||||
}
|
||||
|
||||
/// Compute the `Z` polynomial by reusing the computations done in `wires_permutation_partial_products`.
|
||||
fn compute_z<F: Extendable<D>, const D: usize>(
|
||||
fn compute_z<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
partial_products: &[PolynomialValues<F>],
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) -> PolynomialValues<F> {
|
||||
@ -316,7 +317,7 @@ fn compute_z<F: Extendable<D>, const D: usize>(
|
||||
plonk_z_points.into()
|
||||
}
|
||||
|
||||
fn compute_quotient_polys<'a, F: Extendable<D>, const D: usize>(
|
||||
fn compute_quotient_polys<'a, F: PrimeField + Extendable<D>, const D: usize>(
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
prover_data: &'a ProverOnlyCircuitData<F, D>,
|
||||
public_inputs_hash: &HashOut<F>,
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// 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<F: Extendable<D>, const D: usize>(
|
||||
fn get_fri_query_round<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
proof: &Proof<F, D>,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> FriQueryRoundTarget<D> {
|
||||
@ -172,7 +173,7 @@ mod tests {
|
||||
}
|
||||
|
||||
// Construct a `ProofTarget` with the same dimensions as `proof`.
|
||||
fn proof_to_proof_target<F: Extendable<D>, const D: usize>(
|
||||
fn proof_to_proof_target<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
proof_with_pis: &ProofWithPublicInputs<F, D>,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ProofWithPublicInputsTarget<D> {
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize>(
|
||||
pub(crate) fn eval_vanishing_poly<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
x: F::Extension,
|
||||
vars: EvaluationVars<F, D>,
|
||||
@ -102,7 +102,7 @@ pub(crate) fn eval_vanishing_poly<F: Extendable<D>, const D: usize>(
|
||||
}
|
||||
|
||||
/// Like `eval_vanishing_poly`, but specialized for base field points.
|
||||
pub(crate) fn eval_vanishing_poly_base<F: Extendable<D>, const D: usize>(
|
||||
pub(crate) fn eval_vanishing_poly_base<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
index: usize,
|
||||
x: F,
|
||||
@ -200,7 +200,7 @@ pub(crate) fn eval_vanishing_poly_base<F: Extendable<D>, 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<F: Extendable<D>, const D: usize>(
|
||||
pub fn evaluate_gate_constraints<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
gates: &[PrefixedGate<F, D>],
|
||||
num_gate_constraints: usize,
|
||||
vars: EvaluationVars<F, D>,
|
||||
@ -219,7 +219,7 @@ pub fn evaluate_gate_constraints<F: Extendable<D>, const D: usize>(
|
||||
constraints
|
||||
}
|
||||
|
||||
pub fn evaluate_gate_constraints_base<F: Extendable<D>, const D: usize>(
|
||||
pub fn evaluate_gate_constraints_base<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
gates: &[PrefixedGate<F, D>],
|
||||
num_gate_constraints: usize,
|
||||
vars: EvaluationVarsBase<F>,
|
||||
@ -238,7 +238,7 @@ pub fn evaluate_gate_constraints_base<F: Extendable<D>, const D: usize>(
|
||||
constraints
|
||||
}
|
||||
|
||||
pub fn evaluate_gate_constraints_recursively<F: Extendable<D>, const D: usize>(
|
||||
pub fn evaluate_gate_constraints_recursively<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
gates: &[PrefixedGate<F, D>],
|
||||
num_gate_constraints: usize,
|
||||
@ -270,7 +270,7 @@ pub fn evaluate_gate_constraints_recursively<F: Extendable<D>, 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<F: Extendable<D>, const D: usize>(
|
||||
pub(crate) fn eval_vanishing_poly_recursively<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
x: ExtensionTarget<D>,
|
||||
|
||||
@ -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<F: Extendable<D>, const D: usize>(
|
||||
pub(crate) fn verify<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
proof_with_pis: ProofWithPublicInputs<F, D>,
|
||||
verifier_data: &VerifierOnlyCircuitData<F>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
|
||||
@ -90,8 +90,8 @@ impl<F: Field> PolynomialCoeffs<F> {
|
||||
// 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| {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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<T: Product + Copy + Sub<Output = T>>(
|
||||
res
|
||||
}
|
||||
|
||||
pub fn check_partial_products_recursively<F: Extendable<D>, const D: usize>(
|
||||
pub fn check_partial_products_recursively<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
v: &[ExtensionTarget<D>],
|
||||
partials: &[ExtensionTarget<D>],
|
||||
|
||||
@ -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<F: Field> ReducingFactor<F> {
|
||||
}
|
||||
|
||||
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<F>) {
|
||||
*p *= self.base.exp(self.count);
|
||||
*p *= self.base.exp_u64(self.count);
|
||||
self.count = 0;
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ impl<const D: usize> ReducingFactorTarget<D> {
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtensionTarget<D>
|
||||
where
|
||||
F: Extendable<D>,
|
||||
F: PrimeField + Extendable<D>,
|
||||
{
|
||||
let max_coeffs_len = ReducingGate::<D>::max_coeffs_len(
|
||||
builder.config.num_wires,
|
||||
@ -149,7 +149,7 @@ impl<const D: usize> ReducingFactorTarget<D> {
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtensionTarget<D>
|
||||
where
|
||||
F: Extendable<D>,
|
||||
F: PrimeField + Extendable<D>,
|
||||
{
|
||||
let l = terms.len();
|
||||
self.count += l as u64;
|
||||
@ -170,7 +170,7 @@ impl<const D: usize> ReducingFactorTarget<D> {
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtensionTarget<D>
|
||||
where
|
||||
F: Extendable<D>,
|
||||
F: PrimeField + Extendable<D>,
|
||||
{
|
||||
let exp = builder.exp_u64_extension(self.base, self.count);
|
||||
self.count = 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user