Skip to content

Commit

Permalink
feat: make single_phase::assign_with_constraints generic
Browse files Browse the repository at this point in the history
Use const generic for max rotations accessed by the vertical gate.
This way we can re-use the code for RLC gate.
  • Loading branch information
jonathanpwang committed Aug 29, 2023
1 parent 6c80289 commit c8fea56
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 4 deletions.
7 changes: 6 additions & 1 deletion halo2-base/src/gates/flex_gate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ pub struct BasicGateConfig<F: ScalarField> {
}

impl<F: ScalarField> BasicGateConfig<F> {
/// Constructor
pub fn new(q_enable: Selector, value: Column<Advice>) -> Self {
Self { q_enable, value, _marker: PhantomData }
}

/// Instantiates a new [BasicGateConfig].
///
/// Assumes `phase` is in the range [0, MAX_PHASE).
Expand Down Expand Up @@ -103,7 +108,7 @@ pub struct FlexGateConfig<F: ScalarField> {
pub basic_gates: Vec<Vec<BasicGateConfig<F>>>,
/// A [Vec] of [Fixed] [Column]s for allocating constant values.
pub constants: Vec<Column<Fixed>>,
/// Max number of rows in flex gate.
/// Max number of usable rows in the circuit.
pub max_rows: usize,
}

Expand Down
11 changes: 8 additions & 3 deletions halo2-base/src/gates/flex_gate/threads/single_phase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl<F: ScalarField> VirtualRegionManager<F> for SinglePhaseCoreManager<F> {
assign_witnesses(&self.threads, config, region, break_points);
} else {
let mut copy_manager = self.copy_manager.lock().unwrap();
let break_points = assign_with_constraints(
let break_points = assign_with_constraints::<F, 4>(
&self.threads,
config,
region,
Expand All @@ -165,13 +165,17 @@ impl<F: ScalarField> VirtualRegionManager<F> for SinglePhaseCoreManager<F> {
///
/// For proof generation, see [assign_witnesses].
///
/// This is generic for a "vertical" custom gate that uses a single column and `ROTATIONS` contiguous rows in that column.
///
/// ⚠️ Right now we only support "overlaps" where you can have the gate enabled at `offset` and `offset + ROTATIONS - 1`, but not at `offset + delta` where `delta < ROTATIONS - 1`.
///
/// # Inputs
/// - `max_rows`: The number of rows that can be used for the assignment. This is the number of rows that are not blinded for zero-knowledge.
/// - If `use_unknown` is true, then the advice columns will be assigned as unknowns.
///
/// # Assumptions
/// - All `basic_gates` are in the same phase.
pub fn assign_with_constraints<F: ScalarField>(
pub fn assign_with_constraints<F: ScalarField, const ROTATIONS: usize>(
threads: &[Context<F>],
basic_gates: &[BasicGateConfig<F>],
region: &mut Region<F>,
Expand Down Expand Up @@ -206,7 +210,8 @@ pub fn assign_with_constraints<F: ScalarField>(
.insert(ContextCell::new(ctx.type_id, ctx.context_id, i), cell);

// If selector enabled and row_offset is valid add break point, account for break point overlap, and enforce equality constraint for gate outputs.
if (q && row_offset + 4 > max_rows) || row_offset >= max_rows - 1 {
// ⚠️ This assumes overlap is of form: gate enabled at `row_offset - delta` and `row_offset`, where `delta = ROTATIONS - 1`. We currently do not support `delta < ROTATIONS - 1`.
if (q && row_offset + ROTATIONS > max_rows) || row_offset >= max_rows - 1 {
break_points.push(row_offset);
row_offset = 0;
gate_index += 1;
Expand Down

0 comments on commit c8fea56

Please sign in to comment.