Skip to content

Releases: wienerlabs/mosaic

v0.2.0-phase2 — PLONK + Groth16 batch production

20 Apr 14:02

Choose a tag to compare

Phase 2 technical scope frozen. Two production verifier additions plus infrastructure work that unblocks Phase 3.

Headline: two new verifier paths on Solana L1

Mode Measured CU vs Phase 1
Groth16 BN254 single 80,296 baseline
Groth16 BN254 batch N=5 230,626 (46K/proof) -42.6%
KZG-PLONK BN254 747,666 new

Groth16 batch beats the loop path at N≥2. PLONK is the first non-Groth16 production verifier in the Solana ecosystem — byte-for-byte compatible with snarkjs 0.7.x, verified end-to-end against a real snarkjs fixture.

What's new

Verifiers

  • mosaic-plonk — full KZG-PLONK BN254 verifier. Six rounds of Fiat-Shamir via Keccak-256 transcript, linearization polynomial reconstruction (MSM over VK + proof commitments), KZG batched opening pairing. Six library modules: canonical, fr, field, transcript, challenges, linearization.
  • mosaic-groth16::batch — Bowe-Gabizon randomized aggregation. N proofs sharing a VK → one alt_bn128_pairing syscall with N+3 pairs. Independent SHA-256 challenges keep derivation free of on-chain Fr multiplication.
  • VerifyProofBatch instruction (0x02) exposes batch verification to on-chain callers and CPI.

Infrastructure

  • sol_poseidon syscall wired via solana-poseidon 2.3 (#8) — unblocks Circom-compatible transcripts for Phase 3 KZG-based systems.
  • Real snarkjs 0.7.6 PLONK fixture + SnarkjsPlonkCodec — decoder for snarkjs JSON → canonical wire bytes.
  • cargo-vet attestation baseline (#59): 74 audited / 2 partial / 689 exempted.
  • Threat model expanded with 4 scope-boundary axes: under-constrained circuits, malleable proofs, validator determinism, replay safety (#63).
  • Audit-readiness pass (#60): SECURITY.md, AUDIT.md, disclosure timeline, supply-chain README, pre-audit RFQ/outreach templates.
  • bpf-bench now tracks three regression gates: Groth16 single, Groth16 batch N=5, PLONK single.

Stats

  • 119 tests passing (was 36 at v0.1.0-phase1).
  • SBF ELF 557 KB (was 112 KB, growth owed to arkworks Fr + PLONK linearization + batch path). Well under Solana's 1 MB program size limit.
  • Clippy strict green (correctness + suspicious + todo + unimplemented hard-deny).

Bugs caught along the way

  • PLONK u-challenge absorb order was missing — snarkjs only absorbs Wxi + Wxiω for u, not v. Pre-fix would have silently failed all valid PLONK proofs.
  • Host G1 decode rejected (0, 0) as off-curve. Solana alt_bn128 treats all-zero bytes as identity; snarkjs emits this for zero-polynomial selector commitments (e.g. Qr in our mul-circuit).
  • SBF stack-frame overflow in PLONK linearization (>10 KB at worst). Resolved by splitting monolithic functions into many #[inline(never)] sub-helpers.

Closed issues

#1 PLONK verifier · #5 batch_verify · #8 Poseidon · #33 devnet integration · #59 cargo-vet · #60 audit-readiness · #63 threat model

Compatibility

  • Host: Rust 1.85.0 stable (unchanged)
  • SBF: cargo build-sbf --tools-version v1.52 (unchanged)
  • Solana program SDK: ^2.1 (unchanged, tested against 2.3.0)
  • Wire format: Phase-1 canonical byte layouts stable; PLONK adds its own 768 B proof / 744 B VK layout
  • OnChainError discriminants: all Phase-1 values unchanged; no new variants

Phase 3 preview

Next freeze targets HyperPlonk-KZG, Halo2-KZG, gnark adapter, FRI-STARK, Nova/HyperNova folding. See the [Unreleased] section of CHANGELOG.md for the full list.

Full changelog

CHANGELOG.md § 0.2.0-phase2

v0.1.0-phase1 — Phase 1 freeze

20 Apr 00:14

Choose a tag to compare

Pre-release

Phase 1 technical scope frozen. This pre-release is the reference point for audit-readiness conversations; subsequent commits land documentation, supply-chain attestation, and outreach artifacts without changing the runtime surface.

What's in

  • mosaic-core: ProofSystem, ProofCodec, TranscriptHash, SyscallBackend, two-layer error taxonomy (29 OnChainError variants pinned at stable discriminants), bump arena.
  • mosaic-groth16: BN254 Groth16 verifier with LE_INPUTS const generic for SIMD-0204 forward-compat. Host backend via ark-bn254, SBF backend via solana-bn254 syscalls.
  • mosaic-serde: snarkjs JSON + arkworks canonical adapters producing byte-equal canonical output. gnark/halo2/plonky3/risc0 are stubs.
  • mosaic-chunked: 48-hour session PDA protocol with rolling SHA-256 commitment. PDA seeds bound to (session_id, payer) to defend front-running griefing.
  • mosaic-program: 112 KB SBF ELF dispatching single-tx VerifyProof + chunked-upload instructions.
  • mosaic-sdk: instruction builder + host-side preflight.
  • mosaic-bench: bpf-bench measures real on-chain CU (80,296 CU Groth16 mul-circuit, 44.6% of the 180K ADR-0005 cap).
  • mosaic-fuzz: three libFuzzer harnesses.

Verification

  • cargo test --workspace --all-features: 36 passed, 0 failed
  • cargo clippy strict: 0 errors
  • cargo build-sbf --tools-version v1.52: 112 KB mosaic_program.so
  • Round-trip: snarkjs + arkworks + canonical paths byte-equal
  • Differential (proptest): arkworks reference vs Mosaic host backend, 16 cases

Fixture corpus

Deterministic Groth16 mul-circuit (proves a * b == c with a=7, b=6) committed in three formats under tests/fixtures/groth16/mul-circuit/.

Documentation

5 ADRs + 1 design doc (chunked-upload implementation contract) + threat model + CU budget + lint policy + SECURITY/AUDIT/CONTRIBUTING.

Known limitations

  • No external audit yet (issue #19)
  • Fixtures are programmatic, not Circom-sourced (#24)
  • Poseidon syscall path for Solana 2.x not wired (#8)
  • Only Groth16 implemented; PLONK/STARK/Nova stubs (#1, #3, #4)

Compatibility

  • Host: Rust 1.85.0 stable
  • SBF: cargo-build-sbf --tools-version v1.52 mandatory
  • Solana program SDK: ^2.1 (tested against 2.3.0)

Full changelog

CHANGELOG.md