Skip to content

tvm_vm: round-trip the real deposit RLC proof through ZKHALO2VERIFYWITHVK#247

Open
SergeSPb wants to merge 7 commits into
serhii/node-3406-vergrth16-with-vkfrom
pruvendo/deposit-rlc-vkblob-v2
Open

tvm_vm: round-trip the real deposit RLC proof through ZKHALO2VERIFYWITHVK#247
SergeSPb wants to merge 7 commits into
serhii/node-3406-vergrth16-with-vkfrom
pruvendo/deposit-rlc-vkblob-v2

Conversation

@SergeSPb
Copy link
Copy Markdown
Collaborator

Summary

Adds the first on-node end-to-end verification of a real EVM→AN deposit proof through the ZKHALO2VERIFYWITHVK opcode (v2 circuit_shape = Rlc).

  • New test round_trip_deposit_rlc_real_proof_returns_true in tvm_vm/src/tests/test_halo2_with_vk.rs drives the deposit-prover's v2 RLC triple — EthCircuitImpl VkBlob + 7 public inputs + Blake2b SHPLONK proof — through the node's exact executor (execute_zkhalo2_verify_with_vk) and asserts it returns true.
  • Adds a 12 KB HALO2TVM bundle fixture (tvm_vm/halo2_test_data/deposit_rlc_bundle.bin).

Why the fixture was regenerated

The opcode rebuilds its verifier KZG params from the chain-wide embedded points (KZG_{G0,G2,S_G2}_BYTES). The deposit-prover originally used the Hermez ceremony, whose s_g2 = [tau]·G2 differs from the chain ceremony — so every SHPLONK pairing check failed. The fixture is now generated against the chain's own kzg_bn254_19.srs (downsized to the deposit circuit's k=18), so g2/s_g2 match byte-for-byte and the proof verifies.

Test plan

  • cargo test -p tvm_vm --features gosh --lib round_trip_deposit_rlc_real_proof_returns_trueok
  • CI green on the opcode line

Sergey Egorov and others added 7 commits May 29, 2026 00:40
…K read

Lets the opcode verify deposit-prover proofs (axiom-eth EthCircuitImpl, RLC +
keccak coprocessor), not just BaseCircuitBuilder/DarkDex circuits.

- zk_halo2_with_vk_bundle.rs: v2 circuit_shape byte (offset 10) + BundleConfig
  {Base(BaseCircuitParams), Rlc(EthCircuitParams JSON)}. v1 stays byte-compatible
  (shape pinned 0). +6 parse tests.
- zk_halo2_with_vk.rs: get_or_insert_vk branches read_base_vk (BaseCircuitBuilder)
  vs read_rlc_vk (EthCircuitImpl<Fr, Noop>, empty instructions — VK read rebuilds
  the CS from EthCircuitParams only). +3 rlc_branch_tests (real EthCircuitImpl VK
  keygen → byte-for-byte round-trip; Base reader does not round-trip an RLC VK).
- adds axiom-eth dep (gosh feature). Build requires a NIGHTLY toolchain because
  snark-verifier-sdk uses trait_alias; the stable BaseCircuitBuilder path is
  unaffected.

NOTE: the workspace-root [patch] block is provisional / machine-local — it pins
the gosh halo2 fork (bump-halo2-lib-v0.4.1, stable) and a one-line axiom-eth fork
(gosh-stable-rlcmanager-assignment) via file:// / path. Swap for public git revs
once those PRs land. See acki-nacki-bridge docs/zkhalo2verifywithvk_reference.md §15.

Co-authored-by: Cursor <cursoragent@cursor.com>
The gosh feature's deposit-RLC path (ZKHALO2VERIFYWITHVK reading axiom-eth
EthCircuitImpl VKs) pulls snark-verifier-sdk, which uses trait_alias and only
builds on nightly. Pin channel = "nightly" so cargo build / CI select it without
an explicit +nightly. Verified against rustc 1.98.0-nightly (57d06900f 2026-05-27).

Co-authored-by: Cursor <cursoragent@cursor.com>
…THVK

Add `round_trip_deposit_rlc_real_proof_returns_true` (+ a 12 KB bundle fixture)
that drives the deposit-prover's v2 RLC triple — EthCircuitImpl VkBlob, 7 public
inputs, Blake2b SHPLONK proof — through the node's exact opcode executor
(`execute_zkhalo2_verify_with_vk`, circuit_shape = Rlc) and asserts it verifies
true. This is the first end-to-end on-node verification of a real EVM->AN deposit
proof. The fixture was regenerated against the chain's own KZG ceremony
(kzg_bn254_19.srs), not Hermez, so the embedded g2/s_g2 points match.

Co-authored-by: Cursor <cursoragent@cursor.com>
The CI Lint job runs `cargo +nightly fmt --all -- --check` on the whole
workspace against the floating latest nightly + the repo's rustfmt.toml
(style_edition 2024, wrap_comments, imports_granularity=Item, ...). It was red
on this PR's head — partly on the new deposit-RLC files (doc-comment wrapping in
test_halo2_with_vk.rs, line wrapping in zk_halo2_with_vk{,_bundle}.rs) and partly
on pre-existing opcode/executor files that drifted out of fmt under newer
nightlies. Formatting-only; no logic changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
…htly

The Lint job used dtolnay/rust-toolchain@nightly + `cargo +nightly fmt`, i.e. the
latest nightly each run — non-reproducible and the cause of fmt bitrot. Pin to
nightly-2026-05-28 (rustc 1.98.0-nightly 57d06900f 2026-05-27), the exact build
the RLC gosh stack (axiom-eth -> snark-verifier-sdk, both #![feature(trait_alias)])
was verified against and that the deposit opcode test + Lint passed on. This is
our de-facto "stable" for the RLC path; rust-toolchain.toml matches. Bump
deliberately and in lockstep going forward.

Co-authored-by: Cursor <cursoragent@cursor.com>
The RLC `[patch]` pointed at a local `file://` path (halo2-lib) and a
relative path (axiom-eth) that exist only on the author's machine, so
both CI Test jobs failed at dependency resolution. Repoint them at the
published forks:
  - github.com/SergeSPb/halo2-lib-zkevm-sha256-and-bls12-381@bump-halo2-lib-v0.4.1
  - github.com/SergeSPb/axiom-eth@gosh-stable-rlcmanager-assignment
(temporary publish-for-CI homes; swap to gosh-sh once those PRs land).

Also switch the `Priority Units` job to the pinned nightly-2026-05-28:
it builds `--features tvm_vm/gosh`, which pulls axiom-eth /
snark-verifier-sdk — those require nightly (`trait_alias`). `tvm_client`
stays on stable (it doesn't touch the halo2 stack).

Co-authored-by: Cursor <cursoragent@cursor.com>
The caller-VK Groth16 verifier was added to verify gnark-wrapped Halo2
deposit proofs on the AN side. That design is retired: the deposit-prover
now emits a Halo2 SHPLONK proof verified *natively* by ZKHALO2VERIFYWITHVK
(0xC7 0x4A), and TokenBridge.finalizeDeposit uses the Halo2 path — nothing
calls the Groth16-with-VK opcode anymore.

Remove the opcode end to end: handler (execute_vergrth16_with_vk) + gas
constant/accessors + dispatch (0x52) + assembler mnemonic/round-trip entry
+ the unit-test module. The hard-coded-VK VERGRTH16 (zkLogin) and the Halo2
opcodes (0x49 ZKHALO2VERIFY, 0x4A ZKHALO2VERIFYWITHVK) are untouched.

Note: the deleted test also had a stale program byte (ran 0xC7 0x49, the
Halo2 DarkDex verifier, instead of 0x52), so it fed Groth16 bytes to the
wrong opcode and "rejected" a valid proof — the CI failure that surfaced
once the build was fixed. Removing the dead opcode resolves it.

tvm_vm gosh suite: 129/129 green; assembler round-trip green.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant