2021-02-09 21:25:21 -08:00
|
|
|
use std::hash::{Hash, Hasher};
|
2021-04-01 13:46:24 -07:00
|
|
|
use std::sync::Arc;
|
2021-02-09 21:25:21 -08:00
|
|
|
|
2021-03-28 15:36:51 -07:00
|
|
|
use crate::circuit_builder::CircuitBuilder;
|
2021-02-09 21:25:21 -08:00
|
|
|
use crate::field::field::Field;
|
2021-03-01 13:40:05 -08:00
|
|
|
use crate::generator::WitnessGenerator;
|
2021-03-28 15:36:51 -07:00
|
|
|
use crate::target::Target;
|
2021-04-21 22:31:45 +02:00
|
|
|
use crate::vars::{EvaluationTargets, EvaluationVars};
|
2021-02-09 21:25:21 -08:00
|
|
|
|
|
|
|
|
/// A custom gate.
|
2021-04-01 13:46:24 -07:00
|
|
|
pub trait Gate<F: Field>: 'static + Send + Sync {
|
2021-02-09 21:25:21 -08:00
|
|
|
fn id(&self) -> String;
|
|
|
|
|
|
2021-03-28 15:36:51 -07:00
|
|
|
fn eval_unfiltered(&self, vars: EvaluationVars<F>) -> Vec<F>;
|
2021-02-09 21:25:21 -08:00
|
|
|
|
2021-03-28 15:36:51 -07:00
|
|
|
fn eval_unfiltered_recursively(
|
|
|
|
|
&self,
|
|
|
|
|
builder: &mut CircuitBuilder<F>,
|
|
|
|
|
vars: EvaluationTargets,
|
|
|
|
|
) -> Vec<Target>;
|
|
|
|
|
|
|
|
|
|
fn eval_filtered(&self, vars: EvaluationVars<F>) -> Vec<F> {
|
|
|
|
|
// TODO: Filter
|
|
|
|
|
self.eval_unfiltered(vars)
|
|
|
|
|
}
|
2021-03-25 15:20:14 -07:00
|
|
|
|
2021-04-02 19:15:39 -07:00
|
|
|
fn eval_filtered_recursively(
|
|
|
|
|
&self,
|
|
|
|
|
builder: &mut CircuitBuilder<F>,
|
|
|
|
|
vars: EvaluationTargets,
|
|
|
|
|
) -> Vec<Target> {
|
|
|
|
|
// TODO: Filter
|
|
|
|
|
self.eval_unfiltered_recursively(builder, vars)
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-09 21:25:21 -08:00
|
|
|
fn generators(
|
|
|
|
|
&self,
|
|
|
|
|
gate_index: usize,
|
2021-03-28 15:36:51 -07:00
|
|
|
local_constants: &[F],
|
2021-03-01 13:40:05 -08:00
|
|
|
) -> Vec<Box<dyn WitnessGenerator<F>>>;
|
2021-02-09 21:25:21 -08:00
|
|
|
|
2021-03-28 15:36:51 -07:00
|
|
|
/// The number of wires used by this gate.
|
|
|
|
|
fn num_wires(&self) -> usize;
|
2021-02-09 21:25:21 -08:00
|
|
|
|
2021-03-28 15:36:51 -07:00
|
|
|
/// The number of constants used by this gate.
|
|
|
|
|
fn num_constants(&self) -> usize;
|
2021-02-09 21:25:21 -08:00
|
|
|
|
|
|
|
|
/// The maximum degree among this gate's constraint polynomials.
|
2021-03-28 15:36:51 -07:00
|
|
|
fn degree(&self) -> usize;
|
|
|
|
|
|
|
|
|
|
fn num_constraints(&self) -> usize;
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A wrapper around an `Rc<Gate>` which implements `PartialEq`, `Eq` and `Hash` based on gate IDs.
|
|
|
|
|
#[derive(Clone)]
|
2021-04-01 13:46:24 -07:00
|
|
|
pub struct GateRef<F: Field>(pub(crate) Arc<dyn Gate<F>>);
|
2021-02-09 21:25:21 -08:00
|
|
|
|
|
|
|
|
impl<F: Field> GateRef<F> {
|
2021-02-24 12:25:13 -08:00
|
|
|
pub fn new<G: Gate<F>>(gate: G) -> GateRef<F> {
|
2021-04-01 13:46:24 -07:00
|
|
|
GateRef(Arc::new(gate))
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<F: Field> PartialEq for GateRef<F> {
|
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
|
|
self.0.id() == other.0.id()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<F: Field> Hash for GateRef<F> {
|
|
|
|
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
|
|
|
self.0.id().hash(state)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<F: Field> Eq for GateRef<F> {}
|
|
|
|
|
|
|
|
|
|
/// A gate along with any constants used to configure it.
|
|
|
|
|
pub struct GateInstance<F: Field> {
|
|
|
|
|
pub gate_type: GateRef<F>,
|
|
|
|
|
pub constants: Vec<F>,
|
|
|
|
|
}
|