Fold a Summation Circuit
The example extends the Quickstart by introducing a summation circuit .
While the quickstart features a basic identity mapping (), this example replaces it with a custom StepCircuit
that performs a summation operation, offering a more practical and detailed exploration of the Sirius framework.
The entire code for this example can be found at https://github.com/snarkify/sirius-simple-example
All changes from the quickstart are captured in this commit: https://github.com/snarkify/sirius-simple-example/commit/5b3e7bd449c1e10be2f90db4762838e066c2a10f
Why Build a Simple Example?
This example demonstrates how to move beyond basic operations by implementing a circuit that actively processes inputs, specifically summing them with themselves. This approach provides a clearer understanding of how to create and configure custom circuits using Sirius, making it an ideal next step after completing the quickstart.
Understanding Gates in Halo2 Frontend
In Halo2, a gate is a core component used to enforce specific constraints in a cryptographic circuit. At a high level, a gate defines a mathematical relationship between different values within the circuit, ensuring that certain conditions are met. For example, a multiplication gate might ensure that the product of two input values equals an output value.
Gates use symbolic expressions to represent these relationships, which are later enforced during the proof generation process. These expressions are crucial in ensuring the circuit operates correctly and can be verified by both the prover and the verifier.
For more details, please check our page on PLONKish
Circuit Configuration in fn configure
fn configure
In this section, we describe the specific changes made in the fn configure
function within the MyStepCircuit
implementation. This function is responsible for setting up the necessary components of the circuit to perform a simple summation operation.
Explanation
Selector (
s
):The selector
s
is initialized usingcs.selector()
. This selector is used to control when the summation gate is active, ensuring that the gate’s constraints are only enforced during the appropriate operations.
Advice Columns (
input
,output
):Two advice columns are introduced:
input
: This column holds the input values, which will be used in the summation operation.output
: This column stores the results of the summation (input + input
).
The equality check is enabled for the
input
column withcs.enable_equality(config.input)
, ensuring that the same value is used consistently within the circuit.
Gate Definition:
A gate named
"sum"
is created usingcs.create_gate
. This gate enforces the condition that the value in theoutput
column must be equal to the sum of theinput
column value with itself (i.e.,input + input
).The equation is constructed as
s * (input.clone() + input - output)
, wheres
is the selector controlling the gate, andinput
andoutput
are the values from the respective columns. This ensures that the circuit correctly performs the summation operation.
This configuration sets up the circuit to handle a simple summation operation, demonstrating how to use selectors and advice columns within the Halo2 framework.
Circuit Synthesis in fn synthesize_step
fn synthesize_step
In this section, we describe the specific changes made in the fn synthesize_step
function within the MyStepCircuit
implementation. This function is responsible for assigning values to the circuit's cells and enforcing the constraints defined during the configuration phase.
Explanation
Region Assignment:
The
layouter.assign_region
function is used to define a region in which the circuit's logic will be executed. Each iteration overz_i
represents a step in the circuit, with operations performed on each input value.
Selector Activation:
The selector
s
is enabled for each row in the region usingconfig.s.enable(&mut region, i)
. This activates the gate that enforces the summation operation defined in the configuration step. This gate will not work on the other lines. It is important that gates should be enabled regardless of the input on the same offsets.
Input Assignment:
The input value is assigned to the
input
column usingregion.assign_advice
. This step copies the value fromz_i
into theinput
column, where it will be used in the summation operation.
Equality Constraint:
The
region.constrain_equal(cell.cell(), input.cell())
function ensures that the original input cell (z_i
) is equal to the newly assignedinput
cell. This check enforces consistency in the values being used across the circuit.
Summation and Output Assignment:
The summation operation is performed, and the result is placed in the
output
column usingregion.assign_advice
. Specifically, the input value is doubled (input.value().copied() + input.value()
) and assigned to theoutput
column.
Result Collection:
The results from all iterations are collected into a vector and then converted into an array using
try_into
. This array represents the output values (z_out
) of the circuit for this step.
This function synthesizes the circuit by assigning values and ensuring that all constraints are satisfied, effectively performing the summation operation defined in the configuration.
Running the Example
1. First Run
To run the example for the first time, use the following command:
This will compile the project in release mode, which is optimized for speed. During this initial run, the #set-up-commitment-keys for the BN256 and Grumpkin curves will be generated and cached. This process may take some time, so running in release mode ensures it completes as quickly as possible.
2. Subsequent Runs
For subsequent runs, you can use the following command without the --release flag:
This will reuse the previously generated commitment keys, so the process will be faster, and there’s no need to recompile in release mode unless you're making significant changes or need the performance optimization again.
3. Expected Output
When the example runs successfully, you should see output indicating that the folding steps were executed and verified successfully:
Summary
In this section, we explored the implementation of the fn configure
and fn synthesize_step
functions within the MyStepCircuit
in the Sirius Simple Example. These functions work together to define and synthesize a simple step circuit that performs a summation operation.
fn configure
: This function sets up the circuit by defining the necessary components, including a selector and advice columns forinput
andoutput
. A custom gate is created to enforce the summation logic, where the input is doubled and stored in the output column.fn synthesize_step
: This function assigns values to the circuit's cells and ensures that all constraints are correctly enforced. It activates the selector, assigns the input values, performs the summation, and places the result in the output column, synthesizing the circuit for each computation step.
Together, these functions illustrate how to configure and synthesize a simple custom circuit within the Sirius framework, providing a clear example of circuit creation and execution. This example helps developers understand the practical steps involved in building and running custom circuits in a cryptographic context.
Last updated