Skip to content

Proof type encoding scheme #1

Description

@frisitano

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-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.:
    {
      "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"
  }
]
  • 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.

References

To be surfaced at the upcoming breakout call (guest program versioning).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestquestionFurther information is requested

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions