2 stable releases
2.0.13 | Mar 12, 2024 |
---|---|
2.0.12 | Jan 21, 2024 |
#8 in #block-header
1MB
17K
SLoC
AxiomV2Core ZK Circuits
Proving and Verifying Key Generation
For instructions on how to generate the exact proving and verifying keys we use in production on Ethereum Mainnet, see here.
Public Instance Formats
Any Snark
has an associated Vec<Fr>
of public instances. We describe the format for the ones relevant to the AxiomV2Core
circuits below.
EthBlockHeaderChainCircuit
pub struct EthBlockHeaderChainInput<F> {
header_rlp_encodings: Vec<Vec<u8>>,
num_blocks: u32, // num_blocks in [0, 2 ** max_depth)
max_depth: usize,
network: Network,
_marker: PhantomData<F>,
}
This depends on a max_depth
parameter. The public instances are:
prev_hash
:H256
as twoFr
elements in hi-lo formatend_hash
:H256
as twoFr
elements in hi-lo formatstart_block_number . end_block_number
: we assume both numbers areu32
and encode them to a singleFr
element asstart_block_number * 2^32 + end_block_number
merkle_mountain_range
: a sequence ofmax_depth + 1
H256
elements, each encoded as twoFr
elements in hi-lo format
Notes:
prev_hash
is the parent hash of block numberstart_block_number
end_hash
is the block hash of block numberend_block_number
end_block_number - start_block_number
is constrained to be<= 2^max_depth
- This was previously assumed in
axiom-eth
v0.1.1
but not enforced because the block numbers are public instances, but we now enforce it for safety
- This was previously assumed in
merkle_mountain_range
is ordered from largest peak (depthmax_depth
) first to smallest peak (depth0
) last
EthBlockHeaderChainIntermediateAggregationCircuit
pub struct EthBlockHeaderChainIntermediateAggregationInput {
num_blocks: u32,
snarks: Vec<Snark>,
pub max_depth: usize,
pub initial_depth: usize,
}
This circuit takes two EthBlockHeaderChainCircuit
s and aggregates them. The public instances are:
4 * LIMBS = 12
Fr
elements for the two BN254G1
points representing the accumulator, used by the verifier for a pairing checkprev_hash
:H256
as twoFr
elements in hi-lo formatend_hash
:H256
as twoFr
elements in hi-lo formatstart_block_number . end_block_number
: we assume both numbers areu32
and encode them to a singleFr
element asstart_block_number * 2^32 + end_block_number
merkle_mountain_range
: a sequence of2^{max_depth - initial_depth} + initial_depth
H256
elements, each encoded as twoFr
elements in hi-lo format
Notes:
- Same notes as
EthBlockHeaderChainCircuit
except thatmerkle_mountain_range
is not actually a Merkle mountain range: we recover a Merkle mountain range of lengthmax_depth + 1
by forming a Merkle mountain range from leavesmerkle_mountain_range[..2^{max_depth - initial_depth}]
and then appendingmerkle_mountain_range[2^{max_depth - initial_depth}..]
to the end of it.- The reason is that we want to delay Keccaks
EthBlockHeaderChainRootAggregationCircuit
pub struct EthBlockHeaderChainRootAggregationInput {
/// See [EthBlockHeaderChainIntermediateAggregationInput]
pub inner: EthBlockHeaderChainIntermediateAggregationInput,
/// Succinct verifying key (generator of KZG trusted setup) should match `inner.snarks`
pub svk: Svk,
prev_acc_indices: Vec<Vec<usize>>,
}
This circuit takes two EthBlockHeaderChainIntermediateAggregationCircuit
s and aggregates them. The public instances are:
4 * LIMBS = 12
Fr
elements for the two BN254G1
points representing the accumulator, used by the verifier for a pairing checkprev_hash
:H256
as twoFr
elements in hi-lo formatend_hash
:H256
as twoFr
elements in hi-lo formatstart_block_number . end_block_number
: we assume both numbers areu32
and encode them to a singleFr
element asstart_block_number * 2^32 + end_block_number
merkle_mountain_range
: a sequence ofmax_depth + 1
H256
elements, each encoded as twoFr
elements in hi-lo format
Notes:
- Same notes as
EthBlockHeaderChainCircuit
- This circuit is the same as
EthBlockHeaderChainIntermediateAggregationCircuit
except that it does do the final Keccaks to form the full Merkle mountain range
Passthrough Aggregation Circuit
This is from axiom-eth
.
pub struct InputMerkleAggregation {
pub snarks: Vec<EnhancedSnark>,
}
We will only use this where snarks
has length 1 and consists of a single snark. In this case it is an AggregationCircuit
that purely passes through the public instances of the single snark in snarks
, discarding old accumulators (there is no Merkle root computation because there is only one snark).
We will use this snark on EthBlockHeaderChainRootAggregationCircuit
or itself if we want multiple rounds of passthrough aggregation.
The public instances are exactly the same as for EthBlockHeaderChainRootAggregationCircuit
.
Dependencies
~31–51MB
~1M SLoC