EIP-8025 -- zkEVM
Note: This document is a work-in-progress for researchers and implementers.
Introduction
This document specifies the cryptographic operations for zkEVM based execution
proofs enabling stateless validation of execution payloads.
Note: This specification provides placeholder implementations. Production
implementations should use established zkEVM systems.
Constants
All of the constants below are subject to change and one should not overindex on
them. MAX_PROOF_SIZE
, MAX_PROVING_KEY_SIZE
, and MAX_VERIFICATION_KEY_SIZE
are all arbitrary. MAX_WITNESS_SIZE
is the worst case witness size for the MPT
for a payload with a maximum gas limit of 30M gas.
Name |
Value |
MAX_PROOF_SIZE |
307200 (= 300KiB) |
MAX_PROVING_KEY_SIZE |
2**28 (= 256MiB) |
MAX_VERIFICATION_KEY_SIZE |
2**20 (= 1MiB) |
MAX_WITNESS_SIZE |
314572800 (= 300MiB) |
Custom types
Name |
SSZ equivalent |
Description |
ZKEVMProof |
Container |
Proof of execution of a program |
Cryptographic types
Note: ProgramBytecode
represents the bytecode for a particular execution
layer client. The size depends on the client; 16
is a placeholder.
Name |
SSZ equivalent |
Description |
ProgramBytecode |
ByteList[16] |
Execution layer program bytecode |
ProofID |
uint8 |
Identifier for proof system |
ProvingKey |
ByteList[MAX_PROVING_KEY_SIZE] |
Key used for proof generation |
VerificationKey |
ByteList[MAX_VERIFICATION_KEY_SIZE] |
Key used for proof verification |
ZKExecutionWitness |
ByteList[MAX_WITNESS_SIZE] |
zkEVM execution witness data for stateless program execution |
PrivateInput |
Container |
Private inputs for execution proof generation |
PublicInput |
Container |
Public inputs for execution proof generation and verification |
Containers
ZKEVMProof
| class ZKEVMProof(Container):
proof_data: ByteList[MAX_PROOF_SIZE]
proof_type: ProofID
public_inputs: PublicInput
|
| class PrivateInput(Container):
execution_payload: ExecutionPayload
execution_witness: ZKExecutionWitness
|
| class PublicInput(Container):
block_hash: Hash32
parent_hash: Hash32
|
Helper functions
Preprocessing
generate_keys
| def generate_keys(
program_bytecode: ProgramBytecode, proof_id: ProofID
) -> tuple[ProvingKey, VerificationKey]:
"""
Generate proving and verification keys for the given program bytecode and proof system.
"""
proving_key = generate_proving_key(program_bytecode, proof_id)
verification_key = generate_verification_key(program_bytecode, proof_id)
return (proving_key, verification_key)
|
Proof verification
verify_execution_proof_impl
| def verify_execution_proof_impl(proof: ZKEVMProof, verification_key: VerificationKey) -> bool:
"""
Verify a zkEVM execution proof using the verification key.
"""
if len(proof.proof_data) > MAX_PROOF_SIZE:
return False
return True
|
generate_verification_key
| def generate_verification_key(
program_bytecode: ProgramBytecode, proof_id: ProofID
) -> VerificationKey:
"""
Generate a verification key for the given program bytecode and proof system.
"""
verification_key = VerificationKey(program_bytecode + proof_id.to_bytes(1, "little"))
return verification_key
|
Proof generation
generate_execution_proof_impl
| def generate_execution_proof_impl(
private_input: PrivateInput,
proving_key: ProvingKey,
proof_id: ProofID,
public_inputs: PublicInput,
) -> ZKEVMProof:
"""
Generate a zkEVM execution proof using the proving key, private inputs and public inputs
"""
proof_data = hash(
public_inputs.block_hash + public_inputs.parent_hash + proof_id.to_bytes(1, "little")
)
return ZKEVMProof(
proof_data=ByteList(proof_data), proof_type=proof_id, public_inputs=public_inputs
)
|
generate_proving_key
| def generate_proving_key(program_bytecode: ProgramBytecode, proof_id: ProofID) -> ProvingKey:
"""
Generate a proving key for the given program bytecode and proof system.
"""
return ProvingKey(program_bytecode + proof_id.to_bytes(1, "little"))
|
verify_zkevm_proof
| def verify_zkevm_proof(
zk_proof: ZKEVMProof, parent_hash: Hash32, block_hash: Hash32, program_bytecode: ProgramBytecode
) -> bool:
"""
Public method to verify a zkEVM execution proof against block hashes.
"""
# Validate that public inputs match the provided parent and current block hash
if zk_proof.public_inputs.block_hash != block_hash:
return False
if zk_proof.public_inputs.parent_hash != parent_hash:
return False
_, verification_key = generate_keys(program_bytecode, zk_proof.proof_type)
return verify_execution_proof_impl(zk_proof, verification_key)
|
generate_zkevm_proof
| def generate_zkevm_proof(
execution_payload: ExecutionPayload,
execution_witness: ZKExecutionWitness,
program_bytecode: ProgramBytecode,
proof_id: ProofID,
) -> Optional[ZKEVMProof]:
"""
Public method to generate an execution proof for a payload.
"""
proving_key, _ = generate_keys(program_bytecode, proof_id)
public_inputs = PublicInput(
block_hash=execution_payload.block_hash, parent_hash=execution_payload.parent_hash
)
private_input = PrivateInput(
execution_payload=execution_payload, execution_witness=execution_witness
)
return generate_execution_proof_impl(private_input, proving_key, proof_id, public_inputs)
|