Skip to content

tests: implement FUZ-01..05 property & uniformity tests#45

Open
adamkrellenstein wants to merge 2 commits into
mainfrom
adam/crypto-proofs-fuzzing
Open

tests: implement FUZ-01..05 property & uniformity tests#45
adamkrellenstein wants to merge 2 commits into
mainfrom
adam/crypto-proofs-fuzzing

Conversation

@adamkrellenstein

@adamkrellenstein adamkrellenstein commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces the five #[ignore]-d fuzzing stubs in tests/fuzzing_targets.rs with real, deterministic property and statistical tests over the stable PoR core primitives:

  • FUZ-01 merklebuild_tree → get_padded_proof_for_leaf → verify roundtrip for every padded leaf, plus the only-if direction (a proof must not verify against an unrelated root). Mirrors production usage by zero-padding the leaf count to a power of two (as validate_and_encode does).
  • FUZ-02 prepare_file — coherent metadata (power-of-two padding, depth == log2(padded_len), validate() passes) and determinism of file_id/object_id/root; object_id is content-only (nonce-independent).
  • FUZ-03 prove/verify — bounded random Nova roundtrip over depths 0..=3 and 1..=3 challenges.
  • FUZ-04 domain-tag separation — the seven protocol domain tags yield pairwise-distinct tagged Poseidon hashes for random (x, y).
  • FUZ-05 challenge-index uniformity — seeded chi-squared over 2⁸ buckets, failing only on extreme non-uniformity.

Notes

  • Uses seeded StdRng (already a dev-dependency) rather than introducing proptest, so the suite stays dependency-free; each case prints reproducible seed/index context on failure. The byte-oriented cargo-fuzz harnesses under fuzz/ remain the complementary deserialization-robustness layer.
  • Scope is deliberately the stable primitives (merkle, prepare, poseidon tags, challenge derivation) + a bounded prove/verify — not circuit internals or proof wire-format, which the dedicated circuit/e2e suites already cover and which the constant-size-proof work is actively changing.
  • FUZ-01 surfaced (and now documents) that build_tree does not itself pad the leaf layer — padding is an upstream prepare_file responsibility.

All five pass locally; cargo clippy --all-targets --all-features -- -D warnings and the full nextest suite are green (pre-push hook passed).


Note

Low Risk
Test-only changes with no production logic modified; adds dev test coverage and reuses existing statrs for FUZ-05.

Overview
Removes the ignored FUZ-01..05 stub file and adds property_tests.rs, which runs deterministic, seeded-random checks against the PoR crypto surface instead of unimplemented! placeholders.

Merkle (FUZ-01) exercises power-of-two padded chunk layouts (matching production padding), verifies every leaf’s padded proof against its root, rejects foreign roots, and fails on a tampered sibling. prepare_file (FUZ-02) checks metadata coherence, ID/root determinism, and nonce-independent object_id. Prove/verify (FUZ-03) runs a small number of Nova roundtrips via existing test fixtures over random depths and challenge counts. Domain tags (FUZ-04) assert pairwise-distinct tagged Poseidon hashes across all seven protocol tags. Challenge indices (FUZ-05) applies a seeded chi-squared test on derive_index_from_bits at depth 8.

The suite uses StdRng with fixed seeds (no proptest); byte-level cargo-fuzz harnesses are unchanged as the deserialization layer.

Reviewed by Cursor Bugbot for commit bb4b143. Bugbot is set up for automated code reviews on this repo. Configure here.

Replace the five `#[ignore]`-d fuzzing stubs with real, deterministic
property/statistical tests over the stable PoR core primitives:

  - FUZ-01 merkle: build_tree → get_padded_proof_for_leaf → verify roundtrip
    for every padded leaf, plus the only-if direction against a foreign root.
  - FUZ-02 prepare_file: coherent metadata (power-of-two padding,
    depth == log2(padded_len), validate() passes) and determinism of
    file_id/object_id/root; object_id is content-only (nonce-independent).
  - FUZ-03 prove/verify: bounded random roundtrip over depths 0..=3 and 1..=3
    challenges (small case count; the e2e suite covers fixed shapes).
  - FUZ-04 domain-tag separation: the seven protocol domain tags yield
    pairwise-distinct tagged Poseidon hashes for random (x, y).
  - FUZ-05 challenge-index uniformity: seeded chi-squared over 2^8 buckets,
    failing only on extreme non-uniformity.

Uses seeded `StdRng` (already a dev-dependency) rather than introducing
`proptest`, so the suite stays dependency-free and builds offline; each case
prints reproducible seed/index context on failure.
let mut data = vec![0u8; data_len];
rng.fill_bytes(&mut data);
let nonce_len = rng.gen_range(0..=32);
let mut nonce = vec![0u8; nonce_len];
@codspeed-hq

codspeed-hq Bot commented Jun 2, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 13 untouched benchmarks
⏩ 13 skipped benchmarks1


Comparing adam/crypto-proofs-fuzzing (bb4b143) with main (fe9f977)

Open in CodSpeed

Footnotes

  1. 13 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Review found FUZ-02 was pinned to a single (depth 8, single-codeword) point:
data ≤4096 bytes never exceeds one codeword (231×31 = 7161 data bytes), so
padded_len/depth never varied and the coherence asserts only ever checked
(256, 8). Widen the data range to ~16 KB so cases span one-to-three codewords
(depths 8–10), making `depth == log2(padded_len)` a real check; trim the case
count to keep erasure-coding cost reasonable.

Also add a tamper-direction negative to FUZ-01: corrupting one sibling must
break verification against the *correct* root. The prior foreign-root check
alone wouldn't catch a verifier that mishandles sibling order or ignores the
path, since that case also differs in the root.
@adamkrellenstein adamkrellenstein added area: crypto Cryptography / circuits / proofs area: ci CI / test infrastructure labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci CI / test infrastructure area: crypto Cryptography / circuits / proofs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants