Skip to content

Commit

Permalink
Custom circuit builder (#7)
Browse files Browse the repository at this point in the history
* custom circuit builder (WIP)

* add per dense/spread contexts & assignment

* enable spread table constraints

* contingent range check

* fix max input bytes constant in sha256 chip

* refactor sha256 chip, uncomment hash2curve

* refactor again, use `thread_pool` instead of ctxs

* refactor step circuit & agrs struct

* add `Eth2CircuitBuilder`

* uncomment Sha256Wide chip

* remove unused features from Sha256Wide config

* add ShaWide thread builder

* sha256Wide assign to region

* uncomment CommitteeUpdateCircuit

* fix ShaBitThreadBuilder
  • Loading branch information
nulltea authored Sep 12, 2023
1 parent 94ed274 commit 083c264
Show file tree
Hide file tree
Showing 34 changed files with 2,475 additions and 3,209 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["lightclient-circuits", "prover", "eth-types"]
members = ["lightclient-circuits", "eth-types"]

# Definition of benchmarks profile to use.
[profile.bench]
Expand All @@ -26,12 +26,12 @@ halo2curves = { git = "https://github.com/timoftime/halo2curves", branch = "dev/
# halo2curves = { path = "../halo2curves" }

[patch."https://github.com/axiom-crypto/halo2-lib"]
halo2-base = { git = "https://github.com/timoftime/halo2-lib", rev = "7cebe716bb0569a7cb741c44ef8e87b2eadbbafb", default-features = false, features = [
halo2-base = { git = "https://github.com/timoftime/halo2-lib", rev = "d3455345c40fdee4462e400b55b94559c6d494e9", default-features = false, features = [
"halo2-pse",
"display",
] }
halo2-ecc = { git = "https://github.com/timoftime/halo2-lib", rev = "7cebe716bb0569a7cb741c44ef8e87b2eadbbafb", default-features = false }
poseidon = { git = "https://github.com/timoftime/halo2-lib", rev = "7cebe716bb0569a7cb741c44ef8e87b2eadbbafb", default-features = false }
halo2-ecc = { git = "https://github.com/timoftime/halo2-lib", rev = "d3455345c40fdee4462e400b55b94559c6d494e9", default-features = false }
poseidon = { git = "https://github.com/timoftime/halo2-lib", rev = "d3455345c40fdee4462e400b55b94559c6d494e9", default-features = false }

# halo2-base = { path = "../halo2-lib/halo2-base", default-features = false, features = [
# "halo2-pse",
Expand Down
129 changes: 129 additions & 0 deletions lightclient-circuits/src/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
use eth_types::Field;
use halo2_base::{
gates::builder::{FlexGateConfigParams, MultiPhaseThreadBreakPoints},
AssignedValue,
};
use halo2_proofs::{
circuit::{Layouter, SimpleFloorPlanner},
plonk::{Circuit, Column, ConstraintSystem, Error, Instance},
};
use log::debug;

use crate::{
gadget::crypto::{SHAConfig, ShaCircuitBuilder, ShaThreadBuilder},
util::{ThreadBuilderBase, ThreadBuilderConfigBase},
};

#[derive(Clone, Debug)]
/// Config shared for block header and storage proof circuits
pub struct Eth2Config<F: Field, CustomConfig: ThreadBuilderConfigBase<F>> {
sha: SHAConfig<F, CustomConfig>,
pub instance: Column<Instance>,
}

/// This is an extension of [`ShaCircuitBuilder`] that adds support for public instances (aka public inputs+outputs)
pub struct Eth2CircuitBuilder<F: Field, ThreadBuilder: ThreadBuilderBase<F>> {
pub inner: ShaCircuitBuilder<F, ThreadBuilder>,
pub assigned_instances: Vec<AssignedValue<F>>,
}

impl<F: Field, ThreadBuilder: ThreadBuilderBase<F>> Eth2CircuitBuilder<F, ThreadBuilder> {
/// Creates a new [Eth2CircuitBuilder] with `use_unknown` of [ThreadBuilder] set to true.
pub fn keygen(assigned_instances: Vec<AssignedValue<F>>, builder: ThreadBuilder) -> Self {
Self {
assigned_instances,
inner: ShaCircuitBuilder::keygen(builder),
}
}

/// Creates a new [Eth2CircuitBuilder] with `use_unknown` of [ThreadBuilder] set to false.
pub fn mock(assigned_instances: Vec<AssignedValue<F>>, builder: ThreadBuilder) -> Self {
Self {
assigned_instances,
inner: ShaCircuitBuilder::mock(builder),
}
}

/// Creates a new [Eth2CircuitBuilder].
pub fn prover(
assigned_instances: Vec<AssignedValue<F>>,
builder: ThreadBuilder,
break_points: MultiPhaseThreadBreakPoints,
) -> Self {
Self {
assigned_instances,
inner: ShaCircuitBuilder::prover(builder, break_points),
}
}

pub fn config(&self, k: usize, minimum_rows: Option<usize>) -> FlexGateConfigParams {
self.inner.config(k, minimum_rows)
}

pub fn break_points(&self) -> MultiPhaseThreadBreakPoints {
self.inner.break_points.borrow().clone()
}

pub fn instance_count(&self) -> usize {
self.assigned_instances.len()
}

pub fn instance(&self) -> Vec<F> {
self.assigned_instances.iter().map(|v| *v.value()).collect()
}
}

impl<F: Field, ThreadBuilder: ThreadBuilderBase<F>> Circuit<F>
for Eth2CircuitBuilder<F, ThreadBuilder>
{
type Config = Eth2Config<F, ThreadBuilder::Config>;
type FloorPlanner = SimpleFloorPlanner;

fn without_witnesses(&self) -> Self {
unimplemented!()
}

fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
let sha = ShaCircuitBuilder::<F, ThreadBuilder>::configure(meta);
let instance = meta.instance_column();
meta.enable_equality(instance);

Eth2Config { sha, instance }
}

fn synthesize(
&self,
config: Self::Config,
mut layouter: impl Layouter<F>,
) -> Result<(), Error> {
// we later `take` the builder, so we need to save this value
let witness_gen_only = self.inner.builder.borrow().witness_gen_only();

let assigned_advices = self.inner.sub_synthesize(&config.sha, &mut layouter)?;

if !witness_gen_only {
// expose public instances
let mut layouter = layouter.namespace(|| "expose");
for (i, instance) in self.assigned_instances.iter().enumerate() {
let cell = instance.cell.unwrap();
let (cell, _) = assigned_advices
.get(&(cell.context_id, cell.offset))
.expect("instance not assigned");
layouter.constrain_instance(*cell, config.instance, i);
}
}
Ok(())
}
}

impl<F: Field, ThreadBuilder: ThreadBuilderBase<F>> snark_verifier_sdk::CircuitExt<F>
for Eth2CircuitBuilder<F, ThreadBuilder>
{
fn num_instance(&self) -> Vec<usize> {
vec![self.instance_count()]
}

fn instances(&self) -> Vec<Vec<F>> {
vec![self.instance()]
}
}
Loading

0 comments on commit 083c264

Please sign in to comment.