You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Once execution proofs start flowing between zkVMs, prover services (zkboost), CL clients consuming them, and zkAttestors verifying them, every consumer needs an unambiguous way to identify which proof variant they're dealing with — i.e. the specific (guest program, zkVM kind + version) pair that produced a given proof. Today there is no canonical scheme for this.
This issue captures the discussion held in the Eth R&D #l1-zkevm-protocol thread Proof type encoding (kicked off from l2beat/native-rollups#3 (comment)) and gathers feedback from EL and zkVM teams, who ultimately have to adopt whatever scheme is chosen.
What needs to be encoded
A proof_type identifier should let any consumer resolve, at minimum:
the guest program (the stateless validator compiled into the zkVM) — identified by its ELF / verification key,
the zkVM kind + version that compiled it.
The EL implementation a guest was built from is metadata of the guest — it shows up by convention in the guest name (e.g. ethrex-<commit>) but isn't an independent axis. Once the guest program is identified, the EL identity is fixed.
Downstream uses include:
CL / zkboost request APIs picking which guest to prove.
zkAttestors maintaining an allow-list of acceptable guests for the current fork.
ere-guests publishing release manifests pointing at the right ELF / VK URLs.
ethereum-package resolving which Ere version to spin up for a given proof type.
Operators / pandaops filtering which (guest, zkVM) combinations are valid to run together.
Benchmarks / debugging uniquely identifying what was proven — already done today in zkevm-benchmark-runs.
Proposals on the table
1. Combined string — interim consensus
Format: <guest-name>-<commit>/<zkvm-kind>-v<zkvm-version> — e.g. ethrex-33695e2/zisk-v0.16.1. The <guest-name>-<commit> portion is just the guest program's identifier (stateless validators are conventionally named after the EL they're built from plus a git commit).
Already used by zkevm-benchmark-runs for output paths.
Requires no coordination across teams and no new standard to comply with.
Human-readable; easy to grep, log, and key release artifacts on.
Maps cleanly to an ere-guests release manifest, e.g.:
Strictly sufficient for unique identification at the verification layer — a zkAttestor only needs the allow-list and the zkvm_guest_id attached to the gossiped proof; everything else (including which EL the guest came from) is captured in the verification key.
CL / zkboost can refer to entries by index into a shared list — no string parsing.
Opaque to humans — fine for verifiers, awkward for ops, debugging, and release management.
3. Independent semver for guest and zkVM — deferred
Treat guest program and zkVM versions as semver where the major version is tied to the zkEVM standards version they implement, so a static check can tell you whether a given (guest, zkVM) combination is compatible without waiting for runtime errors / undefined behaviour.
Discussion converged on this being the right long-term direction but likely premature: there is no zkVM or guest program today that can meaningfully use semver, and no zkEVM / guest fully complies with the standards yet. Coordinating a semver scheme now risks slowing iteration without a concrete payoff.
Worth revisiting once those layers stabilise. Open question: who maintains the compatibility matrix — us, zkVM teams, or operators (pandaops)?
Direction the thread converged on
Short term: standardise on the <guest>-<commit>/<zkvm>-vX.Y.Z string as the canonical proof_type — works today, no new standards required.
Underneath that: treat the hash-based zkvm_guest_id as the wire-/verifier-level identifier; the human-readable string is the operator- / release-level handle.
Defer semver / static-compatibility validation until guests and zkVMs implement enough of the zkEVM standards to make a versioned API boundary meaningful.
Asks
Confirm the interim <guest>-<commit>/<zkvm>-vX.Y.Z encoding as the canonical proof_type string and lock its grammar (separator, version pinning rules, guest identifier when no published version exists, commit length, etc.).
Decide whether the wire-level proof identifier should be the hash form, and pin its derivation (exact field set + ordering).
Decide where the per-fork allow-list of (zkvm_kind, zkvm_version, program_vk) entries lives and how it gets updated.
Decide whether ere-guests release manifests are the source of truth for resolving proof_type → (ere_version, elf_url, vk_url), and pin the schema.
EL and zkVM teams: feedback on whether this works for your release / versioning conventions, and where the future semver discussion should be tracked.
Background
Once execution proofs start flowing between zkVMs, prover services (zkboost), CL clients consuming them, and zkAttestors verifying them, every consumer needs an unambiguous way to identify which proof variant they're dealing with — i.e. the specific (guest program, zkVM kind + version) pair that produced a given proof. Today there is no canonical scheme for this.
This issue captures the discussion held in the Eth R&D
#l1-zkevm-protocolthread Proof type encoding (kicked off from l2beat/native-rollups#3 (comment)) and gathers feedback from EL and zkVM teams, who ultimately have to adopt whatever scheme is chosen.What needs to be encoded
A
proof_typeidentifier should let any consumer resolve, at minimum:The EL implementation a guest was built from is metadata of the guest — it shows up by convention in the guest name (e.g.
ethrex-<commit>) but isn't an independent axis. Once the guest program is identified, the EL identity is fixed.Downstream uses include:
ere-guestspublishing release manifests pointing at the right ELF / VK URLs.ethereum-packageresolving which Ere version to spin up for a given proof type.Proposals on the table
1. Combined string — interim consensus
Format:
<guest-name>-<commit>/<zkvm-kind>-v<zkvm-version>— e.g.ethrex-33695e2/zisk-v0.16.1. The<guest-name>-<commit>portion is just the guest program's identifier (stateless validators are conventionally named after the EL they're built from plus a git commit).zkevm-benchmark-runsfor output paths.ere-guestsrelease manifest, e.g.:{ "release": { "ethrex-33695e2/zisk-v0.16.1": { "ere_version": "0.8.1", "elf_url": "https://github.com/eth-act/ere-guests/releases/download/v0.9.0/stateless-validator-ethrex-zisk.elf", "vk_url": "https://github.com/eth-act/ere-guests/releases/download/v0.9.0/stateless-validator-ethrex-zisk.vk" } } }2. Hash-based identifier
zkvm_guest_id = hash(zkvm_kind || zkvm_version || program_vk), with a per-fork allow-list maintained by zkAttestors:[ { "zkvm_kind": "zisk", "zkvm_version": "v0.16.1", "program_vk": "0x01....ef" } ]zkvm_guest_idattached to the gossiped proof; everything else (including which EL the guest came from) is captured in the verification key.3. Independent semver for guest and zkVM — deferred
Treat guest program and zkVM versions as semver where the major version is tied to the zkEVM standards version they implement, so a static check can tell you whether a given (guest, zkVM) combination is compatible without waiting for runtime errors / undefined behaviour.
Direction the thread converged on
<guest>-<commit>/<zkvm>-vX.Y.Zstring as the canonicalproof_type— works today, no new standards required.zkvm_guest_idas the wire-/verifier-level identifier; the human-readable string is the operator- / release-level handle.Asks
<guest>-<commit>/<zkvm>-vX.Y.Zencoding as the canonicalproof_typestring and lock its grammar (separator, version pinning rules, guest identifier when no published version exists, commit length, etc.).(zkvm_kind, zkvm_version, program_vk)entries lives and how it gets updated.ere-guestsrelease manifests are the source of truth for resolvingproof_type → (ere_version, elf_url, vk_url), and pin the schema.References
#l1-zkevm-protocol→ Proof type encoding): https://discord.com/channels/595666850260713488/1500852681584017460To be surfaced at the upcoming breakout call (guest program versioning).