Chapter 1에서는 하나의 큰 region만 다루었다.
인접한 셀을 referring하여 연산을 반복하면 되어 쉬운 방법이나, 대체로 이렇게 하지 않고, 일반적인 소프트웨어 공학이나 하드웨어 디자인처럼 작게 나누어 큰 것으로 만든다.
region을 이용하는 것은 logical 유닛을 생성하는 것이다.
사실, 일반적인 circuit에서 gate라고 불리는 것은(addition gate/multiplication gate) Halo2에서 특정 게이트가 활성화된 지역과 더 유사하다.
그래서 더 복잡한 서킷을 모듈러한 방법으로 만들 수 있게 한다.
Fixed Column : a column containing values fixed by the verifier which the prover cannot change.
q_enable : 이것도 또한 fixed column이나,column::Fixed가 더 general한 방식
So far, we have created multiple regions
But every method has been implemented on the TestCircuit struct like writing Java with only a single class.
To modularize our gadgets, we use pattern called chips
Chip is equivalent to a class in OOP, grouping related functionality together
[Halo2 Circuit = Layout (Region-based) + Constraints (Gate-based)]
|
|-- Region: assigns values (witnesses)
|
|-- Gate: enforces constraints (polynomials)
An instance of Arithmeticchip can be created at configuration time for the circuit:
Vertical (Stacked) :
// stacked layout
meta.create_gate("mul", |meta| {
let a = meta.query_advice(advice, Rotation::cur()); // row 0
let b = meta.query_advice(advice, Rotation::next()); // row 1
let c = meta.query_advice(advice, Rotation(2)); // row 2
vec![a * b - c]
});
Advice column (w)
┌───────────────┐
row 0 │ a │ ← input 1
row 1 │ b │ ← input 2
row 2 │ c │ ← output
└───────────────┘
Horizontal layout :
// horizontal layout
meta.create_gate("mul", |meta| {
let a = meta.query_advice(w0, Rotation::cur()); // row 0, col w0
let b = meta.query_advice(w1, Rotation::cur()); // row 0, col w1
let c = meta.query_advice(w2, Rotation::cur()); // row 0, col w2
vec![a * b - c]
});
w0 w1 w2
┌──────┬────────┬──────────┐
row 0 │ a │ b │ c │ ← all in the same row
└──────┴────────┴──────────┘
✅ Pros
Rotation::cur())❌ Cons: Uses more columns