This commit is contained in:
wborgeaud 2022-01-28 12:07:02 +01:00
parent 5caf92a39a
commit cdea0d9f96
27 changed files with 405 additions and 45 deletions

View File

@ -3,6 +3,7 @@ use std::ops::Range;
use plonky2::field::extension_field::{Extendable, FieldExtension};
use plonky2::field::field_types::Field;
use plonky2::gates::batchable::MultiOpsGate;
use plonky2::gates::gate::Gate;
use plonky2::gates::util::StridedConstraintConsumer;
use plonky2::hash::hash_types::RichField;
@ -242,6 +243,16 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for InsertionGate<
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for InsertionGate<F, D> {
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
#[derive(Debug)]
struct InsertionGenerator<F: RichField + Extendable<D>, const D: usize> {
gate_index: usize,

View File

@ -2,6 +2,7 @@ use std::ops::Range;
use plonky2_field::extension_field::Extendable;
use crate::gates::batchable::BatchableGate;
use crate::gates::gate::Gate;
use crate::hash::hash_types::RichField;
use crate::iop::ext_target::ExtensionTarget;
@ -12,7 +13,7 @@ use crate::plonk::circuit_builder::CircuitBuilder;
/// with the given size, and whose values are extension field elements, given by input wires.
/// Outputs the evaluation of the interpolant at a given (extension field) evaluation point.
pub(crate) trait InterpolationGate<F: RichField + Extendable<D>, const D: usize>:
Gate<F, D> + Copy
BatchableGate<F, D> + Copy
{
fn new(subgroup_bits: usize) -> Self;

View File

@ -1,6 +1,7 @@
use plonky2_field::extension_field::Extendable;
use plonky2_field::packed_field::PackedField;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
@ -151,6 +152,20 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ArithmeticGate
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for ArithmeticGate {
fn num_ops(&self) -> usize {
self.num_ops
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
vec![
Target::wire(gate_index, Self::wire_ith_multiplicand_0(i)),
Target::wire(gate_index, Self::wire_ith_multiplicand_1(i)),
Target::wire(gate_index, Self::wire_ith_addend(i)),
]
}
}
impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D> for ArithmeticGate {
fn eval_unfiltered_base_packed<P: PackedField<Scalar = F>>(
&self,

View File

@ -3,6 +3,7 @@ use std::ops::Range;
use plonky2_field::extension_field::Extendable;
use plonky2_field::extension_field::FieldExtension;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
@ -158,6 +159,23 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ArithmeticExte
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D>
for ArithmeticExtensionGate<D>
{
fn num_ops(&self) -> usize {
self.num_ops
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
[
ExtensionTarget::<D>::from_range(gate_index, Self::wires_ith_multiplicand_0(i)).0,
ExtensionTarget::<D>::from_range(gate_index, Self::wires_ith_multiplicand_1(i)).0,
ExtensionTarget::<D>::from_range(gate_index, Self::wires_ith_addend(i)).0,
]
.concat()
}
}
#[derive(Clone, Debug)]
struct ArithmeticExtensionGenerator<F: RichField + Extendable<D>, const D: usize> {
gate_index: usize,

View File

@ -5,6 +5,7 @@ use plonky2_field::extension_field::Extendable;
use plonky2_field::field_types::Field;
use plonky2_field::packed_field::PackedField;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
@ -232,6 +233,20 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32ArithmeticG
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for U32ArithmeticGate<F, D> {
fn num_ops(&self) -> usize {
self.num_ops
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
vec![
Target::wire(gate_index, self.wire_ith_multiplicand_0(i)),
Target::wire(gate_index, self.wire_ith_multiplicand_1(i)),
Target::wire(gate_index, self.wire_ith_addend(i)),
]
}
}
impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D>
for U32ArithmeticGate<F, D>
{

View File

@ -5,6 +5,7 @@ use plonky2_field::field_types::{Field, PrimeField};
use plonky2_field::packed_field::PackedField;
use plonky2_util::{bits_u64, ceil_div_usize};
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
@ -280,6 +281,16 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for AssertLessThan
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for AssertLessThanGate<F, D> {
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D>
for AssertLessThanGate<F, D>
{

View File

@ -4,6 +4,7 @@ use plonky2_field::extension_field::Extendable;
use plonky2_field::field_types::{Field, PrimeField};
use plonky2_field::packed_field::PackedField;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
@ -135,6 +136,17 @@ impl<F: RichField + Extendable<D>, const D: usize, const B: usize> Gate<F, D> fo
1 + self.num_limbs
}
}
impl<F: RichField + Extendable<D>, const D: usize, const B: usize> MultiOpsGate<F, D>
for BaseSumGate<B>
{
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
impl<F: RichField + Extendable<D>, const D: usize, const B: usize> PackedEvaluableBase<F, D>
for BaseSumGate<B>

View File

@ -1,28 +1,94 @@
use std::collections::HashMap;
use std::hash::Hash;
use std::fmt::{Debug, Error, Formatter};
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::sync::Arc;
use plonky2_field::extension_field::Extendable;
use crate::gates::gate::Gate;
use crate::hash::hash_types::RichField;
use crate::iop::target::Target;
use crate::plonk::circuit_builder::CircuitBuilder;
pub trait BatchableGate<F: RichField + Extendable<D>, const D: usize>: Gate<F, D> {
type Parameters: Copy;
fn find_available_slot(&self, params: Self::Parameters) -> (usize, usize);
fn fill_gate(&self, params: Self::Parameters, builder: &mut CircuitBuilder<F, D>);
// TODO: It would be nice to have a `Parameters` associated type.
fn fill_gate(
&self,
params: &[F],
current_slot: &CurrentSlot<F, D>,
builder: &mut CircuitBuilder<F, D>,
);
}
pub struct CurrentSlot<F: RichField + Extendable<D>, const D: usize, G: BatchableGate<F, D>> {
current_slot: HashMap<G::Parameters, (usize, usize)>,
pub struct CurrentSlot<F: RichField + Extendable<D>, const D: usize> {
current_slot: HashMap<Vec<F>, (usize, usize)>,
}
// pub struct Yo<F: RichField + Extendable<D>, const D: usize>(
// CurrentSlot<F, D, dyn BatchableGate<F, D>>,
// );
#[derive(Clone)]
pub struct GateRef<F: RichField + Extendable<D>, const D: usize>(
pub(crate) Arc<dyn BatchableGate<F, D>>,
);
impl<F: RichField + Extendable<D>, const D: usize> GateRef<F, D> {
pub fn new<G: BatchableGate<F, D>>(gate: G) -> GateRef<F, D> {
GateRef(Arc::new(gate))
}
}
impl<F: RichField + Extendable<D>, const D: usize> PartialEq for GateRef<F, D> {
fn eq(&self, other: &Self) -> bool {
self.0.id() == other.0.id()
}
}
impl<F: RichField + 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: RichField + Extendable<D>, const D: usize> Eq for GateRef<F, D> {}
impl<F: RichField + Extendable<D>, const D: usize> Debug for GateRef<F, D> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
write!(f, "{}", self.0.id())
}
}
// pub trait SingleOpGate<F: RichField + Extendable<D>, const D: usize>: Gate<F, D> {}
// impl<F: RichField + Extendable<D>, G: SingleOpGate<F, D>, const D: usize> MultiOpsGate<F, D> for G {
// fn num_ops(&self) -> usize {
// 1
// }
//
// fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
// unreachable!()
// }
// }
pub trait MultiOpsGate<F: RichField + Extendable<D>, const D: usize>: Gate<F, D> {
fn num_ops(&self) -> usize;
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target>;
}
impl<F: RichField + Extendable<D>, G: MultiOpsGate<F, D>, const D: usize> BatchableGate<F, D>
for G
{
fn fill_gate(
&self,
params: &[F],
current_slot: &CurrentSlot<F, D>,
builder: &mut CircuitBuilder<F, D>,
) {
if let Some(&(gate_index, op)) = current_slot.current_slot.get(params) {
let zero = builder.zero();
for i in op..self.num_ops() {
for dep in self.dependencies_ith_op(gate_index, i) {
builder.connect(dep, zero);
}
}
}
}
}

View File

@ -5,6 +5,7 @@ use plonky2_field::field_types::{Field, PrimeField};
use plonky2_field::packed_field::PackedField;
use plonky2_util::{bits_u64, ceil_div_usize};
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
@ -313,6 +314,26 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ComparisonGate
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for ComparisonGate<F, D> {
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
// impl<F: Richfield + Extendable<d>, const D: usize> Singleopgate<f, d> for multiopsgate<f, d> {
// fn num_ops(&self) -> usize {
// 1
// }
//
// fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
// unreachable!()
// }
// }
impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D>
for ComparisonGate<F, D>
{

View File

@ -4,6 +4,7 @@ use plonky2_field::extension_field::Extendable;
use plonky2_field::field_types::Field;
use plonky2_field::packed_field::PackedField;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
@ -102,6 +103,16 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ConstantGate {
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for ConstantGate {
fn num_ops(&self) -> usize {
self.num_consts
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
vec![]
}
}
impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D> for ConstantGate {
fn eval_unfiltered_base_packed<P: PackedField<Scalar = F>>(
&self,

View File

@ -5,6 +5,7 @@ use plonky2_field::field_types::Field;
use plonky2_field::ops::Square;
use plonky2_field::packed_field::PackedField;
use crate::gates::batchable::{BatchableGate, MultiOpsGate};
use crate::gates::gate::Gate;
use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
@ -190,6 +191,16 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for Exponentiation
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for ExponentiationGate<F, D> {
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D>
for ExponentiationGate<F, D>
{

View File

@ -6,6 +6,7 @@ use plonky2_field::batch_util::batch_multiply_inplace;
use plonky2_field::extension_field::{Extendable, FieldExtension};
use plonky2_field::field_types::Field;
use crate::gates::batchable::GateRef;
use crate::gates::gate_tree::Tree;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
@ -141,35 +142,35 @@ pub trait Gate<F: RichField + Extendable<D>, const D: usize>: 'static + Send + S
fn num_constraints(&self) -> usize;
}
/// A wrapper around an `Rc<Gate>` which implements `PartialEq`, `Eq` and `Hash` based on gate IDs.
#[derive(Clone)]
pub struct GateRef<F: RichField + Extendable<D>, const D: usize>(pub(crate) Arc<dyn Gate<F, D>>);
impl<F: RichField + 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: RichField + Extendable<D>, const D: usize> PartialEq for GateRef<F, D> {
fn eq(&self, other: &Self) -> bool {
self.0.id() == other.0.id()
}
}
impl<F: RichField + 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: RichField + Extendable<D>, const D: usize> Eq for GateRef<F, D> {}
impl<F: RichField + Extendable<D>, const D: usize> Debug for GateRef<F, D> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
write!(f, "{}", self.0.id())
}
}
// /// A wrapper around an `Rc<Gate>` which implements `PartialEq`, `Eq` and `Hash` based on gate IDs.
// #[derive(Clone)]
// pub struct GateRef<F: RichField + Extendable<D>, const D: usize>(pub(crate) Arc<dyn Gate<F, D>>);
//
// impl<F: RichField + 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: RichField + Extendable<D>, const D: usize> PartialEq for GateRef<F, D> {
// fn eq(&self, other: &Self) -> bool {
// self.0.id() == other.0.id()
// }
// }
//
// impl<F: RichField + 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: RichField + Extendable<D>, const D: usize> Eq for GateRef<F, D> {}
//
// impl<F: RichField + 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: RichField + Extendable<D>, const D: usize> {

View File

@ -1,7 +1,7 @@
use log::debug;
use plonky2_field::extension_field::Extendable;
use crate::gates::gate::GateRef;
use crate::gates::batchable::GateRef;
use crate::hash::hash_types::RichField;
/// A binary tree where leaves hold some type `T` and other nodes are empty.

View File

@ -4,6 +4,7 @@ use plonky2_field::extension_field::Extendable;
use plonky2_field::field_types::Field;
use plonky2_field::packed_field::PackedField;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
@ -215,6 +216,17 @@ impl<F: RichField + Extendable<D> + GMiMC<WIDTH>, const D: usize, const WIDTH: u
gmimc::NUM_ROUNDS + WIDTH + 1
}
}
impl<F: RichField + Extendable<D> + GMiMC<WIDTH>, const D: usize, const WIDTH: usize>
MultiOpsGate<F, D> for GMiMCGate<F, D, WIDTH>
{
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
impl<F: RichField + Extendable<D> + GMiMC<WIDTH>, const D: usize, const WIDTH: usize>
PackedEvaluableBase<F, D> for GMiMCGate<F, D, WIDTH>

View File

@ -8,6 +8,7 @@ use plonky2_field::polynomial::PolynomialCoeffs;
use crate::gadgets::interpolation::InterpolationGate;
use crate::gadgets::polynomial::PolynomialCoeffsExtAlgebraTarget;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
@ -202,6 +203,17 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D>
self.num_points() * D + D
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D>
for HighDegreeInterpolationGate<F, D>
{
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
#[derive(Debug)]
struct InterpolationGenerator<F: RichField + Extendable<D>, const D: usize> {

View File

@ -9,6 +9,7 @@ use plonky2_field::polynomial::PolynomialCoeffs;
use crate::gadgets::interpolation::InterpolationGate;
use crate::gadgets::polynomial::PolynomialCoeffsExtAlgebraTarget;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
@ -294,6 +295,18 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LowDegreeInter
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D>
for LowDegreeInterpolationGate<F, D>
{
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
#[derive(Debug)]
struct InterpolationGenerator<F: RichField + Extendable<D>, const D: usize> {
gate_index: usize,

View File

@ -3,6 +3,7 @@ use std::ops::Range;
use plonky2_field::extension_field::Extendable;
use plonky2_field::extension_field::FieldExtension;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
@ -145,6 +146,20 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for MulExtensionGa
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for MulExtensionGate<D> {
fn num_ops(&self) -> usize {
self.num_ops
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
[
ExtensionTarget::<D>::from_range(gate_index, Self::wires_ith_multiplicand_0(i)).0,
ExtensionTarget::<D>::from_range(gate_index, Self::wires_ith_multiplicand_1(i)).0,
]
.concat()
}
}
#[derive(Clone, Debug)]
struct MulExtensionGenerator<F: RichField + Extendable<D>, const D: usize> {
gate_index: usize,

View File

@ -1,9 +1,11 @@
use plonky2_field::extension_field::Extendable;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::hash::hash_types::RichField;
use crate::iop::ext_target::ExtensionTarget;
use crate::iop::generator::WitnessGenerator;
use crate::iop::target::Target;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBaseBatch};
@ -56,6 +58,16 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for NoopGate {
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for NoopGate {
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
#[cfg(test)]
mod tests {
use plonky2_field::goldilocks_field::GoldilocksField;

View File

@ -3,6 +3,7 @@ use std::marker::PhantomData;
use plonky2_field::extension_field::Extendable;
use plonky2_field::field_types::Field;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::poseidon_mds::PoseidonMdsGate;
use crate::gates::util::StridedConstraintConsumer;
@ -406,6 +407,15 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for PoseidonGate<F
+ 4
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for PoseidonGate<F, D> {
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
#[derive(Debug)]
struct PoseidonGenerator<F: RichField + Extendable<D> + Poseidon, const D: usize> {

View File

@ -6,6 +6,7 @@ use plonky2_field::extension_field::Extendable;
use plonky2_field::extension_field::FieldExtension;
use plonky2_field::field_types::Field;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
@ -196,6 +197,17 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> Gate<F, D> for Pos
SPONGE_WIDTH * D
}
}
impl<F: RichField + Extendable<D> + Poseidon, const D: usize> MultiOpsGate<F, D>
for PoseidonMdsGate<F, D>
{
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
#[derive(Clone, Debug)]
struct PoseidonMdsGenerator<const D: usize> {

View File

@ -3,12 +3,14 @@ use std::ops::Range;
use plonky2_field::extension_field::Extendable;
use plonky2_field::packed_field::PackedField;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
use crate::iop::ext_target::ExtensionTarget;
use crate::iop::generator::WitnessGenerator;
use crate::iop::target::Target;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::vars::{
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
@ -87,6 +89,16 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for PublicInputGat
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for PublicInputGate {
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D> for PublicInputGate {
fn eval_unfiltered_base_packed<P: PackedField<Scalar = F>>(
&self,

View File

@ -5,6 +5,7 @@ use plonky2_field::extension_field::Extendable;
use plonky2_field::field_types::Field;
use plonky2_field::packed_field::PackedField;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
@ -230,6 +231,21 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGa
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for RandomAccessGate<F, D> {
fn num_ops(&self) -> usize {
self.num_copies
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
RandomAccessGenerator {
gate_index,
gate: *self,
copy: i,
}
.dependencies()
}
}
impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D>
for RandomAccessGate<F, D>
{

View File

@ -3,6 +3,7 @@ use std::ops::Range;
use plonky2_field::extension_field::Extendable;
use plonky2_field::extension_field::FieldExtension;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
@ -166,6 +167,16 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ReducingGate<D
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for ReducingGate<D> {
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
#[derive(Debug)]
struct ReducingGenerator<const D: usize> {
gate_index: usize,

View File

@ -3,6 +3,7 @@ use std::ops::Range;
use plonky2_field::extension_field::Extendable;
use plonky2_field::extension_field::FieldExtension;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
@ -166,6 +167,16 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ReducingExtens
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for ReducingExtensionGate<D> {
fn num_ops(&self) -> usize {
1
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
unreachable!()
}
}
#[derive(Debug)]
struct ReducingGenerator<const D: usize> {
gate_index: usize,

View File

@ -4,6 +4,7 @@ use plonky2_field::extension_field::Extendable;
use plonky2_field::field_types::Field;
use plonky2_field::packed_field::PackedField;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
@ -221,6 +222,22 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32Subtraction
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for U32SubtractionGate<F, D> {
fn num_ops(&self) -> usize {
self.num_ops
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
U32SubtractionGenerator {
gate: *self,
gate_index,
i,
_phantom: Default::default(),
}
.dependencies()
}
}
impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D>
for U32SubtractionGate<F, D>
{

View File

@ -5,6 +5,7 @@ use plonky2_field::extension_field::Extendable;
use plonky2_field::field_types::Field;
use plonky2_field::packed_field::PackedField;
use crate::gates::batchable::MultiOpsGate;
use crate::gates::gate::Gate;
use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
@ -189,6 +190,16 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for SwitchGate<F,
}
}
impl<F: RichField + Extendable<D>, const D: usize> MultiOpsGate<F, D> for SwitchGate<F, D> {
fn num_ops(&self) -> usize {
self.num_copies
}
fn dependencies_ith_op(&self, gate_index: usize, i: usize) -> Vec<Target> {
todo!()
}
}
impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D> for SwitchGate<F, D> {
fn eval_unfiltered_base_packed<P: PackedField<Scalar = F>>(
&self,

View File

@ -18,9 +18,9 @@ use crate::gadgets::arithmetic_u32::U32Target;
use crate::gates::arithmetic_base::ArithmeticGate;
use crate::gates::arithmetic_extension::ArithmeticExtensionGate;
use crate::gates::arithmetic_u32::U32ArithmeticGate;
use crate::gates::batchable::{BatchableGate, CurrentSlot};
use crate::gates::batchable::{BatchableGate, CurrentSlot, GateRef};
use crate::gates::constant::ConstantGate;
use crate::gates::gate::{Gate, GateInstance, GateRef, PrefixedGate};
use crate::gates::gate::{Gate, GateInstance, PrefixedGate};
use crate::gates::gate_tree::Tree;
use crate::gates::multiplication_extension::MulExtensionGate;
use crate::gates::noop::NoopGate;
@ -86,6 +86,8 @@ pub struct CircuitBuilder<F: RichField + Extendable<D>, const D: usize> {
// yo: Vec<Yo<F, D, dyn Copy>>,
batched_gates: BatchedGates<F, D>,
current_slots: HashMap<GateRef<F, D>, CurrentSlot<F, D>>,
}
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
@ -105,6 +107,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
arithmetic_results: HashMap::new(),
targets_to_constants: HashMap::new(),
batched_gates: BatchedGates::new(),
current_slots: HashMap::new(),
};
builder.check_config();
builder
@ -189,7 +192,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
/// Adds a gate to the circuit, and returns its index.
pub fn add_gate<G: Gate<F, D>>(&mut self, gate_type: G, constants: Vec<F>) -> usize {
pub fn add_gate<G: BatchableGate<F, D>>(&mut self, gate_type: G, constants: Vec<F>) -> usize {
self.check_gate_compatibility(&gate_type);
assert_eq!(
gate_type.num_constants(),