Repository navigation
perf(zk-verifier)!: verify from a key prepared at registration (storage v2) - #162
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
perf(zk-verifier)!: verify from a key prepared at registration (storage v2)
Preparing a Groth16 verifying key takes about half the cost of every proof verification. That covers deserializing it with point validation, computing
e(alpha, beta)and preparing-gammaand-deltain G2. Until now it ran on every proof, for a key that never changes.This PR prepares each key once, when it is registered, stores the result and verifies from it.
verify_proof(benchmark, same machine)validate_transaction(live dev node)Proofs arrive through public RPC and the transaction pool, so this halves what an invalid proof costs a node.
Design
orbinum-zk-verifier3.1.0 (new moduleprepared.rs, additive):VerifyingKey::prepared_bytes()validates and prepares a key and serializes it uncompressed.prepared_from_stored(bytes)reads that form back without re-validating its points, after a strict layout check:gamma_abccount is in1..=MAX_PUBLIC_INPUTS + 1;-gammaand-deltahave exactly 87 line coefficients each (fixed by BN254's Miller loop) and a clear infinity flag;MAX_PREPARED_VK_BYTES.ark-serializereserves aVecfrom its length prefix before reading it. The check runs first, so a forged prefix never reaches the allocator.pallet-zk-verifier0.17.0 (breaking: storage v2):PreparedKeys: (CircuitId, version) → prepared form.keys.rsowns all key storage. A key, its hash and its prepared form are written, removed and purged together there, and nothing else writesPreparedKeys.Migration
migrations::v2::MigrateToV2(VersionedMigration<1, 2, …>) is listed in the runtime'sMigrations.try-runtime,post_upgradechecks that each prepared form equals its key's preparation and that none is orphaned.Weights
Regenerated here without failures (
pallet_zk_verifierandpallet_shielded_pool,--steps 50 --repeat 20, official template), and the output compiles.weights.rsis not replaced: official numbers come from the reference machine.verify_proofregister_verification_keybatch_register_verification_keysset_active_version,unretire_versionremove_verification_key,purge_circuitThe last-but-one row predates this PR: since 0.16.0 these two calls validate the key, and the committed weights undercharge them. Both are Root-only.
Upgrade notes
spec_versionbump. If this ships with spec 18, nothing else is needed. If spec 18 is deployed first, this needs spec 19.Testing
Unit:
orbinum-zk-verifierark-serializewrites; the bound is exact. Refused: wrong length, absurd prefixes (u64::MAX,2^40), line counts that add up but differ, set infinity flagspallet-zk-verifierremoveandpurgeleave no orphan in any map. A re-registered version or purged circuit gets the new key's form, never a stale one. The prepared form wins over the raw key. Another circuit's form in the slot fails closedpost_upgradeaccepts the migrated state and refuses a tampered oneruntime-benchmarks,skip-proof-verification), plus the try-runtime test.pallet-shielded-pool,pallet-evm-precompile-shielded-poolandorbinum-runtimepass. clippy-D warnings, fmt,--no-default-featuresandtry-runtimecleanLive dev node, real proofs (
ts-tests/e2e-prepared-keys-live.cjs, 22/22, starting from the previous runtime):setCodeWithoutChecksRegression:
e2e-cross-tree-live.cjs42/42,e2e-spend-hardening-live.cjs78/78, key-rule checks 12/12.