Fix merge conflicts

This commit is contained in:
wborgeaud 2021-12-16 15:20:45 +01:00
parent bdbc8b6931
commit 288a0b7cf8
34 changed files with 326 additions and 304 deletions

View File

@ -1,4 +1,3 @@
use crate::field::field_types::{Field, PrimeField};
use std::convert::TryInto;
use crate::field::field_types::{Field, RichField};

View File

@ -13,7 +13,6 @@ use crate::iop::challenger::RecursiveChallenger;
use crate::iop::target::{BoolTarget, Target};
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData};
use crate::plonk::circuit_data::CommonCircuitData;
use crate::plonk::config::{AlgebraicConfig, AlgebraicHasher, GenericConfig};
use crate::plonk::plonk_common::PlonkPolynomials;
use crate::plonk::proof::OpeningSetTarget;
@ -24,14 +23,14 @@ use crate::with_context;
impl<F: 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(
fn compute_evaluation<C: GenericConfig<D, F = F>>(
&mut self,
x: Target,
x_index_within_coset_bits: &[BoolTarget],
arity_bits: usize,
evals: &[ExtensionTarget<D>],
beta: ExtensionTarget<D>,
common_data: &CommonCircuitData<F, D>,
common_data: &CommonCircuitData<F, C, D>,
) -> ExtensionTarget<D> {
let arity = 1 << arity_bits;
debug_assert_eq!(evals.len(), arity);
@ -70,10 +69,10 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
/// Make sure we have enough wires and routed wires to do the FRI checks efficiently. This check
/// isn't required -- without it we'd get errors elsewhere in the stack -- but just gives more
/// helpful errors.
fn check_recursion_config(
fn check_recursion_config<C: GenericConfig<D, F = F>>(
&self,
max_fri_arity_bits: usize,
common_data: &CommonCircuitData<F, D>,
common_data: &CommonCircuitData<F, C, D>,
) {
let random_access = RandomAccessGate::<F, D>::new_from_config(
&self.config,

View File

@ -1,7 +1,6 @@
use std::borrow::Borrow;
use crate::field::extension_field::Extendable;
use crate::gates::arithmetic::ArithmeticExtensionGate;
use crate::field::field_types::{PrimeField, RichField};
use crate::gates::arithmetic_base::ArithmeticGate;
use crate::gates::exponentiation::ExponentiationGate;

View File

@ -4,8 +4,6 @@ use crate::field::extension_field::{Extendable, OEF};
use crate::field::field_types::{Field, PrimeField, RichField};
use crate::gates::arithmetic_extension::ArithmeticExtensionGate;
use crate::gates::multiplication_extension::MulExtensionGate;
use crate::field::field_types::{Field, PrimeField};
use crate::gates::arithmetic::ArithmeticExtensionGate;
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
use crate::iop::target::Target;
use crate::iop::witness::{PartitionWitness, Witness};

View File

@ -248,6 +248,7 @@ mod tests {
use rand::Rng;
use crate::iop::witness::Witness;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
use crate::{
field::goldilocks_field::GoldilocksField,
iop::witness::PartialWitness,
@ -256,16 +257,19 @@ mod tests {
#[test]
fn test_biguint_add() -> Result<()> {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type FF = <C as GenericConfig<D>>::FE;
let mut rng = rand::thread_rng();
let x_value = BigUint::from_u128(rng.gen()).unwrap();
let y_value = BigUint::from_u128(rng.gen()).unwrap();
let expected_z_value = &x_value + &y_value;
type F = GoldilocksField;
let config = CircuitConfig::standard_recursion_config();
let mut pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut builder = CircuitBuilder::<F, D>::new(config);
let x = builder.add_virtual_biguint_target(x_value.to_u32_digits().len());
let y = builder.add_virtual_biguint_target(y_value.to_u32_digits().len());
@ -277,13 +281,17 @@ mod tests {
pw.set_biguint_target(&y, &y_value);
pw.set_biguint_target(&expected_z, &expected_z_value);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}
#[test]
fn test_biguint_sub() -> Result<()> {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type FF = <C as GenericConfig<D>>::FE;
let mut rng = rand::thread_rng();
let mut x_value = BigUint::from_u128(rng.gen()).unwrap();
@ -293,10 +301,9 @@ mod tests {
}
let expected_z_value = &x_value - &y_value;
type F = GoldilocksField;
let config = CircuitConfig::standard_recursion_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut builder = CircuitBuilder::<F, D>::new(config);
let x = builder.constant_biguint(&x_value);
let y = builder.constant_biguint(&y_value);
@ -305,23 +312,26 @@ mod tests {
builder.connect_biguint(&z, &expected_z);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}
#[test]
fn test_biguint_mul() -> Result<()> {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type FF = <C as GenericConfig<D>>::FE;
let mut rng = rand::thread_rng();
let x_value = BigUint::from_u128(rng.gen()).unwrap();
let y_value = BigUint::from_u128(rng.gen()).unwrap();
let expected_z_value = &x_value * &y_value;
type F = GoldilocksField;
let config = CircuitConfig::standard_recursion_config();
let mut pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut builder = CircuitBuilder::<F, D>::new(config);
let x = builder.add_virtual_biguint_target(x_value.to_u32_digits().len());
let y = builder.add_virtual_biguint_target(y_value.to_u32_digits().len());
@ -333,22 +343,25 @@ mod tests {
pw.set_biguint_target(&y, &y_value);
pw.set_biguint_target(&expected_z, &expected_z_value);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}
#[test]
fn test_biguint_cmp() -> Result<()> {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type FF = <C as GenericConfig<D>>::FE;
let mut rng = rand::thread_rng();
let x_value = BigUint::from_u128(rng.gen()).unwrap();
let y_value = BigUint::from_u128(rng.gen()).unwrap();
type F = GoldilocksField;
let config = CircuitConfig::standard_recursion_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut builder = CircuitBuilder::<F, D>::new(config);
let x = builder.constant_biguint(&x_value);
let y = builder.constant_biguint(&y_value);
@ -357,13 +370,17 @@ mod tests {
builder.connect(cmp.target, expected_cmp.target);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}
#[test]
fn test_biguint_div_rem() -> Result<()> {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type FF = <C as GenericConfig<D>>::FE;
let mut rng = rand::thread_rng();
let mut x_value = BigUint::from_u128(rng.gen()).unwrap();
@ -373,10 +390,9 @@ mod tests {
}
let (expected_div_value, expected_rem_value) = x_value.div_rem(&y_value);
type F = GoldilocksField;
let config = CircuitConfig::standard_recursion_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut builder = CircuitBuilder::<F, D>::new(config);
let x = builder.constant_biguint(&x_value);
let y = builder.constant_biguint(&y_value);
@ -388,7 +404,7 @@ mod tests {
builder.connect_biguint(&div, &expected_div);
builder.connect_biguint(&rem, &expected_rem);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}

View File

@ -186,12 +186,15 @@ mod tests {
use crate::iop::witness::PartialWitness;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
use crate::plonk::verifier::verify;
#[test]
fn test_curve_point_is_valid() -> Result<()> {
type F = GoldilocksField;
const D: usize = 4;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type FF = <C as GenericConfig<D>>::FE;
let config = CircuitConfig::standard_recursion_config();
@ -205,7 +208,7 @@ mod tests {
builder.curve_assert_valid(&g_target);
builder.curve_assert_valid(&neg_g_target);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
@ -214,8 +217,10 @@ mod tests {
#[test]
#[should_panic]
fn test_curve_point_is_not_valid() {
type F = GoldilocksField;
const D: usize = 4;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type FF = <C as GenericConfig<D>>::FE;
let config = CircuitConfig::standard_recursion_config();
@ -232,7 +237,7 @@ mod tests {
builder.curve_assert_valid(&not_g_target);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common).unwrap();
@ -240,8 +245,10 @@ mod tests {
#[test]
fn test_curve_double() -> Result<()> {
type F = GoldilocksField;
const D: usize = 4;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type FF = <C as GenericConfig<D>>::FE;
let config = CircuitConfig::standard_recursion_config();
@ -268,7 +275,7 @@ mod tests {
builder.connect_affine_point(&double_g_expected, &double_g_actual);
builder.connect_affine_point(&double_neg_g_expected, &double_neg_g_actual);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
@ -276,8 +283,10 @@ mod tests {
#[test]
fn test_curve_add() -> Result<()> {
type F = GoldilocksField;
const D: usize = 4;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type FF = <C as GenericConfig<D>>::FE;
let config = CircuitConfig::standard_recursion_config();
@ -297,7 +306,7 @@ mod tests {
builder.connect_affine_point(&g_plus_2g_expected, &g_plus_2g_actual);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
@ -306,8 +315,10 @@ mod tests {
#[test]
#[ignore]
fn test_curve_mul() -> Result<()> {
type F = GoldilocksField;
const D: usize = 4;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type FF = <C as GenericConfig<D>>::FE;
let config = CircuitConfig {
num_routed_wires: 33,
@ -331,7 +342,7 @@ mod tests {
builder.connect_affine_point(&five_g_expected, &five_g_actual);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
@ -340,8 +351,10 @@ mod tests {
#[test]
#[ignore]
fn test_curve_random() -> Result<()> {
type F = GoldilocksField;
const D: usize = 4;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type FF = <C as GenericConfig<D>>::FE;
let config = CircuitConfig {
num_routed_wires: 33,
@ -360,7 +373,7 @@ mod tests {
let randot_times_two = builder.curve_scalar_mul(&randot, &two_target);
builder.connect_affine_point(&randot_doubled, &randot_times_two);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)

View File

@ -4,7 +4,6 @@ use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::Extendable;
use crate::field::field_types::RichField;
use crate::gates::gate::Gate;
use crate::gates::interpolation::InterpolationGate;
use crate::iop::target::Target;
use crate::plonk::circuit_builder::CircuitBuilder;
@ -113,6 +112,8 @@ mod tests {
use crate::field::extension_field::FieldExtension;
use crate::field::field_types::Field;
use crate::field::interpolation::interpolant;
use crate::gates::interpolation::HighDegreeInterpolationGate;
use crate::gates::low_degree_interpolation::LowDegreeInterpolationGate;
use crate::iop::witness::PartialWitness;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::CircuitConfig;

View File

@ -76,13 +76,17 @@ mod tests {
use crate::iop::witness::PartialWitness;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
use crate::plonk::verifier::verify;
fn test_list_le(size: usize, num_bits: usize) -> Result<()> {
type F = GoldilocksField;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type FF = <C as GenericConfig<D>>::FE;
let config = CircuitConfig::standard_recursion_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut builder = CircuitBuilder::<F, D>::new(config);
let mut rng = rand::thread_rng();
@ -120,7 +124,7 @@ mod tests {
let expected_result = builder.constant_bool(a_biguint <= b_biguint);
builder.connect(result.target, expected_result.target);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}

View File

@ -219,19 +219,22 @@ mod tests {
use crate::iop::witness::PartialWitness;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
use crate::plonk::verifier::verify;
#[test]
fn test_nonnative_add() -> Result<()> {
type FF = Secp256K1Base;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let x_ff = FF::rand();
let y_ff = FF::rand();
let sum_ff = x_ff + y_ff;
type F = GoldilocksField;
let config = CircuitConfig::standard_recursion_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut builder = CircuitBuilder::<F, D>::new(config);
let x = builder.constant_nonnative(x_ff);
let y = builder.constant_nonnative(y_ff);
@ -240,7 +243,7 @@ mod tests {
let sum_expected = builder.constant_nonnative(sum_ff);
builder.connect_nonnative(&sum, &sum_expected);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}
@ -248,6 +251,9 @@ mod tests {
#[test]
fn test_nonnative_sub() -> Result<()> {
type FF = Secp256K1Base;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let x_ff = FF::rand();
let mut y_ff = FF::rand();
while y_ff.to_biguint() > x_ff.to_biguint() {
@ -255,10 +261,9 @@ mod tests {
}
let diff_ff = x_ff - y_ff;
type F = GoldilocksField;
let config = CircuitConfig::standard_recursion_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut builder = CircuitBuilder::<F, D>::new(config);
let x = builder.constant_nonnative(x_ff);
let y = builder.constant_nonnative(y_ff);
@ -267,7 +272,7 @@ mod tests {
let diff_expected = builder.constant_nonnative(diff_ff);
builder.connect_nonnative(&diff, &diff_expected);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}
@ -275,14 +280,16 @@ mod tests {
#[test]
fn test_nonnative_mul() -> Result<()> {
type FF = Secp256K1Base;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let x_ff = FF::rand();
let y_ff = FF::rand();
let product_ff = x_ff * y_ff;
type F = GoldilocksField;
let config = CircuitConfig::standard_recursion_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut builder = CircuitBuilder::<F, D>::new(config);
let x = builder.constant_nonnative(x_ff);
let y = builder.constant_nonnative(y_ff);
@ -291,7 +298,7 @@ mod tests {
let product_expected = builder.constant_nonnative(product_ff);
builder.connect_nonnative(&product, &product_expected);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}
@ -299,13 +306,15 @@ mod tests {
#[test]
fn test_nonnative_neg() -> Result<()> {
type FF = Secp256K1Base;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let x_ff = FF::rand();
let neg_x_ff = -x_ff;
type F = GoldilocksField;
let config = CircuitConfig::standard_recursion_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut builder = CircuitBuilder::<F, D>::new(config);
let x = builder.constant_nonnative(x_ff);
let neg_x = builder.neg_nonnative(&x);
@ -313,7 +322,7 @@ mod tests {
let neg_x_expected = builder.constant_nonnative(neg_x_ff);
builder.connect_nonnative(&neg_x, &neg_x_expected);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}
@ -321,13 +330,15 @@ mod tests {
#[test]
fn test_nonnative_inv() -> Result<()> {
type FF = Secp256K1Base;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let x_ff = FF::rand();
let inv_x_ff = x_ff.inverse();
type F = GoldilocksField;
let config = CircuitConfig::standard_recursion_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut builder = CircuitBuilder::<F, D>::new(config);
let x = builder.constant_nonnative(x_ff);
let inv_x = builder.inv_nonnative(&x);
@ -335,7 +346,7 @@ mod tests {
let inv_x_expected = builder.constant_nonnative(inv_x_ff);
builder.connect_nonnative(&inv_x, &inv_x_expected);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}

View File

@ -71,7 +71,7 @@ impl<const D: usize> PolynomialCoeffsExtAlgebraTarget<D> {
powers: &[ExtensionAlgebraTarget<D>],
) -> ExtensionAlgebraTarget<D>
where
F: RichField + Extendable<D>,
F: Extendable<D>,
{
debug_assert_eq!(self.0.len(), powers.len() + 1);
let acc = self.0[0];

View File

@ -5,7 +5,6 @@ use itertools::izip;
use crate::field::extension_field::Extendable;
use crate::field::field_types::{Field, RichField};
use crate::gates::assert_le::AssertLessThanGate;
use crate::field::field_types::Field;
use crate::gates::comparison::ComparisonGate;
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
use crate::iop::target::{BoolTarget, Target};

View File

@ -197,6 +197,7 @@ mod tests {
use crate::gates::arithmetic_base::ArithmeticGate;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
#[test]
fn low_degree() {
@ -206,7 +207,10 @@ mod tests {
#[test]
fn eval_fns() -> Result<()> {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let gate = ArithmeticGate::new_from_config(&CircuitConfig::standard_recursion_config());
test_eval_fns::<GoldilocksField, _, 4>(gate)
test_eval_fns::<GoldilocksField, C, _, D>(gate)
}
}

View File

@ -344,7 +344,10 @@ mod tests {
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<GoldilocksField, _, 4>(U32ArithmeticGate::<GoldilocksField, 4> {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
test_eval_fns::<GoldilocksField, C, _, D>(U32ArithmeticGate::<GoldilocksField, D> {
num_ops: 3,
_phantom: PhantomData,
})

View File

@ -439,6 +439,7 @@ mod tests {
use crate::gates::gate::Gate;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::hash::hash_types::HashOut;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
use crate::plonk::vars::EvaluationVars;
#[test]
@ -480,10 +481,14 @@ mod tests {
#[test]
fn eval_fns() -> Result<()> {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let num_bits = 20;
let num_chunks = 4;
test_eval_fns::<GoldilocksField, _, 4>(AssertLessThanGate::<_, 4>::new(
test_eval_fns::<GoldilocksField, C, _, D>(AssertLessThanGate::<_, D>::new(
num_bits, num_chunks,
))
}

View File

@ -227,7 +227,6 @@ mod tests {
use crate::field::goldilocks_field::GoldilocksField;
use crate::gadgets::interpolation::InterpolationGate;
use crate::gates::arithmetic_extension::ArithmeticExtensionGate;
use crate::gates::arithmetic::ArithmeticExtensionGate;
use crate::gates::base_sum::BaseSumGate;
use crate::gates::constant::ConstantGate;
use crate::gates::gmimc::GMiMCGate;

View File

@ -19,7 +19,7 @@ use crate::polynomial::PolynomialCoeffs;
/// Interpolation gate with constraints of degree at most `1<<subgroup_bits`.
/// `eval_unfiltered_recursively` uses less gates than `LowDegreeInterpolationGate`.
#[derive(Copy, Clone, Debug)]
pub(crate) struct HighDegreeInterpolationGate<F: RichField + Extendable<D>, const D: usize> {
pub(crate) struct HighDegreeInterpolationGate<F: Extendable<D>, const D: usize> {
pub subgroup_bits: usize,
_phantom: PhantomData<F>,
}
@ -39,7 +39,7 @@ impl<F: Extendable<D>, const D: usize> InterpolationGate<F, D>
}
}
impl<F: RichField + Extendable<D>, const D: usize> HighDegreeInterpolationGate<F, D> {
impl<F: Extendable<D>, const D: usize> HighDegreeInterpolationGate<F, D> {
/// End of wire indices, exclusive.
fn end(&self) -> usize {
self.start_coeffs() + self.num_points() * D
@ -78,9 +78,7 @@ impl<F: RichField + Extendable<D>, const D: usize> HighDegreeInterpolationGate<F
}
}
impl<F: Extendable<D>, const D: usize> Gate<F, D>
for HighDegreeInterpolationGate<F, D>
{
impl<F: Extendable<D>, const D: usize> Gate<F, D> for HighDegreeInterpolationGate<F, D> {
fn id(&self) -> String {
format!("{:?}<D={}>", self, D)
}

View File

@ -392,6 +392,7 @@ mod tests {
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::gates::low_degree_interpolation::LowDegreeInterpolationGate;
use crate::hash::hash_types::HashOut;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
use crate::plonk::vars::EvaluationVars;
use crate::polynomial::PolynomialCoeffs;
@ -402,7 +403,10 @@ mod tests {
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<GoldilocksField, _, 4>(LowDegreeInterpolationGate::new(4))
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
test_eval_fns::<GoldilocksField, C, _, D>(LowDegreeInterpolationGate::new(4))
}
#[test]

View File

@ -189,6 +189,7 @@ mod tests {
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::gates::multiplication_extension::MulExtensionGate;
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
#[test]
fn low_degree() {
@ -198,7 +199,10 @@ mod tests {
#[test]
fn eval_fns() -> Result<()> {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let gate = MulExtensionGate::new_from_config(&CircuitConfig::standard_recursion_config());
test_eval_fns::<GoldilocksField, _, 4>(gate)
test_eval_fns::<GoldilocksField, C, _, D>(gate)
}
}

View File

@ -46,7 +46,7 @@ impl<F: Extendable<D>, const D: usize> PoseidonGate<F, D> {
/// is useful for ordering hashes in Merkle proofs. Otherwise, this should be set to 0.
pub const WIRE_SWAP: usize = 2 * SPONGE_WIDTH;
const START_DELTA: usize = 2 * WIDTH + 1;
const START_DELTA: usize = 2 * SPONGE_WIDTH + 1;
/// A wire which stores `swap * (input[i + 4] - input[i])`; used to compute the swapped inputs.
fn wire_delta(i: usize) -> usize {
@ -64,11 +64,12 @@ impl<F: Extendable<D>, const D: usize> PoseidonGate<F, D> {
"First round S-box inputs are not stored as wires"
);
debug_assert!(round < poseidon::HALF_N_FULL_ROUNDS);
debug_assert!(i < WIDTH);
Self::START_FULL_0 + WIDTH * (round - 1) + i
debug_assert!(i < SPONGE_WIDTH);
Self::START_FULL_0 + SPONGE_WIDTH * (round - 1) + i
}
const START_PARTIAL: usize = Self::START_FULL_0 + WIDTH * (poseidon::HALF_N_FULL_ROUNDS - 1);
const START_PARTIAL: usize =
Self::START_FULL_0 + SPONGE_WIDTH * (poseidon::HALF_N_FULL_ROUNDS - 1);
/// A wire which stores the input of the S-box of the `round`-th round of the partial rounds.
fn wire_partial_sbox(round: usize) -> usize {
@ -82,23 +83,19 @@ impl<F: Extendable<D>, const D: usize> PoseidonGate<F, D> {
/// of full rounds.
fn wire_full_sbox_1(round: usize, i: usize) -> usize {
debug_assert!(round < poseidon::HALF_N_FULL_ROUNDS);
debug_assert!(i < WIDTH);
Self::START_FULL_1 + WIDTH * round + i
debug_assert!(i < SPONGE_WIDTH);
Self::START_FULL_1 + SPONGE_WIDTH * round + i
}
/// End of wire indices, exclusive.
fn end() -> usize {
Self::START_FULL_1 + WIDTH * poseidon::HALF_N_FULL_ROUNDS
Self::START_FULL_1 + SPONGE_WIDTH * poseidon::HALF_N_FULL_ROUNDS
}
}
impl<F: RichField + Extendable<D> + Poseidon<WIDTH>, const D: usize, const WIDTH: usize> Gate<F, D>
for PoseidonGate<F, D, WIDTH>
where
[(); WIDTH - 1]:,
{
impl<F: Extendable<D>, const D: usize> Gate<F, D> for PoseidonGate<F, D> {
fn id(&self) -> String {
format!("{:?}<WIDTH={}>", self, WIDTH)
format!("{:?}<WIDTH={}>", self, SPONGE_WIDTH)
}
fn eval_unfiltered(&self, vars: EvaluationVars<F, D>) -> Vec<F::Extension> {
@ -117,7 +114,7 @@ where
}
// Compute the possibly-swapped input layer.
let mut state = [F::Extension::ZERO; WIDTH];
let mut state = [F::Extension::ZERO; SPONGE_WIDTH];
for i in 0..4 {
let delta_i = vars.local_wires[Self::wire_delta(i)];
let input_lhs = Self::wire_input(i);
@ -125,7 +122,7 @@ where
state[i] = vars.local_wires[input_lhs] + delta_i;
state[i + 4] = vars.local_wires[input_rhs] - delta_i;
}
for i in 8..WIDTH {
for i in 8..SPONGE_WIDTH {
state[i] = vars.local_wires[Self::wire_input(i)];
}
@ -133,54 +130,51 @@ where
// First set of full rounds.
for r in 0..poseidon::HALF_N_FULL_ROUNDS {
<F as Poseidon<WIDTH>>::constant_layer_field(&mut state, round_ctr);
<F as Poseidon>::constant_layer_field(&mut state, round_ctr);
if r != 0 {
for i in 0..WIDTH {
for i in 0..SPONGE_WIDTH {
let sbox_in = vars.local_wires[Self::wire_full_sbox_0(r, i)];
constraints.push(state[i] - sbox_in);
state[i] = sbox_in;
}
}
<F as Poseidon<WIDTH>>::sbox_layer_field(&mut state);
state = <F as Poseidon<WIDTH>>::mds_layer_field(&state);
<F as Poseidon>::sbox_layer_field(&mut state);
state = <F as Poseidon>::mds_layer_field(&state);
round_ctr += 1;
}
// Partial rounds.
<F as Poseidon<WIDTH>>::partial_first_constant_layer(&mut state);
state = <F as Poseidon<WIDTH>>::mds_partial_layer_init(&state);
<F as Poseidon>::partial_first_constant_layer(&mut state);
state = <F as Poseidon>::mds_partial_layer_init(&state);
for r in 0..(poseidon::N_PARTIAL_ROUNDS - 1) {
let sbox_in = vars.local_wires[Self::wire_partial_sbox(r)];
constraints.push(state[0] - sbox_in);
state[0] = <F as Poseidon<WIDTH>>::sbox_monomial(sbox_in);
state[0] += F::Extension::from_canonical_u64(
<F as Poseidon<WIDTH>>::FAST_PARTIAL_ROUND_CONSTANTS[r],
);
state = <F as Poseidon<WIDTH>>::mds_partial_layer_fast_field(&state, r);
state[0] = <F as Poseidon>::sbox_monomial(sbox_in);
state[0] +=
F::Extension::from_canonical_u64(<F as Poseidon>::FAST_PARTIAL_ROUND_CONSTANTS[r]);
state = <F as Poseidon>::mds_partial_layer_fast_field(&state, r);
}
let sbox_in = vars.local_wires[Self::wire_partial_sbox(poseidon::N_PARTIAL_ROUNDS - 1)];
constraints.push(state[0] - sbox_in);
state[0] = <F as Poseidon<WIDTH>>::sbox_monomial(sbox_in);
state = <F as Poseidon<WIDTH>>::mds_partial_layer_fast_field(
&state,
poseidon::N_PARTIAL_ROUNDS - 1,
);
state[0] = <F as Poseidon>::sbox_monomial(sbox_in);
state =
<F as Poseidon>::mds_partial_layer_fast_field(&state, poseidon::N_PARTIAL_ROUNDS - 1);
round_ctr += poseidon::N_PARTIAL_ROUNDS;
// Second set of full rounds.
for r in 0..poseidon::HALF_N_FULL_ROUNDS {
<F as Poseidon<WIDTH>>::constant_layer_field(&mut state, round_ctr);
for i in 0..WIDTH {
<F as Poseidon>::constant_layer_field(&mut state, round_ctr);
for i in 0..SPONGE_WIDTH {
let sbox_in = vars.local_wires[Self::wire_full_sbox_1(r, i)];
constraints.push(state[i] - sbox_in);
state[i] = sbox_in;
}
<F as Poseidon<WIDTH>>::sbox_layer_field(&mut state);
state = <F as Poseidon<WIDTH>>::mds_layer_field(&state);
<F as Poseidon>::sbox_layer_field(&mut state);
state = <F as Poseidon>::mds_layer_field(&state);
round_ctr += 1;
}
for i in 0..WIDTH {
for i in 0..SPONGE_WIDTH {
constraints.push(state[i] - vars.local_wires[Self::wire_output(i)]);
}
@ -203,7 +197,7 @@ where
}
// Compute the possibly-swapped input layer.
let mut state = [F::ZERO; WIDTH];
let mut state = [F::ZERO; SPONGE_WIDTH];
for i in 0..4 {
let delta_i = vars.local_wires[Self::wire_delta(i)];
let input_lhs = Self::wire_input(i);
@ -211,7 +205,7 @@ where
state[i] = vars.local_wires[input_lhs] + delta_i;
state[i + 4] = vars.local_wires[input_rhs] - delta_i;
}
for i in 8..WIDTH {
for i in 8..SPONGE_WIDTH {
state[i] = vars.local_wires[Self::wire_input(i)];
}
@ -219,51 +213,49 @@ where
// First set of full rounds.
for r in 0..poseidon::HALF_N_FULL_ROUNDS {
<F as Poseidon<WIDTH>>::constant_layer(&mut state, round_ctr);
<F as Poseidon>::constant_layer(&mut state, round_ctr);
if r != 0 {
for i in 0..WIDTH {
for i in 0..SPONGE_WIDTH {
let sbox_in = vars.local_wires[Self::wire_full_sbox_0(r, i)];
constraints.push(state[i] - sbox_in);
state[i] = sbox_in;
}
}
<F as Poseidon<WIDTH>>::sbox_layer(&mut state);
state = <F as Poseidon<WIDTH>>::mds_layer(&state);
<F as Poseidon>::sbox_layer(&mut state);
state = <F as Poseidon>::mds_layer(&state);
round_ctr += 1;
}
// Partial rounds.
<F as Poseidon<WIDTH>>::partial_first_constant_layer(&mut state);
state = <F as Poseidon<WIDTH>>::mds_partial_layer_init(&state);
<F as Poseidon>::partial_first_constant_layer(&mut state);
state = <F as Poseidon>::mds_partial_layer_init(&state);
for r in 0..(poseidon::N_PARTIAL_ROUNDS - 1) {
let sbox_in = vars.local_wires[Self::wire_partial_sbox(r)];
constraints.push(state[0] - sbox_in);
state[0] = <F as Poseidon<WIDTH>>::sbox_monomial(sbox_in);
state[0] +=
F::from_canonical_u64(<F as Poseidon<WIDTH>>::FAST_PARTIAL_ROUND_CONSTANTS[r]);
state = <F as Poseidon<WIDTH>>::mds_partial_layer_fast(&state, r);
state[0] = <F as Poseidon>::sbox_monomial(sbox_in);
state[0] += F::from_canonical_u64(<F as Poseidon>::FAST_PARTIAL_ROUND_CONSTANTS[r]);
state = <F as Poseidon>::mds_partial_layer_fast(&state, r);
}
let sbox_in = vars.local_wires[Self::wire_partial_sbox(poseidon::N_PARTIAL_ROUNDS - 1)];
constraints.push(state[0] - sbox_in);
state[0] = <F as Poseidon<WIDTH>>::sbox_monomial(sbox_in);
state =
<F as Poseidon<WIDTH>>::mds_partial_layer_fast(&state, poseidon::N_PARTIAL_ROUNDS - 1);
state[0] = <F as Poseidon>::sbox_monomial(sbox_in);
state = <F as Poseidon>::mds_partial_layer_fast(&state, poseidon::N_PARTIAL_ROUNDS - 1);
round_ctr += poseidon::N_PARTIAL_ROUNDS;
// Second set of full rounds.
for r in 0..poseidon::HALF_N_FULL_ROUNDS {
<F as Poseidon<WIDTH>>::constant_layer(&mut state, round_ctr);
for i in 0..WIDTH {
<F as Poseidon>::constant_layer(&mut state, round_ctr);
for i in 0..SPONGE_WIDTH {
let sbox_in = vars.local_wires[Self::wire_full_sbox_1(r, i)];
constraints.push(state[i] - sbox_in);
state[i] = sbox_in;
}
<F as Poseidon<WIDTH>>::sbox_layer(&mut state);
state = <F as Poseidon<WIDTH>>::mds_layer(&state);
<F as Poseidon>::sbox_layer(&mut state);
state = <F as Poseidon>::mds_layer(&state);
round_ctr += 1;
}
for i in 0..WIDTH {
for i in 0..SPONGE_WIDTH {
constraints.push(state[i] - vars.local_wires[Self::wire_output(i)]);
}
@ -277,7 +269,7 @@ where
) -> Vec<ExtensionTarget<D>> {
// The naive method is more efficient if we have enough routed wires for PoseidonMdsGate.
let use_mds_gate =
builder.config.num_routed_wires >= PoseidonMdsGate::<F, D, WIDTH>::new().num_wires();
builder.config.num_routed_wires >= PoseidonMdsGate::<F, D>::new().num_wires();
let mut constraints = Vec::with_capacity(self.num_constraints());
@ -295,7 +287,7 @@ where
}
// Compute the possibly-swapped input layer.
let mut state = [builder.zero_extension(); WIDTH];
let mut state = [builder.zero_extension(); SPONGE_WIDTH];
for i in 0..4 {
let delta_i = vars.local_wires[Self::wire_delta(i)];
let input_lhs = vars.local_wires[Self::wire_input(i)];
@ -303,7 +295,7 @@ where
state[i] = builder.add_extension(input_lhs, delta_i);
state[i + 4] = builder.sub_extension(input_rhs, delta_i);
}
for i in 8..WIDTH {
for i in 8..SPONGE_WIDTH {
state[i] = vars.local_wires[Self::wire_input(i)];
}
@ -311,47 +303,46 @@ where
// First set of full rounds.
for r in 0..poseidon::HALF_N_FULL_ROUNDS {
<F as Poseidon<WIDTH>>::constant_layer_recursive(builder, &mut state, round_ctr);
<F as Poseidon>::constant_layer_recursive(builder, &mut state, round_ctr);
if r != 0 {
for i in 0..WIDTH {
for i in 0..SPONGE_WIDTH {
let sbox_in = vars.local_wires[Self::wire_full_sbox_0(r, i)];
constraints.push(builder.sub_extension(state[i], sbox_in));
state[i] = sbox_in;
}
}
<F as Poseidon<WIDTH>>::sbox_layer_recursive(builder, &mut state);
state = <F as Poseidon<WIDTH>>::mds_layer_recursive(builder, &state);
<F as Poseidon>::sbox_layer_recursive(builder, &mut state);
state = <F as Poseidon>::mds_layer_recursive(builder, &state);
round_ctr += 1;
}
// Partial rounds.
if use_mds_gate {
for r in 0..poseidon::N_PARTIAL_ROUNDS {
<F as Poseidon<WIDTH>>::constant_layer_recursive(builder, &mut state, round_ctr);
<F as Poseidon>::constant_layer_recursive(builder, &mut state, round_ctr);
let sbox_in = vars.local_wires[Self::wire_partial_sbox(r)];
constraints.push(builder.sub_extension(state[0], sbox_in));
state[0] = <F as Poseidon<WIDTH>>::sbox_monomial_recursive(builder, sbox_in);
state = <F as Poseidon<WIDTH>>::mds_layer_recursive(builder, &state);
state[0] = <F as Poseidon>::sbox_monomial_recursive(builder, sbox_in);
state = <F as Poseidon>::mds_layer_recursive(builder, &state);
round_ctr += 1;
}
} else {
<F as Poseidon<WIDTH>>::partial_first_constant_layer_recursive(builder, &mut state);
state = <F as Poseidon<WIDTH>>::mds_partial_layer_init_recursive(builder, &state);
<F as Poseidon>::partial_first_constant_layer_recursive(builder, &mut state);
state = <F as Poseidon>::mds_partial_layer_init_recursive(builder, &state);
for r in 0..(poseidon::N_PARTIAL_ROUNDS - 1) {
let sbox_in = vars.local_wires[Self::wire_partial_sbox(r)];
constraints.push(builder.sub_extension(state[0], sbox_in));
state[0] = <F as Poseidon<WIDTH>>::sbox_monomial_recursive(builder, sbox_in);
let c = <F as Poseidon<WIDTH>>::FAST_PARTIAL_ROUND_CONSTANTS[r];
state[0] = <F as Poseidon>::sbox_monomial_recursive(builder, sbox_in);
let c = <F as Poseidon>::FAST_PARTIAL_ROUND_CONSTANTS[r];
let c = F::Extension::from_canonical_u64(c);
let c = builder.constant_extension(c);
state[0] = builder.add_extension(state[0], c);
state =
<F as Poseidon<WIDTH>>::mds_partial_layer_fast_recursive(builder, &state, r);
state = <F as Poseidon>::mds_partial_layer_fast_recursive(builder, &state, r);
}
let sbox_in = vars.local_wires[Self::wire_partial_sbox(poseidon::N_PARTIAL_ROUNDS - 1)];
constraints.push(builder.sub_extension(state[0], sbox_in));
state[0] = <F as Poseidon<WIDTH>>::sbox_monomial_recursive(builder, sbox_in);
state = <F as Poseidon<WIDTH>>::mds_partial_layer_fast_recursive(
state[0] = <F as Poseidon>::sbox_monomial_recursive(builder, sbox_in);
state = <F as Poseidon>::mds_partial_layer_fast_recursive(
builder,
&state,
poseidon::N_PARTIAL_ROUNDS - 1,
@ -361,18 +352,18 @@ where
// Second set of full rounds.
for r in 0..poseidon::HALF_N_FULL_ROUNDS {
<F as Poseidon<WIDTH>>::constant_layer_recursive(builder, &mut state, round_ctr);
for i in 0..WIDTH {
<F as Poseidon>::constant_layer_recursive(builder, &mut state, round_ctr);
for i in 0..SPONGE_WIDTH {
let sbox_in = vars.local_wires[Self::wire_full_sbox_1(r, i)];
constraints.push(builder.sub_extension(state[i], sbox_in));
state[i] = sbox_in;
}
<F as Poseidon<WIDTH>>::sbox_layer_recursive(builder, &mut state);
state = <F as Poseidon<WIDTH>>::mds_layer_recursive(builder, &state);
<F as Poseidon>::sbox_layer_recursive(builder, &mut state);
state = <F as Poseidon>::mds_layer_recursive(builder, &state);
round_ctr += 1;
}
for i in 0..WIDTH {
for i in 0..SPONGE_WIDTH {
constraints
.push(builder.sub_extension(state[i], vars.local_wires[Self::wire_output(i)]));
}
@ -385,7 +376,7 @@ where
gate_index: usize,
_local_constants: &[F],
) -> Vec<Box<dyn WitnessGenerator<F>>> {
let gen = PoseidonGenerator::<F, D, WIDTH> {
let gen = PoseidonGenerator::<F, D> {
gate_index,
_phantom: PhantomData,
};
@ -405,31 +396,27 @@ where
}
fn num_constraints(&self) -> usize {
WIDTH * (poseidon::N_FULL_ROUNDS_TOTAL - 1) + poseidon::N_PARTIAL_ROUNDS + WIDTH + 1 + 4
SPONGE_WIDTH * (poseidon::N_FULL_ROUNDS_TOTAL - 1)
+ poseidon::N_PARTIAL_ROUNDS
+ SPONGE_WIDTH
+ 1
+ 4
}
}
#[derive(Debug)]
struct PoseidonGenerator<
F: RichField + Extendable<D> + Poseidon<WIDTH>,
const D: usize,
const WIDTH: usize,
> where
[(); WIDTH - 1]:,
{
struct PoseidonGenerator<F: RichField + Extendable<D> + Poseidon, const D: usize> {
gate_index: usize,
_phantom: PhantomData<F>,
}
impl<F: RichField + Extendable<D> + Poseidon<WIDTH>, const D: usize, const WIDTH: usize>
SimpleGenerator<F> for PoseidonGenerator<F, D, WIDTH>
where
[(); WIDTH - 1]:,
impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F>
for PoseidonGenerator<F, D>
{
fn dependencies(&self) -> Vec<Target> {
(0..WIDTH)
.map(|i| PoseidonGate::<F, D, WIDTH>::wire_input(i))
.chain(Some(PoseidonGate::<F, D, WIDTH>::WIRE_SWAP))
(0..SPONGE_WIDTH)
.map(|i| PoseidonGate::<F, D>::wire_input(i))
.chain(Some(PoseidonGate::<F, D>::WIRE_SWAP))
.map(|input| Target::wire(self.gate_index, input))
.collect()
}
@ -440,19 +427,16 @@ where
input,
};
let mut state = (0..WIDTH)
.map(|i| witness.get_wire(local_wire(PoseidonGate::<F, D, WIDTH>::wire_input(i))))
let mut state = (0..SPONGE_WIDTH)
.map(|i| witness.get_wire(local_wire(PoseidonGate::<F, D>::wire_input(i))))
.collect::<Vec<_>>();
let swap_value = witness.get_wire(local_wire(PoseidonGate::<F, D, WIDTH>::WIRE_SWAP));
let swap_value = witness.get_wire(local_wire(PoseidonGate::<F, D>::WIRE_SWAP));
debug_assert!(swap_value == F::ZERO || swap_value == F::ONE);
for i in 0..4 {
let delta_i = swap_value * (state[i + 4] - state[i]);
out_buffer.set_wire(
local_wire(PoseidonGate::<F, D, WIDTH>::wire_delta(i)),
delta_i,
);
out_buffer.set_wire(local_wire(PoseidonGate::<F, D>::wire_delta(i)), delta_i);
}
if swap_value == F::ONE {
@ -461,67 +445,61 @@ where
}
}
let mut state: [F; WIDTH] = state.try_into().unwrap();
let mut state: [F; SPONGE_WIDTH] = state.try_into().unwrap();
let mut round_ctr = 0;
for r in 0..poseidon::HALF_N_FULL_ROUNDS {
<F as Poseidon<WIDTH>>::constant_layer_field(&mut state, round_ctr);
<F as Poseidon>::constant_layer_field(&mut state, round_ctr);
if r != 0 {
for i in 0..WIDTH {
for i in 0..SPONGE_WIDTH {
out_buffer.set_wire(
local_wire(PoseidonGate::<F, D, WIDTH>::wire_full_sbox_0(r, i)),
local_wire(PoseidonGate::<F, D>::wire_full_sbox_0(r, i)),
state[i],
);
}
}
<F as Poseidon<WIDTH>>::sbox_layer_field(&mut state);
state = <F as Poseidon<WIDTH>>::mds_layer_field(&state);
<F as Poseidon>::sbox_layer_field(&mut state);
state = <F as Poseidon>::mds_layer_field(&state);
round_ctr += 1;
}
<F as Poseidon<WIDTH>>::partial_first_constant_layer(&mut state);
state = <F as Poseidon<WIDTH>>::mds_partial_layer_init(&state);
<F as Poseidon>::partial_first_constant_layer(&mut state);
state = <F as Poseidon>::mds_partial_layer_init(&state);
for r in 0..(poseidon::N_PARTIAL_ROUNDS - 1) {
out_buffer.set_wire(
local_wire(PoseidonGate::<F, D, WIDTH>::wire_partial_sbox(r)),
local_wire(PoseidonGate::<F, D>::wire_partial_sbox(r)),
state[0],
);
state[0] = <F as Poseidon<WIDTH>>::sbox_monomial(state[0]);
state[0] +=
F::from_canonical_u64(<F as Poseidon<WIDTH>>::FAST_PARTIAL_ROUND_CONSTANTS[r]);
state = <F as Poseidon<WIDTH>>::mds_partial_layer_fast_field(&state, r);
state[0] = <F as Poseidon>::sbox_monomial(state[0]);
state[0] += F::from_canonical_u64(<F as Poseidon>::FAST_PARTIAL_ROUND_CONSTANTS[r]);
state = <F as Poseidon>::mds_partial_layer_fast_field(&state, r);
}
out_buffer.set_wire(
local_wire(PoseidonGate::<F, D, WIDTH>::wire_partial_sbox(
local_wire(PoseidonGate::<F, D>::wire_partial_sbox(
poseidon::N_PARTIAL_ROUNDS - 1,
)),
state[0],
);
state[0] = <F as Poseidon<WIDTH>>::sbox_monomial(state[0]);
state = <F as Poseidon<WIDTH>>::mds_partial_layer_fast_field(
&state,
poseidon::N_PARTIAL_ROUNDS - 1,
);
state[0] = <F as Poseidon>::sbox_monomial(state[0]);
state =
<F as Poseidon>::mds_partial_layer_fast_field(&state, poseidon::N_PARTIAL_ROUNDS - 1);
round_ctr += poseidon::N_PARTIAL_ROUNDS;
for r in 0..poseidon::HALF_N_FULL_ROUNDS {
<F as Poseidon<WIDTH>>::constant_layer_field(&mut state, round_ctr);
for i in 0..WIDTH {
<F as Poseidon>::constant_layer_field(&mut state, round_ctr);
for i in 0..SPONGE_WIDTH {
out_buffer.set_wire(
local_wire(PoseidonGate::<F, D, WIDTH>::wire_full_sbox_1(r, i)),
local_wire(PoseidonGate::<F, D>::wire_full_sbox_1(r, i)),
state[i],
);
}
<F as Poseidon<WIDTH>>::sbox_layer_field(&mut state);
state = <F as Poseidon<WIDTH>>::mds_layer_field(&state);
<F as Poseidon>::sbox_layer_field(&mut state);
state = <F as Poseidon>::mds_layer_field(&state);
round_ctr += 1;
}
for i in 0..WIDTH {
out_buffer.set_wire(
local_wire(PoseidonGate::<F, D, WIDTH>::wire_output(i)),
state[i],
);
for i in 0..SPONGE_WIDTH {
out_buffer.set_wire(local_wire(PoseidonGate::<F, D>::wire_output(i)), state[i]);
}
}
}
@ -546,8 +524,7 @@ mod tests {
#[test]
fn wire_indices() {
type F = GoldilocksField;
const WIDTH: usize = 12;
type Gate = PoseidonGate<F, 4, WIDTH>;
type Gate = PoseidonGate<F, 4>;
assert_eq!(Gate::wire_input(0), 0);
assert_eq!(Gate::wire_input(11), 11);

View File

@ -7,6 +7,7 @@ use crate::field::extension_field::Extendable;
use crate::field::extension_field::FieldExtension;
use crate::field::field_types::{Field, RichField};
use crate::gates::gate::Gate;
use crate::hash::hashing::SPONGE_WIDTH;
use crate::hash::poseidon::Poseidon;
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
use crate::iop::target::Target;
@ -15,21 +16,11 @@ use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
#[derive(Debug)]
pub struct PoseidonMdsGate<
F: RichField + Extendable<D> + Poseidon<WIDTH>,
const D: usize,
const WIDTH: usize,
> where
[(); WIDTH - 1]:,
{
pub struct PoseidonMdsGate<F: RichField + Extendable<D> + Poseidon, const D: usize> {
_phantom: PhantomData<F>,
}
impl<F: RichField + Extendable<D> + Poseidon<WIDTH>, const D: usize, const WIDTH: usize>
PoseidonMdsGate<F, D, WIDTH>
where
[(); WIDTH - 1]:,
{
impl<F: RichField + Extendable<D> + Poseidon, const D: usize> PoseidonMdsGate<F, D> {
pub fn new() -> Self {
PoseidonMdsGate {
_phantom: PhantomData,
@ -37,13 +28,13 @@ where
}
pub fn wires_input(i: usize) -> Range<usize> {
assert!(i < WIDTH);
assert!(i < SPONGE_WIDTH);
i * D..(i + 1) * D
}
pub fn wires_output(i: usize) -> Range<usize> {
assert!(i < WIDTH);
(WIDTH + i) * D..(WIDTH + i + 1) * D
assert!(i < SPONGE_WIDTH);
(SPONGE_WIDTH + i) * D..(SPONGE_WIDTH + i + 1) * D
}
// Following are methods analogous to ones in `Poseidon`, but for extension algebras.
@ -51,15 +42,14 @@ where
/// Same as `mds_row_shf` for an extension algebra of `F`.
fn mds_row_shf_algebra(
r: usize,
v: &[ExtensionAlgebra<F::Extension, D>; WIDTH],
v: &[ExtensionAlgebra<F::Extension, D>; SPONGE_WIDTH],
) -> ExtensionAlgebra<F::Extension, D> {
debug_assert!(r < WIDTH);
debug_assert!(r < SPONGE_WIDTH);
let mut res = ExtensionAlgebra::ZERO;
for i in 0..WIDTH {
let coeff =
F::Extension::from_canonical_u64(1 << <F as Poseidon<WIDTH>>::MDS_MATRIX_EXPS[i]);
res += v[(i + r) % WIDTH].scalar_mul(coeff);
for i in 0..SPONGE_WIDTH {
let coeff = F::Extension::from_canonical_u64(1 << <F as Poseidon>::MDS_MATRIX_EXPS[i]);
res += v[(i + r) % SPONGE_WIDTH].scalar_mul(coeff);
}
res
@ -69,16 +59,16 @@ where
fn mds_row_shf_algebra_recursive(
builder: &mut CircuitBuilder<F, D>,
r: usize,
v: &[ExtensionAlgebraTarget<D>; WIDTH],
v: &[ExtensionAlgebraTarget<D>; SPONGE_WIDTH],
) -> ExtensionAlgebraTarget<D> {
debug_assert!(r < WIDTH);
debug_assert!(r < SPONGE_WIDTH);
let mut res = builder.zero_ext_algebra();
for i in 0..WIDTH {
for i in 0..SPONGE_WIDTH {
let coeff = builder.constant_extension(F::Extension::from_canonical_u64(
1 << <F as Poseidon<WIDTH>>::MDS_MATRIX_EXPS[i],
1 << <F as Poseidon>::MDS_MATRIX_EXPS[i],
));
res = builder.scalar_mul_add_ext_algebra(coeff, v[(i + r) % WIDTH], res);
res = builder.scalar_mul_add_ext_algebra(coeff, v[(i + r) % SPONGE_WIDTH], res);
}
res
@ -86,11 +76,11 @@ where
/// Same as `mds_layer` for an extension algebra of `F`.
fn mds_layer_algebra(
state: &[ExtensionAlgebra<F::Extension, D>; WIDTH],
) -> [ExtensionAlgebra<F::Extension, D>; WIDTH] {
let mut result = [ExtensionAlgebra::ZERO; WIDTH];
state: &[ExtensionAlgebra<F::Extension, D>; SPONGE_WIDTH],
) -> [ExtensionAlgebra<F::Extension, D>; SPONGE_WIDTH] {
let mut result = [ExtensionAlgebra::ZERO; SPONGE_WIDTH];
for r in 0..WIDTH {
for r in 0..SPONGE_WIDTH {
result[r] = Self::mds_row_shf_algebra(r, state);
}
@ -100,11 +90,11 @@ where
/// Same as `mds_layer_recursive` for an extension algebra of `F`.
fn mds_layer_algebra_recursive(
builder: &mut CircuitBuilder<F, D>,
state: &[ExtensionAlgebraTarget<D>; WIDTH],
) -> [ExtensionAlgebraTarget<D>; WIDTH] {
let mut result = [builder.zero_ext_algebra(); WIDTH];
state: &[ExtensionAlgebraTarget<D>; SPONGE_WIDTH],
) -> [ExtensionAlgebraTarget<D>; SPONGE_WIDTH] {
let mut result = [builder.zero_ext_algebra(); SPONGE_WIDTH];
for r in 0..WIDTH {
for r in 0..SPONGE_WIDTH {
result[r] = Self::mds_row_shf_algebra_recursive(builder, r, state);
}
@ -112,17 +102,13 @@ where
}
}
impl<F: RichField + Extendable<D> + Poseidon<WIDTH>, const D: usize, const WIDTH: usize> Gate<F, D>
for PoseidonMdsGate<F, D, WIDTH>
where
[(); WIDTH - 1]:,
{
impl<F: RichField + Extendable<D> + Poseidon, const D: usize> Gate<F, D> for PoseidonMdsGate<F, D> {
fn id(&self) -> String {
format!("{:?}<WIDTH={}>", self, WIDTH)
format!("{:?}<WIDTH={}>", self, SPONGE_WIDTH)
}
fn eval_unfiltered(&self, vars: EvaluationVars<F, D>) -> Vec<F::Extension> {
let inputs: [_; WIDTH] = (0..WIDTH)
let inputs: [_; SPONGE_WIDTH] = (0..SPONGE_WIDTH)
.map(|i| vars.get_local_ext_algebra(Self::wires_input(i)))
.collect::<Vec<_>>()
.try_into()
@ -130,7 +116,7 @@ where
let computed_outputs = Self::mds_layer_algebra(&inputs);
(0..WIDTH)
(0..SPONGE_WIDTH)
.map(|i| vars.get_local_ext_algebra(Self::wires_output(i)))
.zip(computed_outputs)
.flat_map(|(out, computed_out)| (out - computed_out).to_basefield_array())
@ -138,7 +124,7 @@ where
}
fn eval_unfiltered_base(&self, vars: EvaluationVarsBase<F>) -> Vec<F> {
let inputs: [_; WIDTH] = (0..WIDTH)
let inputs: [_; SPONGE_WIDTH] = (0..SPONGE_WIDTH)
.map(|i| vars.get_local_ext(Self::wires_input(i)))
.collect::<Vec<_>>()
.try_into()
@ -146,7 +132,7 @@ where
let computed_outputs = F::mds_layer_field(&inputs);
(0..WIDTH)
(0..SPONGE_WIDTH)
.map(|i| vars.get_local_ext(Self::wires_output(i)))
.zip(computed_outputs)
.flat_map(|(out, computed_out)| (out - computed_out).to_basefield_array())
@ -158,7 +144,7 @@ where
builder: &mut CircuitBuilder<F, D>,
vars: EvaluationTargets<D>,
) -> Vec<ExtensionTarget<D>> {
let inputs: [_; WIDTH] = (0..WIDTH)
let inputs: [_; SPONGE_WIDTH] = (0..SPONGE_WIDTH)
.map(|i| vars.get_local_ext_algebra(Self::wires_input(i)))
.collect::<Vec<_>>()
.try_into()
@ -166,7 +152,7 @@ where
let computed_outputs = Self::mds_layer_algebra_recursive(builder, &inputs);
(0..WIDTH)
(0..SPONGE_WIDTH)
.map(|i| vars.get_local_ext_algebra(Self::wires_output(i)))
.zip(computed_outputs)
.flat_map(|(out, computed_out)| {
@ -182,12 +168,12 @@ where
gate_index: usize,
_local_constants: &[F],
) -> Vec<Box<dyn WitnessGenerator<F>>> {
let gen = PoseidonMdsGenerator::<D, WIDTH> { gate_index };
let gen = PoseidonMdsGenerator::<D> { gate_index };
vec![Box::new(gen.adapter())]
}
fn num_wires(&self) -> usize {
2 * D * WIDTH
2 * D * SPONGE_WIDTH
}
fn num_constants(&self) -> usize {
@ -199,30 +185,22 @@ where
}
fn num_constraints(&self) -> usize {
WIDTH * D
SPONGE_WIDTH * D
}
}
#[derive(Clone, Debug)]
struct PoseidonMdsGenerator<const D: usize, const WIDTH: usize>
where
[(); WIDTH - 1]:,
{
struct PoseidonMdsGenerator<const D: usize> {
gate_index: usize,
}
impl<F: RichField + Extendable<D> + Poseidon<WIDTH>, const D: usize, const WIDTH: usize>
SimpleGenerator<F> for PoseidonMdsGenerator<D, WIDTH>
where
[(); WIDTH - 1]:,
impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F>
for PoseidonMdsGenerator<D>
{
fn dependencies(&self) -> Vec<Target> {
(0..WIDTH)
(0..SPONGE_WIDTH)
.flat_map(|i| {
Target::wires_from_range(
self.gate_index,
PoseidonMdsGate::<F, D, WIDTH>::wires_input(i),
)
Target::wires_from_range(self.gate_index, PoseidonMdsGate::<F, D>::wires_input(i))
})
.collect()
}
@ -233,8 +211,8 @@ where
let get_local_ext =
|wire_range| witness.get_extension_target(get_local_get_target(wire_range));
let inputs: [_; WIDTH] = (0..WIDTH)
.map(|i| get_local_ext(PoseidonMdsGate::<F, D, WIDTH>::wires_input(i)))
let inputs: [_; SPONGE_WIDTH] = (0..SPONGE_WIDTH)
.map(|i| get_local_ext(PoseidonMdsGate::<F, D>::wires_input(i)))
.collect::<Vec<_>>()
.try_into()
.unwrap();
@ -243,7 +221,7 @@ where
for (i, &out) in outputs.iter().enumerate() {
out_buffer.set_extension_target(
get_local_get_target(PoseidonMdsGate::<F, D, WIDTH>::wires_output(i)),
get_local_get_target(PoseidonMdsGate::<F, D>::wires_output(i)),
out,
);
}
@ -256,18 +234,23 @@ mod tests {
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::gates::poseidon_mds::PoseidonMdsGate;
use crate::hash::hashing::SPONGE_WIDTH;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
#[test]
fn low_degree() {
type F = GoldilocksField;
let gate = PoseidonMdsGate::<F, 4, SPONGE_WIDTH>::new();
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let gate = PoseidonMdsGate::<F, D>::new();
test_low_degree(gate)
}
#[test]
fn eval_fns() -> anyhow::Result<()> {
type F = GoldilocksField;
let gate = PoseidonMdsGate::<F, 4, SPONGE_WIDTH>::new();
test_eval_fns(gate)
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let gate = PoseidonMdsGate::<F, D>::new();
test_eval_fns::<F, C, _, D>(gate)
}
}

View File

@ -16,13 +16,13 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
/// A gate for checking that a particular element of a list matches a given value.
#[derive(Copy, Clone, Debug)]
pub(crate) struct RandomAccessGate<F: Extendable<D>, const D: usize> {
pub(crate) struct RandomAccessGate<F: Extendable<D>, const D: usize> {
pub bits: usize,
pub num_copies: usize,
_phantom: PhantomData<F>,
}
impl<F: Extendable<D>, const D: usize> RandomAccessGate<F, D> {
impl<F: Extendable<D>, const D: usize> RandomAccessGate<F, D> {
fn new(num_copies: usize, bits: usize) -> Self {
Self {
bits,

View File

@ -209,6 +209,7 @@ mod tests {
use crate::field::goldilocks_field::GoldilocksField;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::gates::reducing_extension::ReducingExtensionGate;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
#[test]
fn low_degree() {
@ -217,6 +218,9 @@ mod tests {
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<GoldilocksField, _, 4>(ReducingExtensionGate::new(22))
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
test_eval_fns::<GoldilocksField, C, _, D>(ReducingExtensionGate::new(22))
}
}

View File

@ -321,6 +321,7 @@ mod tests {
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::gates::subtraction_u32::U32SubtractionGate;
use crate::hash::hash_types::HashOut;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
use crate::plonk::vars::EvaluationVars;
#[test]
@ -333,7 +334,10 @@ mod tests {
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<GoldilocksField, _, 4>(U32SubtractionGate::<GoldilocksField, 4> {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
test_eval_fns::<GoldilocksField, C, _, D>(U32SubtractionGate::<GoldilocksField, D> {
num_ops: 3,
_phantom: PhantomData,
})

View File

@ -53,7 +53,7 @@ const fn check_mds_matrix() -> bool {
let mut i = 0;
let wanted_matrix_exps = [0, 0, 1, 0, 3, 5, 1, 8, 12, 3, 16, 10];
while i < WIDTH {
if <GoldilocksField as Poseidon<12>>::MDS_MATRIX_EXPS[i] != wanted_matrix_exps[i] {
if <GoldilocksField as Poseidon>::MDS_MATRIX_EXPS[i] != wanted_matrix_exps[i] {
return false;
}
i += 1;
@ -68,7 +68,7 @@ const fn mds_matrix_inf_norm() -> u64 {
let mut cumul = 0;
let mut i = 0;
while i < WIDTH {
cumul += 1 << <GoldilocksField as Poseidon<12>>::MDS_MATRIX_EXPS[i];
cumul += 1 << <GoldilocksField as Poseidon>::MDS_MATRIX_EXPS[i];
i += 1;
}
cumul

View File

@ -130,7 +130,7 @@ pub fn hash_n_to_m<F: RichField, P: PlonkyPermutation<F>>(
// Absorb all input chunks.
for input_chunk in inputs.chunks(SPONGE_RATE) {
state[..input_chunk.len()].copy_from_slice(input_chunk);
state = permute(state);
state = P::permute(state);
}
// Squeeze until we have the desired number of outputs.

View File

@ -93,7 +93,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
proof: &MerkleProofTarget,
) {
let zero = self.zero();
let mut state:HashOutTarget = self.hash_or_noop(leaf_data);
let mut state: HashOutTarget = self.hash_or_noop::<H>(leaf_data);
for (&bit, &sibling) in leaf_index_bits.iter().zip(&proof.siblings) {
let mut perm_inputs = [zero; SPONGE_WIDTH];

View File

@ -450,7 +450,7 @@ pub trait Poseidon: PrimeField {
s0,
);
for i in 1..WIDTH {
let t = <Self as Poseidon<WIDTH>>::FAST_PARTIAL_ROUND_W_HATS[r][i - 1];
let t = <Self as Poseidon>::FAST_PARTIAL_ROUND_W_HATS[r][i - 1];
let t = Self::Extension::from_canonical_u64(t);
let t = builder.constant_extension(t);
d = builder.mul_add_extension(t, state[i], d);

View File

@ -1,7 +1,7 @@
use crate::field::extension_field::target::ExtensionTarget;
use std::convert::TryInto;
use std::marker::PhantomData;
use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::{Extendable, FieldExtension};
use crate::field::field_types::RichField;
use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget};

View File

@ -6,7 +6,6 @@ use num::BigUint;
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, RichField};
use crate::gadgets::arithmetic_u32::U32Target;
use crate::gadgets::biguint::BigUintTarget;
use crate::gadgets::nonnative::NonNativeTarget;

View File

@ -5,7 +5,6 @@ use num::{BigUint, FromPrimitive, Zero};
use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::{Extendable, FieldExtension};
use crate::field::field_types::{Field, RichField};
use crate::field::field_types::Field;
use crate::gadgets::arithmetic_u32::U32Target;
use crate::gadgets::biguint::BigUintTarget;
use crate::gadgets::nonnative::NonNativeTarget;

View File

@ -765,7 +765,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
/// Various gate types can contain multiple copies in a single Gate. This helper struct lets a
/// CircuitBuilder track such gates that are currently being "filled up."
pub struct BatchedGates<F: RichField + Extendable<D>, const D: usize> {
pub struct BatchedGates<F: Extendable<D>, const D: usize> {
/// A map `(c0, c1) -> (g, i)` from constants `(c0,c1)` to an available arithmetic gate using
/// these constants with gate index `g` and already using `i` arithmetic operations.
pub(crate) free_arithmetic: HashMap<(F, F), (usize, usize)>,
@ -792,7 +792,7 @@ pub struct BatchedGates<F: RichField + Extendable<D>, const D: usize> {
pub(crate) free_constant: Option<(usize, usize)>,
}
impl<F: RichField + Extendable<D>, const D: usize> BatchedGates<F, D> {
impl<F: Extendable<D>, const D: usize> BatchedGates<F, D> {
pub fn new() -> Self {
Self {
free_arithmetic: HashMap::new(),
@ -807,7 +807,7 @@ impl<F: RichField + Extendable<D>, const D: usize> BatchedGates<F, D> {
}
}
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
impl<F: 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.

View File

@ -15,7 +15,6 @@ use crate::iop::generator::WitnessGenerator;
use crate::iop::target::Target;
use crate::iop::witness::PartialWitness;
use crate::plonk::config::{GenericConfig, Hasher};
use crate::plonk::proof::ProofWithPublicInputs;
use crate::plonk::proof::{CompressedProofWithPublicInputs, ProofWithPublicInputs};
use crate::plonk::prover::prove;
use crate::plonk::verifier::verify;
@ -108,7 +107,7 @@ impl<F: Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> CircuitData<F
pub fn verify_compressed(
&self,
compressed_proof_with_pis: CompressedProofWithPublicInputs<F, D>,
compressed_proof_with_pis: CompressedProofWithPublicInputs<F, C, D>,
) -> Result<()> {
compressed_proof_with_pis.verify(&self.verifier_only, &self.common)
}
@ -151,7 +150,7 @@ impl<F: Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> VerifierCircu
pub fn verify_compressed(
&self,
compressed_proof_with_pis: CompressedProofWithPublicInputs<F, D>,
compressed_proof_with_pis: CompressedProofWithPublicInputs<F, C, D>,
) -> Result<()> {
compressed_proof_with_pis.verify(&self.verifier_only, &self.common)
}

View File

@ -370,8 +370,9 @@ mod tests {
type F = <C as GenericConfig<D>>::F;
let config = CircuitConfig::standard_recursion_config();
let (proof, vd, cd) = dummy_proof::<F,C, D>(&config, 4_000)?;
let (proof, _vd, cd) = recursive_proof::<F,C,C,D>(proof, vd, cd, &config, &config, None, true, true)?;
let (proof, vd, cd) = dummy_proof::<F, C, D>(&config, 4_000)?;
let (proof, _vd, cd) =
recursive_proof::<F, C, C, D>(proof, vd, cd, &config, &config, None, true, true)?;
test_serialization(&proof, &cd)?;
Ok(())
@ -389,12 +390,13 @@ mod tests {
let config = CircuitConfig::standard_recursion_config();
// Start with a degree 2^14 proof, then shrink it to 2^13, then to 2^12.
let (proof, vd, cd) = dummy_proof::<F,C, D>(&config, 16_000)?;
let (proof, vd, cd) = dummy_proof::<F, C, D>(&config, 16_000)?;
assert_eq!(cd.degree_bits, 14);
let (proof, vd, cd) =
recursive_proof::<F,C,C,D>(proof, vd, cd, &config, &config, Some(13), false, false)?;
recursive_proof::<F, C, C, D>(proof, vd, cd, &config, &config, Some(13), false, false)?;
assert_eq!(cd.degree_bits, 13);
let (proof, _vd, cd) = recursive_proof::<F,KC,C,D>(proof, vd, cd, &config, &config, None, true, true)?;
let (proof, _vd, cd) =
recursive_proof::<F, KC, C, D>(proof, vd, cd, &config, &config, None, true, true)?;
assert_eq!(cd.degree_bits, 12);
test_serialization(&proof, &cd)?;
@ -416,7 +418,7 @@ mod tests {
let standard_config = CircuitConfig::standard_recursion_config();
// An initial dummy proof.
let (proof, vd, cd) = dummy_proof::<F,C, D>(&standard_config, 4_000)?;
let (proof, vd, cd) = dummy_proof::<F, C, D>(&standard_config, 4_000)?;
assert_eq!(cd.degree_bits, 12);
// A standard recursive proof.

View File

@ -2,9 +2,8 @@ use std::borrow::Borrow;
use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::Extendable;
use crate::field::field_types::{Field, RichField};
use crate::gates::arithmetic_extension::ArithmeticExtensionGate;
use crate::field::field_types::Field;
use crate::gates::arithmetic_extension::ArithmeticExtensionGate;
use crate::gates::reducing::ReducingGate;
use crate::gates::reducing_extension::ReducingExtensionGate;
use crate::iop::target::Target;
@ -218,7 +217,7 @@ impl<const D: usize> ReducingFactorTarget<D> {
builder: &mut CircuitBuilder<F, D>,
) -> ExtensionTarget<D>
where
F: RichField + Extendable<D>,
F: Extendable<D>,
{
self.count += terms.len() as u64;
terms