tests: implement FUZ-01..05 property & uniformity tests#45
Open
adamkrellenstein wants to merge 2 commits into
Open
tests: implement FUZ-01..05 property & uniformity tests#45adamkrellenstein wants to merge 2 commits into
adamkrellenstein wants to merge 2 commits into
Conversation
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]; |
Merging this PR will not alter performance
Comparing Footnotes
|
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the five
#[ignore]-d fuzzing stubs intests/fuzzing_targets.rswith real, deterministic property and statistical tests over the stable PoR core primitives:build_tree → get_padded_proof_for_leaf → verifyroundtrip 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 (asvalidate_and_encodedoes).depth == log2(padded_len),validate()passes) and determinism offile_id/object_id/root;object_idis content-only (nonce-independent).(x, y).Notes
StdRng(already a dev-dependency) rather than introducingproptest, so the suite stays dependency-free; each case prints reproducible seed/index context on failure. The byte-orientedcargo-fuzzharnesses underfuzz/remain the complementary deserialization-robustness layer.build_treedoes not itself pad the leaf layer — padding is an upstreamprepare_fileresponsibility.All five pass locally;
cargo clippy --all-targets --all-features -- -D warningsand the fullnextestsuite are green (pre-push hook passed).Note
Low Risk
Test-only changes with no production logic modified; adds dev test coverage and reuses existing
statrsfor 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 ofunimplemented!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 onderive_index_from_bitsat depth 8.The suite uses
StdRngwith fixed seeds (noproptest); byte-levelcargo-fuzzharnesses 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.