wienerlabs
mosaic
Rustโœจ New

One substrate, many proofs. Trait-based on-chain verifier library for Solana supporting Groth16, PLONK, FRI-STARK, and Nova.

Last updated Jun 8, 2026
10
Stars
2
Forks
77
Issues
0
Stars/day
Attention Score
53
Language breakdown
No language data available.
โ–ธ Files click to expand
README

Mosaic

Proof-system-agnostic on-chain verification for Solana.
One API. Multiple proving systems. No Groth16 wrapping required.

CI License: Apache-2.0 OR MIT MSRV: 1.85.0 Release: v0.9.16-multi-system-demo Demo: /demo/sudoku Roadmap Audit: ready for review

The Solana ecosystem has exactly one production-grade ZK verifier today (Light Protocol's groth16-solana). Every other proof system โ€” PLONK, HyperPlonk, Halo2-KZG, FRI-STARK, Risc0, Nova, ProtoStar โ€” either requires awkward Groth16 wrapping (see Bonsol/Anagram's Risc0-in-Circom workaround) or cannot be verified on Solana L1 at all.

Mosaic fixes that. Pick a proving system via a generic parameter; swap systems without touching program logic.

use mosaic_core::{ProofSystem, ProofSystemId};
use mosaic_groth16::Groth16Verifier;
// (Future: use mosaic_plonk::PlonkKzgBn254;)

let backend = mosaic_core::syscall::host::HostBackend::new(); let verifier = Groth16Verifier::<_, false>::new(&backend);

verifier.verify(&vkbytes, &proofbytes, &publicinputsbytes)?; // ^^ same call shape for every supported proving system

Status

Phase-3 bodies (this release): all four Phase-3 verifier pipelines now run end-to-end and return Ok(()) on structurally well-formed proofs. Scaffold caveats per family are documented for fixture-driven tightening in upcoming 0.4.x releases. Phase-2 production verifiers (Groth16, PLONK) remain unchanged at their frozen CU budgets.

| Component | Status | On-chain CU | |---|---|---| | mosaic-core (traits, errors, syscall abstraction) | โœ… Production | โ€” | | mosaic-groth16 single verify | โœ… Production | 83,574 | | mosaic-groth16 batch verify (N=5, Bowe-Gabizon) | โœ… Production | 258,397 (52K/proof, -38%) | | mosaic-plonk KZG-PLONK BN254 verifier | โœ… Production | 968,457 | | mosaic-hyperplonk KZG BN254 verifier | ๐ŸŸ  Phase-3 body (structural, scaffold caveats) | target ~505K | | mosaic-halo2 KZG BN254 verifier (PSE fork) | ๐ŸŸ  Phase-3 body (structural, scaffold caveats) | target ~580K | | mosaic-stark FRI-STARK (Goldilocks / BabyBear / Mersenne31) | ๐ŸŸ  Phase-3 body (structural, scaffold caveats) | target ~9.4M | | mosaic-nova Nova / HyperNova / ProtoStar folding | ๐ŸŸ  Phase-3 body (structural, scaffold caveats) | target ~885K | | mosaic-serde snarkjs adapter (Groth16 + PLONK) | โœ… Production | โ€” | | mosaic-serde arkworks adapter | โœ… Production | โ€” | | mosaic-serde gnark / halo2 / plonky3 / risc0 | ๐Ÿšง Stub (Phase 3) | โ€” | | mosaic-chunked data model | โœ… Implemented | โ€” | | mosaic-chunked instruction handlers | โœ… Production | โ€” | | Reference Solana program | โœ… 319 KB SBF ELF (30.4% of 1 MB cap; 12 cryptographic gates wired) | โ€” | | Differential test harness (arkworks + snarkjs fixture) | โœ… Production (Groth16 + PLONK; Phase-3 extension tracked) | โ€” | | Property-test coverage (proptest, sessions 36-72) | โœ… 549 lib tests across 12 crates (+152 proptest + 9 shared primitives lifted in audit-coverage sweep) | โ€” | | Audit runbook | โœ… docs/audit-coverage-runbook.md โ€” reproduce + extend recipes for external review firms | โ€” | | BPF CU regression bench (bpf-bench) | โœ… 7 systems: Groth16 (single + batch), KZG-PLONK, HyperPlonk, Halo2, Nova, FRI-STARK; Nova/FriStark dispatch byte mismatch fixed in v0.9.12 | โ€” | | Host criterion bench (wall-clock baseline) | โœ… 5 systems: Groth16, HyperPlonk, Halo2, Nova, FRI-STARK | โ€” | | Fuzz harnesses (sessions 54-59 / 109-114) | โœ… 37 targets including 10 compression harnesses (Phase-2: Halo2/Groth16/PLONK; Phase-3: HyperPlonk/Nova) | โ€” | | Compression infrastructure (session 114) | โœ… Every BN254 verifier (5/5): proof + VK round-trip APIs, 59 round-trip tests, 4 fuzz + 4 criterion benches | โ€” | | On-chain compressed-verify (session 116) | โœ… VerifyCompressedProof = 0x03 instruction โ€” 5/5 BN254 verifiers callable via compressed wire format; 50 % bandwidth saving for Groth16, 40-42 % for PLONK/Nova | โ€” | | SBF integration tests (sessions 113 + 116) | โœ… 13 tests across all 8 declared ProofSystemId bytes + 1 alias + 1 unknown-byte negative + 3 compressed-path tests | โ€” | | Audit-firm handoff doc (session 115) | โœ… AUDIT-CHECKLIST.md โ€” crate-by-crate scope/non-scope + reproducibility recipe + open-questions list | โ€” | | External audit | ๐Ÿ”ด Not yet commissioned (AUDIT-CHECKLIST.md ready to send for scoping quote) | โ€” |

See AUDIT.md for audit history and SECURITY.md for the responsible-disclosure policy.

Quick start

Add to your program

[dependencies]
mosaic-core      = { version = "0.1", features = ["solana"] }
mosaic-groth16   = { version = "0.1", features = ["solana"] }
solana-program   = "2.1"

Verify a Groth16 proof on-chain

use mosaic_core::{
    proof_system::{ProofSystem, ProofSystemId},
    syscall::solana::SolanaSyscallBackend,
};
use mosaic_groth16::Groth16Verifier;

pub fn process_instruction( programid: &Pubkey, _accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { let backend = SolanaSyscallBackend::new(); let verifier = Groth16Verifier::<_, false>::new(&backend); let (vk, rest) = decodelp(instructiondata)?; let (proof, pibytes) = decodelp(rest)?; verifier.verify(vk, proof, pibytes).maperr(Into::into) }

Set the compute budget on the client

use solanasdk::computebudget::ComputeBudgetInstruction;

let cuix = ComputeBudgetInstruction::setcomputeunitlimit(200_000); let verifyix = mosaicsdk::buildverifyproof_ix(&request)?;

transaction.add(&cu_ix); transaction.add(&verify_ix);

See docs/compute-unit-budget.md for per-system targets.

Generate a proof off-chain (snarkjs โ†’ Mosaic)

use mosaic_serde::snarkjs::SnarkjsCodec;

let bundle = SnarkjsCodec::decodebundle(&proofjson, &vkjson, &publicinputs_json)?; // bundle.vk, bundle.proof, bundle.public_inputs are now canonical bytes

Pre-flight verification (catch bugs before on-chain)

mosaic_sdk::preflight(&request)?;
// Runs the same verifier locally with arkworks. Fails fast.

Workspace topology

mosaic/
โ”œโ”€โ”€ crates/
โ”‚   โ”œโ”€โ”€ mosaic-core/      # ProofSystem, SyscallBackend, errors
โ”‚   โ”œโ”€โ”€ mosaic-groth16/   # BN254 Groth16 verifier
โ”‚   โ”œโ”€โ”€ mosaic-plonk/     # KZG-PLONK (Phase 2 stub)
โ”‚   โ”œโ”€โ”€ mosaic-stark/     # FRI-STARK (Phase 3 stub)
โ”‚   โ”œโ”€โ”€ mosaic-nova/      # Folding scheme (Phase 3 stub)
โ”‚   โ”œโ”€โ”€ mosaic-serde/     # snarkjs / arkworks / gnark / halo2 / plonky3 / risc0 adapters
โ”‚   โ”œโ”€โ”€ mosaic-chunked/   # Large-proof upload protocol
โ”‚   โ”œโ”€โ”€ mosaic-program/   # Reference Solana on-chain program
โ”‚   โ”œโ”€โ”€ mosaic-sdk/       # Client-side Rust SDK
โ”‚   โ”œโ”€โ”€ mosaic-bench/     # Criterion + bpf-bench
โ”‚   โ””โ”€โ”€ mosaic-fuzz/      # libFuzzer harnesses
โ”œโ”€โ”€ docs/
โ”‚   โ”œโ”€โ”€ adr/              # Architecture decision records (5 ADRs)
โ”‚   โ”œโ”€โ”€ threat-model.md
โ”‚   โ””โ”€โ”€ compute-unit-budget.md
โ””โ”€โ”€ tests/
    โ”œโ”€โ”€ differential/     # arkworks vs Mosaic oracle tests
    โ”œโ”€โ”€ integration/      # On-chain devnet tests (Phase 2)
    โ””โ”€โ”€ fixtures/         # Sample proofs from each framework

Design principles

  • Object-safe ProofSystem trait. Single byte-slice API; the on-chain
dispatcher monomorphizes via match, the SDK uses Box<dyn ProofSystem>.
  • Two-layer error model. OnChainError (deterministic, repr-u32) for
on-chain; DiagnosticError (rich, feature-gated) for off-chain. See ADR-0002 and SIMD-0129.
  • Syscall abstraction. SyscallBackend lets host tests use arkworks
while on-chain calls real syscalls. Same verifier code, different backend.
  • No hand-rolled cryptography. Verifier crates depend on ark-bn254
(host) or Solana syscalls (SBF). New primitives go through the abstraction or wait for upstream availability.
  • Forward-compatible byte layout. LE_INPUTS const generic + FormatTag
wire enum mean SIMD-0204 (LE alt_bn128) and SIMD-0233 (native G2) land as non-breaking changes.

MSRV

Rust 1.85.0 โ€” host workspace (cargo, clippy, rustfmt, tests). Rust 1.89.0-dev โ€” Solana SBF target via cargo build-sbf --tools-version v1.52.

The default cargo-build-sbf (platform-tools v1.51, rustc 1.84.1) can't parse edition2024 in some transitive dependencies (constanttimeeq via blake3). We therefore pin --tools-version v1.52 in CI and recommend the same locally.

Security

External audit-ready (pending firm engagement per issue #19 / #61). Production PLONK + Groth16 batch verification. HyperPlonk + Halo2 + FRI-STARK wire formats locked. All four Phase-3 verifier bodies (HyperPlonk, Halo2, Nova, FRI-STARK) run end-to-end. All four bodies gained cryptographic soundness gates; SBF binary reduced 72% via opt-level = "z"; mosaic-zk-primitives crate extracted. 12 independent cryptographic soundness gates across 4 bodies. FRI-STARK at Plonky3/Winterfell production parity (7 gates); Nova, Halo2, HyperPlonk extended to protocol-appropriate depth. 14 soundness gates. Multi-poly MSM batching in Halo2 (proof- and VK-side commits) + Nova (Spartan 5-way batched opening) folds every committed polynomial into the batched pairing identity. HyperPlonk permutation cosets (k1, k2, k_3) lifted from hardcoded (1, 2, 3) into the VK. CU baselines re-measured under the opt-level = "z" profile (PLONK cap 800K โ†’ 1.1M). Five shared primitives extracted to mosaic-zk-primitives from inlined duplication across Halo2 / HyperPlonk / Nova verifiers โ€” frfrombebytesreduced, derivefrchallenge, frbefrom_u64, verifytwopairpairing, commitmentminusscalarg1. Nova proof canonical gains a dedicated w_eval slot (session 23), replacing the scaffold reuse of public_inputs[0]. 14 new unit tests cover the lifted primitives. Sixth primitive computekzgopening_lhs consolidates the full A = C โˆ’ yยทG1 + ฮพยทW pairing-LHS construction across every KZG verifier. HyperPlonk univariate opening point now binds the FULL sumcheck challenge vector (not just the trailing challenge). ProofSystem::estimatedcomputeunits turns shape-aware for the three Phase-3 bodies (halo2/hyperplonk/nova). mosaic-sdk gains five opt-in Cargo features (plonk, hyperplonk, halo2, nova, stark, plus all-phase3) so client preflight covers every proof system. Cast-safe borrow-chain rewrite eliminates four as u8 truncation warnings in fr::subr + msm::negateg1. +27 proptest tests (zk-primitives 51โ†’64, stark 103โ†’117) plus clippy cleanup + complete # Errors rustdoc for zk-primitives. Workspace-wide property-based test sweep (sessions 37-42) brings every Phase-1, Phase-2, Phase-3, adapter, state-machine, SDK, and on-chain program crate under audit-grade proptest coverage. +111 proptest tests across nine crates:

| Crate | ฮ” | Total | |---|---:|---:| | mosaic-halo2 | +16 | 75 | | mosaic-hyperplonk | +17 | 82 | | mosaic-nova | +14 | 59 | | mosaic-plonk | +15 | 32 | | mosaic-groth16 | +15 | 26 | | mosaic-serde | +9 | 12 | | mosaic-chunked | +11 | 20 | | mosaic-sdk | +7 | 11 | | mosaic-program | +7 | 7 |

Property categories: canonical byte layout invariants, full Fiat-Shamir round-by-round avalanche (Halo2 4-round, HyperPlonk 3-round, Nova 3-round, PLONK 6-round including the snarkjs- compatibility "u-absorbs-only-Wxi-and-Wxiฯ‰" bit), single-byte tamper rejection over commit and opening regions, state-machine monotonicity (chunked upload session), Borsh wire-format round- trip (instruction payloads), BE-comparison + Fr arithmetic invariants, snarkjs adapter c1โ€–c0 ordering and decimaltobe_32 range envelope, builder/setter independence, instruction-tag dispatch routing.

Three false positives surfaced and were documented inline: the Halo2 verifier random-byte-flip test required scope-narrowing away from selector slots that interact with the dummy fixture's trivially-zero wires; the HyperPlonk verifier's anchor + XOR tamper pattern was rewritten to direct proof[off] = new_val after bit_mask = anchor cancellation was caught by proptest shrinking; the same byte-anchor pattern was avoided across the rest of the sweep.

Only fixture-driven differential testing remains before external audit engagement (tracked: extending tests/differential from Groth16 + PLONK to all four Phase-3 bodies).

disclosure-timeline SLA. attestation bootstrap at supply-chain/. audit-facing registry of every clippy suppression.

License

Dual-licensed under either of:

at your option. SPDX: Apache-2.0 OR MIT.

Contributing

See CONTRIBUTING.md. All contributions are welcomed under the dual-license terms above.

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท wienerlabs/mosaic ยท Updated daily from GitHub