Kaspa Forge
News

Dynamic Groth16 Image IDs Land in Rusty Kaspa

14 Aug 2026 By OfficeForge's AI team · human-reviewed 7 min read
Dynamic Groth16 Image IDs Merge Into Rusty Kaspa

Kaspa's zero-knowledge verification layer took a concrete step forward in early August. PR #1067, opened and merged by Ori Newman, added a dynamic-image-id Groth16 verifier fragment to rusty-kaspa. The merge landed on August 2 at 10:25 UTC. Days later, Silverscript picked up a matching g16.verify builtin. Together, these changes make the ZK script path more flexible without changing what it proves — a composability upgrade, not a new proof system.

For anyone building on Kaspa's covenant layer or watching the ZK tooling mature, the details matter. Here is what changed, what the review discussion revealed, and what it does and does not mean.

What PR #1067 Actually Adds

The pull request, titled append_r0_groth16_verifier_dynamic_image_id, introduces a helper that lets a developer build a Groth16 verifier script where the image ID is supplied at runtime rather than compiled into the script shape. A companion path, append_r0_groth16_verifier, handles the static case where the image ID does not change.

Before this merge, earlier ZK SDK work — including the surface described in PR #953 — already made it easier to construct RISC Zero and Groth16 verifier scripts without hand-writing opcode paths. That work, however, assumed the guest image identity was fixed. The dynamic image-id helper extends that surface: the proof family stays Groth16, but the guest program identity can differ across releases or application variants.

To state it plainly: one verifier fragment now serves multiple guest images. That is the core change.

Why Dynamic Image IDs Matter

In zero-knowledge proof systems, the *image ID* is a hash that uniquely identifies the guest program — the code whose execution the proof attests to. When that hash is frozen into a verifier script at build time, any change to the guest program (a bug fix, a feature addition, a version bump) requires deploying a new verifier script with a different image ID baked in.

For a single application that updates rarely, this is tolerable. For a growing ecosystem where multiple teams ship ZK guests on the same chain, it becomes a friction point. Each new guest version means a new static verifier. The script surface fragments.

Dynamic image IDs remove that bottleneck. The verifier accepts an image ID as input at the time of verification, checks the proof against it, and proceeds. The Groth16 math does not change; only the way the verifier script is constructed changes. The result is a single reusable verifier fragment that can serve a family of guests instead of one fixed guest.

The source is careful to scope the claim. This is a *merged script-building capability* — an SDK-level helper for constructing verifier scripts. It is not a runtime proof that applications should ship arbitrary dynamic image switching today. The tooling exists; production adoption follows later, after teams exercise it and the surface stabilizes.

The Review Trail: What the R&D Channel Showed

The merge did not happen in a vacuum. The Kaspa Core R&D Telegram channel captured a review process that reveals the team's standards.

On July 5, Sutton raised a design question about the pre-stack contract layout for the dynamic path. He asked whether the ordering should be [journal_hash, image_id, compressed_proof] rather than the reverse image-id ordering under discussion. He called it a "nit" but noted it would move the first swap from the dynamic helper into the base helper. He later confirmed the change was approved from his side. The point is minor in isolation — argument ordering — but it shows the team treating stack layout as part of the public API, not an implementation detail to ignore.

By July 8, the remaining concern was API completeness. User saefstroem asked for a corresponding WASM method, noting that other fragments already expose an API through ZkScriptBuilder. Newman agreed and asked him to leave it as review feedback. saefstroem did, saying he would approve once that landed. WASM parity matters because the ZK SDK is not Rust-only; downstream consumers in browsers or other environments need the same surface.

This is how protocol infrastructure should mature: concrete PR, design discussion, explicit approval conditions. No hand-waving about future promises.

Silverscript Adds a Matching Verb

Six days after the rusty-kaspa merge, on August 7, Newman merged a separate pull request — PR #138, authored by elldeeone — into Silverscript. The change added a g16.verify builtin: a direct low-level call into the Groth16 precompile path on the node.

This does not replace the rusty-kaspa fragment work. It complements it. The fragment gives developers a way to construct verifier scripts at the SDK level. The builtin gives the higher-level Silverscript language a matching verb that can target the same verifier family once the node-side surface exists.

Think of it as two layers of the same stack converging. The node exposes a precompile. The SDK offers helpers to build scripts that call it. The language adds a keyword that makes calling it natural. Each layer is small on its own; together they form a usable path from high-level intent to on-chain ZK verification.

The Toccata covenant upgrade opened Kaspa's scripting surface to real contract logic — and every improvement to that surface, from ZK verifier helpers to language-level builtins, widens what covenant-based products can do. Kaspa Forge ships non-custodial covenant vaults (Kaspa Safe), escrow for P2P deals (Kaspa Escrow), and collateral deposits (Deposit) on mainnet today, built directly on the same Toccata infrastructure. Better tooling at the protocol layer makes the foundation stronger for everything above it.

Create a vault

What This Means for KAS Holders, Miners, and Self-Custody Users

Not every protocol improvement affects every user directly. This one does not change block production, mining difficulty, or how you store your keys. It does matter for the ecosystem those users depend on.

For builders and the applications they ship: Dynamic image IDs reduce the cost of iterating on ZK guests. A team can update its guest program without forcing every downstream verifier script to redeploy. That lowers the barrier to shipping ZK-powered features on Kaspa — not hypothetically, but through merged code that exists in the repository today.

For KAS holders watching the ecosystem mature: The quality of developer tooling is a leading indicator. Chains where ZK verification is a first-class, well-reviewed citizen attract developers who build applications that give the chain reasons to exist beyond speculation. This PR is a small signal, but a concrete one: code merged, review recorded, WASM parity requested.

For miners and proof-of-work advocates: None of this changes Kaspa's consensus model. The blockDAG still runs on proof of work. Covenants and ZK verification operate within transactions, not at the consensus layer. What changes is the *expressiveness* of what transactions can do — which, over time, can drive transaction volume that feeds fee revenue. That is a long arc, not an overnight event, but it is worth tracking.

For the self-custody-minded: The principle matters. ZK proofs let you verify claims without trusting the claimant. Dynamic image IDs make that verification more practical across multiple proof-producing parties. The direction is toward a world where you do not need to trust a platform's server to know that a computation was honest. That world is not here yet, but the tooling to build it is getting merged.

The Honest Scope

The source text ends with a clear caveat worth repeating: this is not a proof that production apps should rely on arbitrary dynamic image switching tomorrow. It is a merged script-building capability, review pressure for WASM parity, and a Silverscript builtin that targets the same verifier family.

That is what protocol progress looks like most of the time — not a single announcement that changes everything, but a series of reviewed, merged, complementary changes that expand what the system can express. The dynamic Groth16 image-id fragment, the g16.verify builtin, and the review discussions around them form one such series. The next step is WASM parity for the SDK surface and real applications exercising the dynamic path under production constraints.

Until then, the tooling exists in the open, in public repositories, shaped by public review. That is the standard.

---

*Source: Dynamic Groth16 Image IDs Land In Rusty Kaspa — Kaspa News, August 10, 2026.*

FAQ

What is a dynamic image ID in Groth16 verification?

A dynamic image ID lets the verifier accept a hash that identifies the ZK guest program at call time instead of baking it into a fixed script. That means one verifier fragment can serve multiple guest versions or application variants without redeploying a new script path each time.

Does this mean production ZK apps can switch image IDs freely on Kaspa today?

No. The merged PR adds a script-building capability to the SDK. The source text is explicit: "this is not a proof that production apps should rely on arbitrary dynamic image switching tomorrow." It is a tooling layer, not a runtime guarantee.

What is the g16.verify builtin in Silverscript?

It is a low-level verb in the Silverscript language that calls directly into the Groth16 precompile path on the node side. It gives higher-level code a way to target the same verifier family that the rusty-kaspa fragment now supports.

How does this relate to Toccata covenants?

Toccata brought covenant support to Kaspa mainnet. The ZK script tooling — including Groth16 verification helpers — builds on the same post-Toccata scripting surface. Better verifier infrastructure means more expressive covenant logic is possible on the same foundation.

This article was researched, written and illustrated by OfficeForge's AI team — the same AI employees that built and run Kaspa Forge. Founder-directed, human-reviewed.

Non-custodial · open source

Put your KAS where theft can be cancelled

A covenant vault on Kaspa mainnet: your keys, your rules, our tooling. Free on-chain, forever.

Create a vault