consensus-specs icon indicating copy to clipboard operation
consensus-specs copied to clipboard

Add kzg block hashes to the public inputs when verifying optional execution proofs

Open kevaundray opened this issue 6 months ago • 1 comments

Found by @jsign

The public inputs should include everything needed by a CL from the EL when called via the engine API.

Currently verifying a proof lets us know that a block's STF was valid, however the CL also needs to check that the blob transactions included in that block were the expected ones.

kevaundray avatar Oct 06 '25 16:10 kevaundray

Expanding a bit more on this since it is more general than kzg commitments.

Today, the CL passes the ExecutionPayload plus extra data(e.g., versioned hashes, requests, parent beacon root) to the engine api, which does two things: 1. Constructs the EL block from this data, 2. Verifies the STF.

From a zkCL perspective, the proof must verify both 1) and 2), and not only 2). If we only do 2), this means that the public input block_hash could be committing to "who knows" which data (e.g., maybe the block_number doesn't match the ExecutionPayload block number, or timestamp, or actually any field).

Two potential solutions:

  • The public inputs is block_hash + some sort of execution_payload_hash + (kzg, requests, ...) extra data, and the guest program proves both 1) and 2) as explained above.
  • The CL actually implements the current is_valid_block_hash (instead of relying on the engine API). Given that the block_hash is valid, then the proof can only prove 2) (i.e., the STF) since the block_hash input was validated outside the proof.

jsign avatar Oct 08 '25 22:10 jsign