use std::marker::PhantomData;
use halo2_base::{
halo2_proofs::{
circuit::{Layouter, SimpleFloorPlanner},
plonk::{Circuit, ConstraintSystem, Error},
},
utils::ScalarField,
};
pub trait TwoPhaseCircuitInstructions<F: ScalarField> {
type Config: Clone;
type Params: Clone + Default;
fn configure_with_params(meta: &mut ConstraintSystem<F>, params: Self::Params) -> Self::Config;
fn params(&self) -> Self::Params;
fn clear(&self);
fn initialize(&self, _config: &Self::Config, _layouter: impl Layouter<F>) {}
fn virtual_assign_phase0(&self);
fn raw_synthesize_phase0(&self, config: &Self::Config, layouter: impl Layouter<F>);
fn load_challenges(&self, config: &Self::Config, layouter: impl Layouter<F>);
fn virtual_assign_phase1(&self);
fn raw_synthesize_phase1(&self, config: &Self::Config, layouter: impl Layouter<F>);
}
#[derive(Clone, Debug)]
pub struct TwoPhaseCircuit<F: ScalarField, CI: TwoPhaseCircuitInstructions<F>>(
pub CI,
PhantomData<F>,
);
impl<F: ScalarField, CI: TwoPhaseCircuitInstructions<F>> TwoPhaseCircuit<F, CI> {
pub fn new(instructions: CI) -> Self {
Self(instructions, PhantomData)
}
}
impl<F: ScalarField, CI: TwoPhaseCircuitInstructions<F>> Circuit<F> for TwoPhaseCircuit<F, CI> {
type Config = CI::Config;
type FloorPlanner = SimpleFloorPlanner;
type Params = CI::Params;
fn params(&self) -> Self::Params {
self.0.params()
}
fn without_witnesses(&self) -> Self {
unimplemented!()
}
fn configure_with_params(meta: &mut ConstraintSystem<F>, params: Self::Params) -> Self::Config {
CI::configure_with_params(meta, params)
}
fn configure(_: &mut ConstraintSystem<F>) -> Self::Config {
unreachable!()
}
fn synthesize(
&self,
config: Self::Config,
mut layouter: impl Layouter<F>,
) -> Result<(), Error> {
self.0.clear();
self.0.initialize(&config, layouter.namespace(|| "initialize"));
self.0.virtual_assign_phase0();
self.0.raw_synthesize_phase0(&config, layouter.namespace(|| "raw synthesize phase0"));
#[cfg(feature = "halo2-axiom")]
{
layouter.next_phase();
}
self.0.load_challenges(&config, layouter.namespace(|| "load challenges"));
self.0.virtual_assign_phase1();
self.0.raw_synthesize_phase1(&config, layouter.namespace(|| "raw synthesize phase1"));
Ok(())
}
}