Zebra Coverage-Guided Fuzzing Infrastructure

Hi ZCG team, Zebra maintainers, and Zcash community,

I’m happy to share the delivery for Milestone 2 of the Zebra coverage-guided fuzzing grant.

Milestone 2

Building on Milestone 1, this milestone delivers the second set of coverage-guided

fuzz targets for Zebra, together with continuous-fuzzing infrastructure on GitHub

Actions and a public, auto-updating coverage dashboard.

Deliverables (all complete)

1. RPC interface input handlingrpc_handler_fuzz and jsonrpsee_envelope_fuzz,

exercising zebra-rpc’s methods.rs (34% region coverage).

2. Script & transparent/shielded address parsingscript_verify_fuzz and

script_flag_matrix_fuzz drive transparent-script verification through the zcash_script

C/C++ library via FFI (sanitizer-coverage does not instrument the C side, so these provide

crash detection rather than Rust region coverage); address_fuzz drives

transparent/address.rs (63% region coverage).

3. Note-commitment tree insert/removenote_commitment_tree_fuzz, exercising

orchard/tree.rs (54% region coverage).

4. Equihash solution verificationequihash_fuzz, exercising work/equihash.rs

(65% region coverage).

That is 7 new operational targets, meeting the proposal’s “7+ targets” criterion and

covering the full deliverable family. Combined with Milestone 1’s 5 block/P2P-deserialization

targets, the suite now runs 12 targets in one cumulative repository.

Continuous fuzzing (ClusterFuzzLite on GitHub Actions)

  • Pull-request fuzzing — short code-change runs with AddressSanitizer + SARIF output

  • Batch fuzzing every 6 hours — accumulates newly-discovered inputs into the corpus

  • Daily coverage report + corpus pruning

Coverage

Per-subject-under-test region coverage is reported per source file. (A whole-report total

is not meaningful here — it averages in the Rust standard library and every third-party

dependency, none of which the fuzzers target.) Beyond the headline files above, **90+

Zebra source files are exercised at ≥5% region coverage**. These are seed-corpus baselines

and grow with sustained fuzzing.

No crashes found to date across the 12 targets.

Corpus

The seed corpus is mainnet-derived public data — real blocks, transactions, headers and

P2P messages dumped from a fully-synced Zcash node — plus a small set of hand-constructed

protocol seeds. The CI corpus accumulates and is periodically pruned/minimized.

Repositories (public, fully reproducible)

The vendored crates are upstream Zebra v5.0.0, byte-identical except for two fuzzing-only

cfg gates that expose otherwise-private modules to the harnesses. Anyone can clone, build

and run (cargo +nightly fuzz build/run --fuzz-dir zebra-fuzz/fuzz <target>), and the

coverage report rebuilds automatically every night in CI.

1 Like