Skip to content

Commit

Permalink
Moved RangeWithInstanceCircuitBuilder to halo2-lib (#9)
Browse files Browse the repository at this point in the history
* chore: sync with halo2-lib

* fix: clippy
  • Loading branch information
jonathanpwang authored May 5, 2023
1 parent 57aaba5 commit aecfd45
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 125 deletions.
111 changes: 3 additions & 108 deletions snark-verifier-sdk/src/halo2/aggregation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ use halo2_base::{
gates::{
builder::{
CircuitBuilderStage, FlexGateConfigParams, GateThreadBuilder,
MultiPhaseThreadBreakPoints, RangeCircuitBuilder,
MultiPhaseThreadBreakPoints, RangeCircuitBuilder, RangeWithInstanceCircuitBuilder,
RangeWithInstanceConfig,
},
range::RangeConfig,
RangeChip,
},
halo2_proofs::{
circuit::{Layouter, SimpleFloorPlanner},
halo2curves::bn256::{Bn256, Fr, G1Affine},
plonk::{self, Circuit, Column, ConstraintSystem, Instance, Selector},
plonk::{self, Circuit, ConstraintSystem, Selector},
poly::{
commitment::{Params, ParamsProver},
kzg::commitment::ParamsKZG,
Expand Down Expand Up @@ -152,63 +152,6 @@ impl AggregationConfigParams {
}
}

#[derive(Clone, Debug)]
pub struct RangeWithInstanceConfig<F: ScalarField> {
pub range: RangeConfig<F>,
pub instance: Column<Instance>,
}

/// This is an extension of [`RangeCircuitBuilder`] that adds support for public instances (aka public inputs+outputs)
///
/// The intended design is that a [`GateThreadBuilder`] is populated and then produces some assigned instances, which are supplied as `assigned_instances` to this struct.
/// The [`Circuit`] implementation for this struct will then expose these instances and constrain them using the Halo2 API.
#[derive(Clone, Debug)]
pub struct RangeWithInstanceCircuitBuilder<F: ScalarField> {
pub circuit: RangeCircuitBuilder<F>,
pub assigned_instances: Vec<AssignedValue<F>>,
}

impl<F: ScalarField> RangeWithInstanceCircuitBuilder<F> {
pub fn keygen(
builder: GateThreadBuilder<F>,
assigned_instances: Vec<AssignedValue<F>>,
) -> Self {
Self { circuit: RangeCircuitBuilder::keygen(builder), assigned_instances }
}

pub fn mock(builder: GateThreadBuilder<F>, assigned_instances: Vec<AssignedValue<F>>) -> Self {
Self { circuit: RangeCircuitBuilder::mock(builder), assigned_instances }
}

pub fn prover(
builder: GateThreadBuilder<F>,
assigned_instances: Vec<AssignedValue<F>>,
break_points: MultiPhaseThreadBreakPoints,
) -> Self {
Self { circuit: RangeCircuitBuilder::prover(builder, break_points), assigned_instances }
}

pub fn new(circuit: RangeCircuitBuilder<F>, assigned_instances: Vec<AssignedValue<F>>) -> Self {
Self { circuit, assigned_instances }
}

pub fn config(&self, k: u32, minimum_rows: Option<usize>) -> FlexGateConfigParams {
self.circuit.0.builder.borrow().config(k as usize, minimum_rows)
}

pub fn break_points(&self) -> MultiPhaseThreadBreakPoints {
self.circuit.0.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()
}
}

#[derive(Clone, Debug)]
pub struct AggregationCircuit {
pub inner: RangeWithInstanceCircuitBuilder<Fr>,
Expand Down Expand Up @@ -427,54 +370,6 @@ impl AggregationCircuit {
}
}

impl<F: ScalarField> Circuit<F> for RangeWithInstanceCircuitBuilder<F> {
type Config = RangeWithInstanceConfig<F>;
type FloorPlanner = SimpleFloorPlanner;

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

fn configure(meta: &mut plonk::ConstraintSystem<F>) -> Self::Config {
let range = RangeCircuitBuilder::configure(meta);
let instance = meta.instance_column();
meta.enable_equality(instance);
RangeWithInstanceConfig { range, instance }
}

fn synthesize(
&self,
config: Self::Config,
mut layouter: impl Layouter<F>,
) -> Result<(), plonk::Error> {
// copied from RangeCircuitBuilder::synthesize but with extra logic to expose public instances
let range = config.range;
let circuit = &self.circuit.0;
range.load_lookup_table(&mut layouter).expect("load lookup table should not fail");
// we later `take` the builder, so we need to save this value
let witness_gen_only = circuit.builder.borrow().witness_gen_only();
let assigned_advices = circuit.sub_synthesize(
&range.gate,
&range.lookup_advice,
&range.q_lookup,
&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: ScalarField> CircuitExt<F> for RangeWithInstanceCircuitBuilder<F> {
fn num_instance(&self) -> Vec<usize> {
vec![self.instance_count()]
Expand Down
10 changes: 5 additions & 5 deletions snark-verifier/examples/recursion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ mod recursion {
.flat_map(|preprocessed| {
let assigned = preprocessed.assigned();
[assigned.x(), assigned.y()]
.map(|coordinate| loader.scalar_from_assigned(coordinate.native().clone()))
.map(|coordinate| loader.scalar_from_assigned(*coordinate.native()))
})
.chain(protocol.transcript_initial_state.clone())
.collect_vec();
Expand Down Expand Up @@ -410,7 +410,7 @@ mod recursion {
.iter()
.zip([rhs.lhs.assigned(), rhs.rhs.assigned()].iter())
.map(|(lhs, rhs)| {
loader.ecc_chip().select(&mut loader.ctx_mut().main(0), lhs, rhs, *condition)
loader.ecc_chip().select(loader.ctx_mut().main(0), lhs, rhs, *condition)
})
.collect::<Vec<_>>()
.try_into()
Expand Down Expand Up @@ -533,8 +533,8 @@ mod recursion {
let mut circuit = Self {
svk,
default_accumulator,
app: app.into(),
previous: previous.into(),
app: app,
previous: previous,
round,
instances,
as_proof,
Expand Down Expand Up @@ -570,7 +570,7 @@ mod recursion {
&self.svk,
&loader,
&self.previous,
Some(preprocessed_digest.clone()),
Some(preprocessed_digest),
);

let default_accmulator = self.load_default_accumulator(&loader).unwrap();
Expand Down
10 changes: 5 additions & 5 deletions snark-verifier/src/loader/evm/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ impl<T: Debug> PartialEq for Value<T> {
impl<T: Debug> Value<T> {
fn identifier(&self) -> String {
match self {
Value::Constant(_) | Value::Memory(_) => format!("{:?}", self),
Value::Negated(value) => format!("-({:?})", value),
Value::Sum(lhs, rhs) => format!("({:?} + {:?})", lhs, rhs),
Value::Product(lhs, rhs) => format!("({:?} * {:?})", lhs, rhs),
Value::Constant(_) | Value::Memory(_) => format!("{self:?}"),
Value::Negated(value) => format!("-({value:?})"),
Value::Sum(lhs, rhs) => format!("({lhs:?} + {rhs:?})"),
Value::Product(lhs, rhs) => format!("({lhs:?} * {rhs:?})"),
}
}
}
Expand Down Expand Up @@ -435,7 +435,7 @@ impl EvmLoader {

pub fn print_gas_metering(self: &Rc<Self>, costs: Vec<u64>) {
for (identifier, cost) in self.gas_metering_ids.borrow().iter().zip(costs) {
println!("{}: {}", identifier, cost);
println!("{identifier}: {cost}");
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions snark-verifier/src/loader/evm/test/tui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,10 +574,10 @@ impl Tui {

let line_number_format = if line_number == current_step {
let step: &DebugStep = &debug_steps[line_number];
format!("{:0>max_pc_len$x}|▶", step.pc, max_pc_len = max_pc_len)
format!("{:0>max_pc_len$x}|▶", step.pc)
} else if line_number < debug_steps.len() {
let step: &DebugStep = &debug_steps[line_number];
format!("{:0>max_pc_len$x}| ", step.pc, max_pc_len = max_pc_len)
format!("{:0>max_pc_len$x}| ", step.pc)
} else {
"END CALL".to_string()
};
Expand Down Expand Up @@ -636,7 +636,7 @@ impl Tui {
.map(|i| stack_item.byte(i))
.map(|byte| {
Span::styled(
format!("{:02x} ", byte),
format!("{byte:02x} "),
if affected.is_some() {
Style::default().fg(Color::Cyan)
} else if byte == 0 {
Expand All @@ -657,7 +657,7 @@ impl Tui {
}

let mut spans = vec![Span::styled(
format!("{:0min_len$}| ", i, min_len = min_len),
format!("{i:0min_len$}| "),
Style::default().fg(Color::White),
)];
spans.extend(words);
Expand Down Expand Up @@ -729,7 +729,7 @@ impl Tui {
.iter()
.map(|byte| {
Span::styled(
format!("{:02x} ", byte),
format!("{byte:02x} "),
if let (Some(w), Some(color)) = (word, color) {
if i == w {
Style::default().fg(color)
Expand All @@ -748,7 +748,7 @@ impl Tui {
.collect();

let mut spans = vec![Span::styled(
format!("{:0min_len$x}| ", i * 32, min_len = min_len),
format!("{:0min_len$x}| ", i * 32),
Style::default().fg(Color::White),
)];
spans.extend(words);
Expand Down
2 changes: 1 addition & 1 deletion snark-verifier/src/loader/evm/util/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ fn get_create2_address_from_hash(
]
.concat();

let hash = keccak256(&bytes);
let hash = keccak256(bytes);

let mut bytes = [0u8; 20];
bytes.copy_from_slice(&hash[12..]);
Expand Down

0 comments on commit aecfd45

Please sign in to comment.