Hello everyone, I am submitting a proposal to Zcash Community Grants (ZCG) to build a continuous batch-verification soundness oracle for Zebra — a differential fuzzing harness that asserts Zebra’s shielded-proof and signature batch verification accepts a set of items if and only if every item also verifies individually. This is a direct continuation of ZCG #234 (Zebra Coverage-Guided Fuzzing Infrastructure) , reusing its corpus and harness scaffolding.
Why This Matters
Zebra verifies shielded proofs and signatures in batches for performance. A batching-layer bug that accepts a batch containing one invalid item — a false-accept — is a silent soundness failure, the same threat class that underlies counterfeiting. Today it’s asserted by neither place you’d expect: production uses a batch-first, single-fallback pattern (tower-fallback ) that only retries items after a batch fails — self-correcting false-rejects but blind to false-accepts ; and the existing fuzz harness checks only for panics, not soundness . Upstream Zebra ships no batch-vs-single equivalence test . The June 5 Orchard incident showed a shielded-verification soundness break can hide for years — that bug was in the circuit ; the batch-verification glue is a distinct, equally-unguarded surface (this oracle is complementary to circuit analysis, not a substitute). With NU6.2 just activated and Ironwood next, the area is actively changing.
Project Overview
A continuous differential oracle that runs both real paths — batch (BatchValidator ) and single (Item::verify_single ) — and asserts they agree, across all four Zebra batch verifiers (Orchard halo2, Sapling/Sprout Groth16, Orchard RedPallas, Sapling RedJubjub), driven by adversarial corpora that hide one invalid item among valid ones, and extended to the new Ironwood pool + turnstile migration, integrated into continuous CI.
Technical Approach
Built on the cargo-fuzz / libFuzzer + ASan scaffolding from #234. Adversarial corpus = real mainnet V5 valid bases + single-element tampering (corrupt a proof / swap a nullifier / perturb a signature scalar / replace a public input) + batch-composition fuzzing (size, ordering, duplicates, empty/singleton) — batching bugs live in the aggregation glue, not the per-item math.
Deliverables and Milestones (3 milestones, ~3 months)
- M1 — Dual-path equivalence framework + Orchard
- M2 — Adversarial corpus + all four verifiers + coverage reporting
- M3 — Ironwood pool + turnstile soundness target + continuous CI (ClusterFuzzLite / OSS-Fuzz)
Budget
- Startup Funding: $3,000
- Milestones 1–3: $42,000 ($15,000 / $15,000 / $12,000)
- Total: $45,000
Design Principles
- Standalone / non-invasive: drives Zebra through public APIs; no consensus code changes.
- Sustainable: CI / OSS-Fuzz keeps the assertion running after the grant — even at zero findings, the machine is a durable ecosystem asset.
- Community-oriented: open repo + corpus, reusable by ZF, Zebra maintainers, and future auditors.
Track Record
Continues ZCG #234, whose M1/M2 work surfaced several Zebra security issues credited to the project lead — including CVE-2026-34202 (Critical, V5 transaction DoS), GHSA-c8w6-x74f-vmg3 (Moderate, Sapling-receiver DoS), and issues #10534 and #10544 . Full proposal details: Grant Application - Batch-vs-Single Verification Equivalence: Continuous Soundness Fuzzing for Zcash Shielded Verification (incl. Ironwood) · Issue #332 · ZcashCommunityGrants/zcashcommunitygrants · GitHub
Thank you for your time and feedback.