Skip to content

Commit

Permalink
Extend Circuit trait to take parameters in config
Browse files Browse the repository at this point in the history
The Circuit trait is extended with the following:
```
pub trait Circuit<F: Field> {
    /// [...]
    type Params: Default;

    fn params(&self) -> Self::Params {
        Self::Params::default()
    }

    fn configure_with_params(meta: &mut ConstraintSystem<F>, params: &Self::Params) -> Self::Config {
        Self::configure(meta)
    }

    fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config;
}
```

This allows runtime parametrization of the circuit configuration.  The extension to the Circuit trait has been designed to minimize the breaking change: existing circuits only need to define the associated `type Params`.

Unfortunately "Associated type defaults" are unstable in Rust, otherwise this would be a non-breaking change.  See rust-lang/rust#29661
  • Loading branch information
ed255 committed Apr 18, 2023
1 parent 4d2c2f4 commit 8c5fa2a
Show file tree
Hide file tree
Showing 32 changed files with 73 additions and 15 deletions.
1 change: 1 addition & 0 deletions halo2_gadgets/benches/poseidon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ where
{
type Config = MyConfig<WIDTH, RATE, L>;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self {
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/benches/sha256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ fn bench(name: &str, k: u32, c: &mut Criterion) {
impl Circuit<pallas::Base> for MyCircuit {
type Config = Table16Config;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self::default()
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ pub(crate) mod tests {
impl Circuit<pallas::Base> for MyCircuit {
type Config = EccConfig<TestFixedBases>;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
MyCircuit { test_errors: false }
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/ecc/chip/mul_fixed/short.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ pub mod tests {
impl Circuit<pallas::Base> for MyCircuit {
type Config = EccConfig<TestFixedBases>;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self::default()
Expand Down
2 changes: 2 additions & 0 deletions halo2_gadgets/src/poseidon/pow5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ mod tests {
{
type Config = Pow5Config<Fp, WIDTH, RATE>;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
PermuteCircuit::<S, WIDTH, RATE>(PhantomData)
Expand Down Expand Up @@ -735,6 +736,7 @@ mod tests {
{
type Config = Pow5Config<Fp, WIDTH, RATE>;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self {
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/sha256/table16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ mod tests {
impl Circuit<pallas::Base> for MyCircuit {
type Config = Table16Config;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
MyCircuit {}
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/sha256/table16/compression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,7 @@ mod tests {
impl Circuit<pallas::Base> for MyCircuit {
type Config = Table16Config;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
MyCircuit {}
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/sha256/table16/message_schedule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ mod tests {
impl Circuit<pallas::Base> for MyCircuit {
type Config = Table16Config;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
MyCircuit {}
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/sha256/table16/spread_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ mod tests {
impl<F: PrimeField> Circuit<F> for MyCircuit {
type Config = SpreadTableConfig;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
MyCircuit {}
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/sinsemilla.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ pub(crate) mod tests {
SinsemillaConfig<TestHashDomain, TestCommitDomain, TestFixedBases>,
);
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
MyCircuit {}
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/sinsemilla/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ pub mod tests {
MerkleConfig<TestHashDomain, TestCommitDomain, TestFixedBases>,
);
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self::default()
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/utilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ mod tests {
impl<const RANGE: usize> Circuit<pallas::Base> for MyCircuit<RANGE> {
type Config = Config;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
MyCircuit(self.0)
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/utilities/cond_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ mod tests {
impl<F: PrimeField> Circuit<F> for MyCircuit<F> {
type Config = CondSwapConfig;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self::default()
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/utilities/decompose_running_sum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ mod tests {
{
type Config = RunningSumConfig<F, WINDOW_NUM_BITS>;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self {
Expand Down
2 changes: 2 additions & 0 deletions halo2_gadgets/src/utilities/lookup_range_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ mod tests {
impl<F: PrimeFieldBits> Circuit<F> for MyCircuit<F> {
type Config = LookupRangeCheckConfig<F, K>;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
*self
Expand Down Expand Up @@ -506,6 +507,7 @@ mod tests {
impl<F: PrimeFieldBits> Circuit<F> for MyCircuit<F> {
type Config = LookupRangeCheckConfig<F, K>;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
MyCircuit {
Expand Down
1 change: 1 addition & 0 deletions halo2_proofs/benches/dev_lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ fn criterion_benchmark(c: &mut Criterion) {
impl<F: PrimeField> Circuit<F> for MyCircuit<F> {
type Config = MyConfig;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self::default()
Expand Down
1 change: 1 addition & 0 deletions halo2_proofs/benches/plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ fn criterion_benchmark(c: &mut Criterion) {
impl<F: Field> Circuit<F> for MyCircuit<F> {
type Config = PlonkConfig;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self {
Expand Down
1 change: 1 addition & 0 deletions halo2_proofs/examples/circuit-layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ impl<FF: Field> StandardCs<FF> for StandardPlonk<FF> {
impl<F: Field> Circuit<F> for MyCircuit<F> {
type Config = PlonkConfig;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self {
Expand Down
9 changes: 7 additions & 2 deletions halo2_proofs/examples/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct StandardPlonk(Fr);
impl Circuit<Fr> for StandardPlonk {
type Config = StandardPlonkConfig;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self::default()
Expand Down Expand Up @@ -140,8 +141,12 @@ fn main() {

let f = File::open("serialization-test.pk").unwrap();
let mut reader = BufReader::new(f);
let pk = ProvingKey::<G1Affine>::read::<_, StandardPlonk>(&mut reader, SerdeFormat::RawBytes)
.unwrap();
let pk = ProvingKey::<G1Affine>::read::<_, StandardPlonk>(
&mut reader,
SerdeFormat::RawBytes,
&circuit.params(),
)
.unwrap();

std::fs::remove_file("serialization-test.pk").unwrap();

Expand Down
1 change: 1 addition & 0 deletions halo2_proofs/examples/shuffle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ impl<F: Field, const W: usize, const H: usize> MyCircuit<F, W, H> {
impl<F: Field, const W: usize, const H: usize> Circuit<F> for MyCircuit<F, W, H> {
type Config = MyConfig<W>;
type FloorPlanner = V1;
type Params = ();

fn without_witnesses(&self) -> Self {
Self::default()
Expand Down
1 change: 1 addition & 0 deletions halo2_proofs/examples/simple-example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ impl<F: Field> Circuit<F> for MyCircuit<F> {
// Since we are using a single chip for everything, we can just reuse its config.
type Config = FieldConfig;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self::default()
Expand Down
1 change: 1 addition & 0 deletions halo2_proofs/examples/two-chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ impl<F: Field> Circuit<F> for MyCircuit<F> {
// Since we are using a single chip for everything, we can just reuse its config.
type Config = FieldConfig;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
Self::default()
Expand Down
1 change: 1 addition & 0 deletions halo2_proofs/src/circuit/floor_planner/single_pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ mod tests {
impl Circuit<vesta::Scalar> for MyCircuit {
type Config = Column<Advice>;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn without_witnesses(&self) -> Self {
MyCircuit {}
Expand Down
1 change: 1 addition & 0 deletions halo2_proofs/src/circuit/floor_planner/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ mod tests {
impl Circuit<vesta::Scalar> for MyCircuit {
type Config = Column<Advice>;
type FloorPlanner = super::V1;
type Params = ();

fn without_witnesses(&self) -> Self {
MyCircuit {}
Expand Down
7 changes: 6 additions & 1 deletion halo2_proofs/src/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ impl<F: Field> Mul<F> for Value<F> {
/// impl<F: PrimeField> Circuit<F> for MyCircuit {
/// type Config = MyConfig;
/// type FloorPlanner = SimpleFloorPlanner;
/// type Params = ();
///
/// fn without_witnesses(&self) -> Self {
/// Self::default()
Expand Down Expand Up @@ -601,7 +602,7 @@ impl<F: FromUniformBytes<64> + Ord> MockProver<F> {
let n = 1 << k;

let mut cs = ConstraintSystem::default();
let config = ConcreteCircuit::configure(&mut cs);
let config = ConcreteCircuit::configure_with_params(&mut cs, &circuit.params());
let cs = cs;

assert!(
Expand Down Expand Up @@ -1536,6 +1537,7 @@ mod tests {
impl Circuit<Fp> for FaultyCircuit {
type Config = FaultyCircuitConfig;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
let a = meta.advice_column();
Expand Down Expand Up @@ -1622,6 +1624,7 @@ mod tests {
impl Circuit<Fp> for FaultyCircuit {
type Config = FaultyCircuitConfig;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
let a = meta.advice_column();
Expand Down Expand Up @@ -1791,6 +1794,7 @@ mod tests {
impl Circuit<Fp> for FaultyCircuit {
type Config = FaultyCircuitConfig;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
let a = meta.advice_column();
Expand Down Expand Up @@ -1925,6 +1929,7 @@ mod tests {
impl Circuit<Fp> for FaultyCircuit {
type Config = FaultyCircuitConfig;
type FloorPlanner = SimpleFloorPlanner;
type Params = ();

fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
let a = meta.advice_column();
Expand Down
2 changes: 1 addition & 1 deletion halo2_proofs/src/dev/cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ impl<G: PrimeGroup, ConcreteCircuit: Circuit<G::Scalar>> CircuitCost<G, Concrete
pub fn measure(k: usize, circuit: &ConcreteCircuit) -> Self {
// Collect the layout details.
let mut cs = ConstraintSystem::default();
let config = ConcreteCircuit::configure(&mut cs);
let config = ConcreteCircuit::configure_with_params(&mut cs, &circuit.params());
let mut assembly = Assembly {
selectors: vec![vec![false; 1 << k]; cs.num_selectors],
};
Expand Down
7 changes: 4 additions & 3 deletions halo2_proofs/src/dev/gates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct Gate {
/// impl<F: Field> Circuit<F> for MyCircuit {
/// type Config = MyConfig;
/// type FloorPlanner = SimpleFloorPlanner;
/// type Params = ();
///
/// fn without_witnesses(&self) -> Self {
/// Self::default()
Expand Down Expand Up @@ -79,7 +80,7 @@ struct Gate {
/// }
/// }
///
/// let gates = CircuitGates::collect::<pallas::Base, MyCircuit>();
/// let gates = CircuitGates::collect::<pallas::Base, MyCircuit>(&());
/// assert_eq!(
/// format!("{}", gates),
/// r#####"R1CS constraint:
Expand All @@ -103,10 +104,10 @@ pub struct CircuitGates {

impl CircuitGates {
/// Collects the gates from within the circuit.
pub fn collect<F: PrimeField, C: Circuit<F>>() -> Self {
pub fn collect<F: PrimeField, C: Circuit<F>>(params: &C::Params) -> Self {
// Collect the graph details.
let mut cs = ConstraintSystem::default();
let _ = C::configure(&mut cs);
let _ = C::configure_with_params(&mut cs, params);

let gates = cs
.gates
Expand Down
12 changes: 8 additions & 4 deletions halo2_proofs/src/plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,12 @@ where
pub fn read<R: io::Read, ConcreteCircuit: Circuit<C::Scalar>>(
reader: &mut R,
format: SerdeFormat,
params: &ConcreteCircuit::Params,
) -> io::Result<Self> {
let mut k = [0u8; 4];
reader.read_exact(&mut k)?;
let k = u32::from_be_bytes(k);
let (domain, cs, _) = keygen::create_domain::<C, ConcreteCircuit>(k);
let (domain, cs, _) = keygen::create_domain::<C, ConcreteCircuit>(k, params);
let mut num_fixed_columns = [0u8; 4];
reader.read_exact(&mut num_fixed_columns)?;
let num_fixed_columns = u32::from_be_bytes(num_fixed_columns);
Expand Down Expand Up @@ -150,8 +151,9 @@ where
pub fn from_bytes<ConcreteCircuit: Circuit<C::Scalar>>(
mut bytes: &[u8],
format: SerdeFormat,
params: &ConcreteCircuit::Params,
) -> io::Result<Self> {
Self::read::<_, ConcreteCircuit>(&mut bytes, format)
Self::read::<_, ConcreteCircuit>(&mut bytes, format, params)
}
}

Expand Down Expand Up @@ -335,8 +337,9 @@ where
pub fn read<R: io::Read, ConcreteCircuit: Circuit<C::Scalar>>(
reader: &mut R,
format: SerdeFormat,
params: &ConcreteCircuit::Params,
) -> io::Result<Self> {
let vk = VerifyingKey::<C>::read::<R, ConcreteCircuit>(reader, format)?;
let vk = VerifyingKey::<C>::read::<R, ConcreteCircuit>(reader, format, params)?;
let l0 = Polynomial::read(reader, format)?;
let l_last = Polynomial::read(reader, format)?;
let l_active_row = Polynomial::read(reader, format)?;
Expand Down Expand Up @@ -369,8 +372,9 @@ where
pub fn from_bytes<ConcreteCircuit: Circuit<C::Scalar>>(
mut bytes: &[u8],
format: SerdeFormat,
params: &ConcreteCircuit::Params,
) -> io::Result<Self> {
Self::read::<_, ConcreteCircuit>(&mut bytes, format)
Self::read::<_, ConcreteCircuit>(&mut bytes, format, params)
}
}

Expand Down
16 changes: 16 additions & 0 deletions halo2_proofs/src/plonk/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -664,13 +664,29 @@ pub trait Circuit<F: Field> {
/// The floor planner used for this circuit. This is an associated type of the
/// `Circuit` trait because its behaviour is circuit-critical.
type FloorPlanner: FloorPlanner;
/// Optional circuit configuration parameters.
type Params: Default;

/// Returns a copy of this circuit with no witness values (i.e. all witnesses set to
/// `None`). For most circuits, this will be equal to `Self::default()`.
fn without_witnesses(&self) -> Self;

/// Returns a reference to the parameters that should be used to configure the circuit.
fn params(&self) -> Self::Params {
Self::Params::default()
}

/// The circuit is given an opportunity to describe the exact gate
/// arrangement, column arrangement, etc.
fn configure_with_params(
meta: &mut ConstraintSystem<F>,
_params: &Self::Params,
) -> Self::Config {
Self::configure(meta)
}

/// Configuration function without parameters. This method is usually only called via the default
/// `configure_with_params` implementation for backwards-compatibility purposes.
fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config;

/// Given the provided `cs`, synthesize the circuit. The concrete type of
Expand Down
Loading

0 comments on commit 8c5fa2a

Please sign in to comment.