For instructions on how to generate the exact proving and verifying keys we use in production on Ethereum Mainnet, see here.
Any Snark
has an associated Vec<Fr>
of public instances. We describe the format for the ones relevant to the AxiomV2Core
circuits below.
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
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
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
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
].