Pre-mainnet review window — v0.9.13-phase3-compression (2026-05-02). The audit-prep sprint that ran from sessions 86 to 114 (v0.9.0 → v0.9.13) delivered:
- All six BN254-curve verifiers implemented (Groth16, KZG-PLONK, HyperPlonk, Halo2, Nova/HyperNova/ProtoStar) plus FRI-STARK (Plonky3 family).
- alt_bn128 compression infrastructure across all five BN254-curve verifiers (proof + VK round-trips, fuzz coverage, criterion benches).
- 712 lib tests + 37 fuzz harnesses + 14 criterion benches + 10 SBF integration tests.
- Audit-coverage runbook + per-gate isolation benches + bpf-bench dispatch byte-fix (s113).
External audit commission is the next gate. See
AUDIT-CHECKLIST.md for the full crate-by-crate
scope / non-scope / known-limitations matrix that audit firms should
review before sending a quote.
If you discover a security vulnerability in Mosaic, please do not open a public GitHub issue. Instead, email baturalp@wienerlabs.com (PGP key coming soon) with:
- A description of the vulnerability and its potential impact.
- Steps to reproduce, or a proof-of-concept exploit.
- Your suggested mitigation, if you have one.
- Whether you would like public credit in the eventual disclosure.
Our response SLA and timeline is documented in
docs/responsible-disclosure-timeline.md.
Every crate inside this repository (workspace members under crates/) plus
the reference Solana program binary produced by
cargo-build-sbf --manifest-path crates/mosaic-program/Cargo.toml:
mosaic-core— verifier trait + error taxonomy + syscall abstractionmosaic-zk-primitives— shared cryptographic primitives (12+ helpers)mosaic-groth16— single + Bowe-Gabizon batched verifiermosaic-plonk— KZG-PLONK BN254 verifiermosaic-hyperplonk— HyperPlonk KZG BN254 verifiermosaic-halo2— Halo2 KZG BN254 verifier (PSE fork-compatible)mosaic-stark— FRI-STARK Goldilocks/BabyBear/Mersenne31mosaic-nova— Nova / HyperNova / ProtoStar folding verifiermosaic-serde— snarkjs + arkworks adapters (gnark stub)mosaic-chunked— chunked-upload protocol + handlersmosaic-program— reference Solana on-chain dispatcher (cdylib)mosaic-sdk— off-chain transaction builder helpers
And published artifacts on crates.io once releases begin.
- Vulnerabilities in upstream dependencies (
arkworks,solana-program,light-poseidon,sha2,tiny-keccak, etc.) — please report those to the respective projects. We will track downstream impact in this repo. - Vulnerabilities in proving systems themselves (Groth16 trust setup, Halo2 implementation, etc.).
- DoS via legitimate-but-expensive proofs that fit within the declared CU budget. CU exhaustion is an accepted attack and mitigated by client-side budgeting, not in-protocol.
- Issues in client-side key management — Mosaic is not a wallet.
- Issues in our test fixtures or benchmark harnesses.
For each of the following attack surfaces, the linked section of
docs/threat-model.md documents current mitigations
and residual risk.
| # | Threat | Mitigation reference |
|---|---|---|
| T-1 | Pairing accepts an invalid proof | docs/threat-model.md § T-1 |
| T-2 | Public inputs ≥ BN254 scalar field order | § T-2 |
| T-3 | Off-curve / wrong-subgroup points | § T-3 |
| T-4 | Length-mismatch panic via crafted bytes | § T-4 |
| T-5 | Validator divergence on error codes (consensus failure) | § T-5 |
| T-6 | Chunked-upload reordering / commitment forgery | § T-6 |
| T-7 | PDA squatting / cross-session aliasing | § T-7 |
| T-8 | Timing side-channels | § T-8 |
| T-9 | Memory unsafety | § T-9 |
| T-10 | Arithmetic overflow | § T-10 |
| T-11 | Compression-syscall round-trip divergence | § T-11 |
| T-12 | Chunked-STARK CU exhaustion / single-tx infeasibility | § T-12 |
Scope-boundary axes documented in docs/threat-model.md:
| # | Axis | Where Mosaic draws the line |
|---|---|---|
| Axis 1 | Under-constrained circuit attacks | Out-of-scope by design; tooling references (Picus, Ecne, ZK-NavigatOR) provided. |
| Axis 2 | Malleable proof vectors | Application responsibility via nullifier / nonce set; chunked-upload's session_id is a worked example. |
| Axis 3 | Validator determinism | Extends T-5; covers arithmetic, iteration order, allocator. |
| Axis 4 | Replay safety + instruction binding | Application responsibility; guidance patterns documented. |
| Component | Status (v0.9.13) |
|---|---|
mosaic-core traits / error taxonomy / syscall surface |
Unaudited. Trait + error code stability frozen since v0.5.0; #[non_exhaustive] enums for forward-compat. |
mosaic-zk-primitives shared cryptographic helpers |
Unaudited. Internal extraction (sessions 90-95); 9 primitives lifted from per-verifier duplicates. |
mosaic-groth16 BN254 verifier (single + batched) |
Unaudited. Algorithm parity with Light Protocol's groth16-solana cross-checked via 36+ tests + arkworks differential harness. |
mosaic-plonk KZG-PLONK BN254 verifier |
Unaudited. snarkjs PLONK 0.7.6 differential test landed at v0.6.0; SBF integration test landed at v0.9.12. |
mosaic-hyperplonk KZG BN254 verifier |
Unaudited; Phase-3 scaffold. Espresso-reference fixture differential test pending session 118. Compression API at v0.9.13. |
mosaic-halo2 KZG BN254 verifier (PSE fork) |
Unaudited; Phase-3 scaffold. Multi-column lookup wired at v0.9.1; multi-lookup at v0.9.6; compression at v0.9.5/.7/.8. |
mosaic-stark FRI-STARK |
Unaudited; Phase-3 scaffold. Plonky3-reference fixture pending; alt_bn128 compression N/A (field-only). Chunked-only on chain: a production-shaped proof (~7.8M CU) exceeds the 1.4M per-transaction cap, so STARK MUST be verified via the chunked path (verify_setup + verify_query_range, driven by BeginStarkVerify / StarkVerifyStep), never single-shot VerifyProof. This mitigates T-12. SDK: build_chunked_stark_plan. |
mosaic-nova Nova/HyperNova/ProtoStar |
Unaudited; Phase-3 scaffold. sonobe-reference fixture pending session 118. Compression at v0.9.13. |
mosaic-serde snarkjs adapter |
Unaudited. Decimal-string parsing is fuzzed (4 harnesses). |
mosaic-serde arkworks adapter |
Unaudited. Round-trip byte equality with snarkjs verified. |
mosaic-chunked protocol + handlers |
Unaudited. Design doc § 7 enumerates DoS surface; integration-tested via chunked_handlers.rs. Session layout v2 adds the StarkVerifyProgress resumable-verification cursor (chunked STARK, #76), end-to-end tested in chunked_stark.rs. |
mosaic-program reference dispatcher |
Unaudited. SBF integration tests at v0.9.12 cover all 8 declared bytes + 2 negative paths (10 tests). |
| alt_bn128 compression infra (s103-114) | Unaudited. Round-trip + fuzz coverage across all 5 BN254 verifiers. Wire format only — never on the verify path. |
External audit commission is tracked in issue
#19; pre-audit outreach
for slot reservation in issue
#61. The
AUDIT-CHECKLIST.md document is the
crate-by-crate scope handoff — audit firms should grep that for
deliverable boundaries.
We do not recommend using Mosaic for production value-bearing transactions until at least one independent audit has landed. See AUDIT.md for the per-release audit log.
- Memory safety: every library crate has
#![forbid(unsafe_code)]. Any future relaxation (e.g. theunsafe-arenafeature, issue #58) requires anallowexception indeny.toml, a writtenSAFETY:block, and a Miri CI job as the lockstep quality gate. - No hand-rolled cryptography: see README.md § Design principles.
- Consensus determinism: see
docs/threat-model.md§ T-5. - Strict CI:
cargo clippywith hard-deny onclippy::correctness + suspicious + todo + unimplemented; pedantic / nursery visible as warnings. Seedocs/lint-policy.mdfor the audit-facing suppression registry. - Supply chain:
cargo-denyfor license + banned-crate checks;cargo-auditfor CVE matching.cargo-vetattestation bootstrap in progress (issue #59). - Fuzzing: 37
libfuzzer-sysharnesses at v0.9.13 (was 3 at v0.1.0). PR matrix runs 22 representative harnesses for 5 min each (~110 min wall-clock); nightly runs the full 37-target sweep for 60 min per harness (~37 hours, in 2 parallel batches under GitHub's 20-concurrent-runner cap). See.github/workflows/fuzz.ymlfor the matrix. - Compression round-trip safety: every BN254-curve verifier has fuzzed compression APIs (4 harnesses for Phase-3 + 6 for Phase-2 = 10 total). Round-trip tests on real BN254 generators confirm bit-for-bit reproduction; pass-through invariants confirm non-curve fields survive compression unmodified.
- SBF runtime evidence: session 113 added 10 SBF integration
tests covering every declared
ProofSystemIddiscriminant byte (8 known + 1 alias + 1 unknown-byte negative) against the realsolana-program-testruntime (rbpf VM, not the host arkworks mock).
For vulnerabilities we confirm and publish:
- Wiener Labs is a CVE Numbering Authority applicant (as of 2026-04-20); pending approval we request CVEs through MITRE's public form.
- Affected versions documented in
AUDIT.mdwith fix commit SHA and downstream advisory links. - GitHub Security Advisory created and linked from the CVE record.
- RustSec advisory filed so
cargo-auditflags it for dependents.
Reporters are credited by name (or handle) in the CVE record and advisory unless they prefer anonymity.
If a vulnerability potentially affects other Solana ZK projects (Light
Protocol, Bonsol, ZK Compression, etc.) we will coordinate disclosure with
the Solana Foundation security team and the respective project maintainers
under the standard Solana security disclosure policy. The
trigger conditions, ecosystem contact tree, embargo timeline, and shared
advisory format are specified in
docs/coordinated-disclosure.md.