Update zk-proofs for Protocol 25: BN254 and Poseidon are live#72
Open
kaankacar wants to merge 1 commit into
Open
Update zk-proofs for Protocol 25: BN254 and Poseidon are live#72kaankacar wants to merge 1 commit into
kaankacar wants to merge 1 commit into
Conversation
CAP-0074 and CAP-0075 both read Status: Final, Protocol version: 25 in stellar-protocol, and mainnet is on protocol 27 — the skill was still calling them proposed and steering builders to attestation workarounds for capabilities that ship natively. - Status table: both CAPs marked Available (Protocol 25+), with the BN254 host-function surface named (crypto::bn254) - Toolchain table: all four rows now on-chain verifiable; UltraHonk routes through Nethermind's rs-soroban-ultrahonk verifier (the stack under OpenZeppelin's Confidential Tokens preview), with a maturity caveat - Noir walkthrough: on-chain verification is now option one; attestation demoted to a fallback - RISC Zero: Groth16-wrapped receipts verify natively - Circom: both curves work; walkthrough stays on bls12381 to match the canonical verifier, and the curve-mismatch pitfall now says match circuit to verifier rather than avoid bn128 - Poseidon Merkle guidance updated; last-verified line added at top - References: official ZK/privacy docs pages, the UltraHonk verifier, and the bn254 SDK module (link checked) Closes #51.
|
| | BLS12-381 ops (G1/G2 add, mul, MSM, pairing check, hash-to-curve, Fr arithmetic) | [CAP-0059](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0059.md) | **Available** (Protocol 22+) | | ||
| | BN254 host functions | [CAP-0074](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0074.md) | Proposed — check current status | | ||
| | Poseidon/Poseidon2 hash | [CAP-0075](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0075.md) | Proposed — check current status | | ||
| | BN254 ops (G1 add/mul/MSM, pairing check, Fr arithmetic — `crypto::bn254`) | [CAP-0074](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0074.md) | **Available** (Protocol 25+) | |
| | RISC Zero (STARK → Groth16 wrap) | Groth16 | BN254 | Gated on CAP-0074 — attest meanwhile | | ||
| | Circom + snarkjs (`-p bls12381`) | Groth16 | BLS12-381 | ✅ via CAP-0059 (Protocol 22+) | | ||
| | Circom + snarkjs (default `bn128`) | Groth16 | BN254 | ✅ via CAP-0074 (Protocol 25+) | | ||
| | Noir + Barretenberg | UltraHonk | BN254 | ✅ via CAP-0074 (Protocol 25+) — needs the [rs-soroban-ultrahonk](https://github.com/NethermindEth/rs-soroban-ultrahonk) verifier contract | |
| For real applications the per-proof flow is: client proves locally (WASM prover or native), submits `(proof, public_signals)` in a contract invocation, contract verifies + applies policy + updates state. | ||
|
|
||
| ## Walkthrough: Noir (off-chain verify + attestation, for now) | ||
| ## Walkthrough: Noir (UltraHonk, on-chain verifiable since Protocol 25) |
| ## Walkthrough: Noir (UltraHonk, on-chain verifiable since Protocol 25) | ||
|
|
||
| Noir's standard backend (Barretenberg) produces UltraHonk proofs over BN254 — neither the proof system nor the curve is on-chain verifiable on Stellar today. | ||
| Noir's standard backend (Barretenberg) produces UltraHonk proofs over BN254. Since Protocol 25 the curve is native (CAP-0074), and UltraHonk verification runs on-chain through [Nethermind's rs-soroban-ultrahonk](https://github.com/NethermindEth/rs-soroban-ultrahonk) verifier contract, whose only host calls are `env.crypto().bn254().g1_msm` and `pairing_check` — this is the stack OpenZeppelin's [Confidential Tokens developer preview](https://stellar.org/blog/developers/developer-preview-confidential-tokens-on-stellar) runs on (testnet). It is a young, community-maintained verifier: check its audit status and maturity before mainnet use. |
| Three ways to get a Noir statement on-chain, in order of preference: | ||
|
|
||
| Track CAP-0074 (BN254): when implemented, BN254 Groth16 verification becomes possible — but UltraHonk would additionally need a verifier implementation in-contract, so Groth16-based paths will land first. | ||
| 1. **On-chain UltraHonk verification** (Protocol 25+): deploy or call an [rs-soroban-ultrahonk](https://github.com/NethermindEth/rs-soroban-ultrahonk)-based verifier and submit `(proof, public inputs)` directly — trustless, no oracle. |
| | BN254 host functions | [CAP-0074](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0074.md) | Proposed — check current status | | ||
| | Poseidon/Poseidon2 hash | [CAP-0075](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0075.md) | Proposed — check current status | | ||
| | BN254 ops (G1 add/mul/MSM, pairing check, Fr arithmetic — `crypto::bn254`) | [CAP-0074](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0074.md) | **Available** (Protocol 25+) | | ||
| | Poseidon/Poseidon2 hash | [CAP-0075](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0075.md) | **Available** (Protocol 25+) | |
| - **Capability gating**: enable ZK flows only where required primitives are confirmed available; keep deterministic fallbacks and document the supported network/protocol matrix. | ||
|
|
||
| For Merkle-tree commitments (privacy pools, allowlists): until Poseidon (CAP-0075) lands, in-circuit-friendly hashing on-chain is expensive — design trees so the contract only needs root comparisons and membership proofs verified inside the SNARK. | ||
| For Merkle-tree commitments (privacy pools, allowlists): the Poseidon/Poseidon2 host functions (CAP-0075, Protocol 25+) make circuit-friendly hashing cheap on-chain, so contracts can recompute Poseidon Merkle roots and commitments directly. On pre-Protocol-25 targets, design trees so the contract only needs root comparisons and membership proofs verified inside the SNARK. |
| ``` | ||
|
|
||
| On Stellar today, use the **attestation pattern** (as with Noir): verify the receipt off-chain — locally or via a proving service — and have an authorized attester submit the journal + attestation to your contract. Once CAP-0074 (BN254) is implemented, the Groth16-wrapped receipt becomes verifiable natively with a BN254 verifier contract mirroring the BLS12-381 one above; the `IMAGE_ID` (which program ran) and journal digest become public inputs. See the [RISC Zero docs](https://dev.risczero.com/api) for the wrapping workflow. | ||
| Since Protocol 25 (CAP-0074), the Groth16-wrapped receipt verifies **natively on-chain**: a BN254 verifier contract mirroring the BLS12-381 one above, with the `IMAGE_ID` (which program ran) and the journal digest as public inputs. See the [RISC Zero docs](https://dev.risczero.com/api) for the wrapping workflow. The attestation pattern remains a fallback for STARK-only receipts (no Groth16 wrap) or pre-Protocol-25 targets. |
|
|
||
| ZK verification on Stellar. Capability is protocol- and SDK-version dependent — always verify CAP status, network version, and `soroban-sdk` host-function support before relying on a primitive. | ||
|
|
||
| > **Last verified against Protocol 27** (mainnet, July 2026). CAP-0074/0075 shipped in Protocol 25 "X-Ray" — if a doc tells you BN254 or Poseidon is "proposed", it predates that. |
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.
Closes #51.
Applies @briwylde08's report, with every claim independently re-verified before writing:
cap-0074.mdandcap-0075.mdin stellar-protocol both read Status: Final, Protocol version: 25, and a livegetVersionInfoagainst mainnet RPC returns protocol 27 — the capabilities have been live for months while the skill still said "Proposed" and steered builders to attestation workarounds.env.crypto().bn254().g1_msmandpairing_check(per the project's milestone docs); it is the stack under OpenZeppelin's Confidential Tokens developer preview. The skill links it with an explicit young-verifier maturity caveat.crypto::bn254module page on docs.rs resolves (link checked before adding).Changes follow the issue's suggested fix list: status table rows to Available (Protocol 25+), all four toolchain rows now on-chain verifiable, the Noir walkthrough rewritten with on-chain UltraHonk as option one and attestation demoted to fallback, RISC Zero's Groth16 wrap marked natively verifiable, the Circom walkthrough and curve-mismatch pitfall reframed from "avoid bn128" to "match circuit curve to verifier", Poseidon Merkle guidance updated, and a "Last verified against Protocol 27" line at the top so future staleness is self-documenting. Frontmatter description and the site card updated to match.
Also picked up the issue's optional suggestion and added the official ZK and Privacy docs pages to references.