introduction
this post is a source code analysis of https://github.com/0xPolygonZero/plonky2
0. field
the lde in proving stage is conducted on extension field
1 | pub trait Field { |
1. Config
1.1 CircuitConfig
the default config is Self::standard_recursion_config()
with value as below
1 | Self { |
notes
routable wire It’s a wire that can be connected to other gates’ wires, rather than an “advice” wire which is for internal state. For example if we had a gate for computing x^8, we’d have two routable wires for the input and output, x and x^8. But if we wanted lower-degree constraints, we could add advice wires for the intermediate results x^2 and x^4
num_routed_wires, the default value is 80. For eample, for a arithmetic gate, it computes
const_0 * multiplicand_0 * multiplicand_1 + const_1 * addend
. i.e 2 wires for multiplicands and 1 wire for the addend and 1 for output. total is 4. therefore, the gate can havenum_routed_wires/4
operations, in this case, it is 20. the circuit builder will add gate when number of operations exceeds 20.
1.2 FriConfig
1 | pub struct FriConfig { |
2. Gates
1 | /// A custom gate. |
2.1 ArithmeticGate
1 | /// A gate which can perform a weighted multiply-add, i.e. `result = c0 x y + c1 z`. If the config |
- num_constants = 2
- degree = 3 ( three inputs)
- num_constraints = num_ops, default 20
2.2 PodeidonGate
All pubic inputs are hashed into 4 Hash Output. Therefore, PoseidonGate is required
1 | /// Evaluates a full Poseidon permutation with 12 state elements. |
2.2 ConstantGate
1 | /// A gate which takes a single constant parameter and outputs that value. |
num_constants
(a configured valuenum_consts
)degree
= 1 ( one inputs)num_constraints
=num_constants
2.3 PublicInputGate
1 | /// A gate whose first four wires will be equal to a hash of public inputs. the value 4 is hadcoded as the hash |
num_constants
=0degree
= 1num_constraints
= 4
3. Circuit Builder
1 | pub struct CircuitBuilder<F: RichField + Extendable<D>, const D: usize> { |
- virtual_target: This is not an actual wire in the witness, but just a target that help facilitate witness generation. In particular, a generator can assign a values to a virtual target, which can then be copied to other (virtual or concrete) targets. When we generate the final witness (a grid of wire values), these virtual targets will go away.
3.1 methods
1 | /// Adds a gate to the circuit, and returns its index. |
3.2 functions
1 | /// Finds a set of shifts that result in unique cosets for the multiplicative subgroup of size `2^subgroup_bits`. |
4. selectors
1 | /// Returns the selector polynomials and related information. |
5. permutation
1 | pub struct WirePartition { |
6. hash
defined in CircuitBuilder
1 | /// Hash function used for building Merkle trees. |
7. IOP
7.1 generator
1 | /// A generator which runs once after a list of dependencies is present in the witness. |
7.2 target
1 | /// A location in the witness. |
7.3 witness
A witness holds information on the values of targets in a circuit.
1 | /// `PartitionWitness` holds a disjoint-set forest of the targets respecting a circuit's copy constraints. |
8. Prover
1 | pub struct ProverOnlyCircuitData< |
8.1 prove_with_partition_witness
- compute full witness. get the matrix of all witness, row is num_of_wires, col is circuit gates number
- compute wire polynomials.
- compute wires commitment, save to
wires_commitment
- construct
challenger
, for oracle - get
num_challenges
forbetas
, andgamms
(used in permutation check) - compute partial products
partial_products_and_zs
. (num_of_products
polys) - compute lookup_polys
- compute `partial_products_zs_and_lookup_commitment
- sample
alphas
(composing polynomial) - compute_quotient_polys
10.1 z_hthe original1
2let points = F::two_adic_subgroup(common_data.degree_bits() + quotient_degree_bits);
let z_h_on_coset = ZeroPolyOnCoset::new(common_data.degree_bits(), quotient_degree_bits); // vanishing_polynomial, evaluated on the shifted cost. shift to make the polynomial evaluation to be none zeroz_h
(vanishing poly) is defined in subgroupH
, it is evaluated in a extension shifted cosetgK
, whereK
is the extented group.|K| = rate * |H|
\[h^n = (\omega^{rate})^n = (\omega^n)^{rate} = v^{rate} = 1 \]
where \(\omega, h \) is the generator ofK
andH
respectively,
On the shifted extended coset, every element is
\(g\omega^i, i \in [0, n*rate -1]\), wheren
is the number of gates (padded to make it power of 2).
the evaluate of z_h
over j
-th element on the coset is
\[(g\omega^j)^n -1 = g^n(\omega^n)^j = g^n\cdot v^j -1\]
since v^rate =1
, here this evaluation will repeat every rate
.
10.2
- batch compute
eval_vanishing_poly_base_batch
, batch size is 32
insideeval_vanishing_poly_base_batch
,1
2let constraint_terms_batch =
evaluate_gate_constraints_base_batch::<F, D>(common_data, vars_batch);
- compute
quotient_polys_commitment
- sample random
zeta
- construct the opening set
1
2
3
4
5
6
7
8
9
10
11
12
13OpeningSet::new(
zeta,
g, // let g = F::Extension::primitive_root_of_unity(common_data.degree_bits());
&prover_data.constants_sigmas_commitment,
&wires_commitment,
&partial_products_zs_and_lookup_commitment,
"ient_polys_commitment,
common_data
)
FriOpenings {
batches: vec![zeta_batch, zeta_next_batch],
} - construct fri_instance
- prove_openings