Fuzzing
Fuzzing here is seeded and deterministic by design (spec §26). Each
target is a loop over the deterministic mock harness driven by a
dependency-free SplitMix64 PRNG derived from a single seed, so
target + seed replays every iteration byte-for-byte. A finding records
the seed, the iteration, and the exact operations that reproduced it — and
reduces to a permanent regression case.
Targets
The fuzz crate runs four targets (spec §26 boundaries):
| Target | What it mutates | Oracle |
|---|---|---|
operations | random multi-operation scenarios (actors, tokens, amounts, op kinds) | cross-operation invariant registry (conservation, ownership, commitment consistency, replay protection, privacy) + no panic/error |
negative-controls | must-reject operations from the declared posture (unregistered actor, zero amounts, frozen account) | rejection expectations — acceptance is a finding |
proof-references | proof reference strings (wrong digest, unknown fixture, malformed, not-a-reference) | rejection + input-binding invariant — anything that verifies is a finding |
public-inputs | public inputs of a valid proof (recipient/sender/token swaps, appended pairs, empties, permutations) | mutations must fail verification; pristine and permuted statements must keep verifying (order independence) |
The oracle is always independent of the system under test — the invariant registry recomputes expected facts from the scenario definition and fixture posture, and the controls come from the declared protocol posture. Never from the surface’s own answers.
Running
cargo run -p cli --bin crucible-scenarios -- fuzz # seed 42, 200 iterations per target
cargo run -p cli --bin crucible-scenarios -- fuzz --seed 7 --iterations 500 --json
Exit code is non-zero when anything was found; --json emits the full
reports including the reproducing operations.
From finding to regression test
- A finding records
seed+iteration— replay the run with that seed. fuzz::reduce_findingdelta-debugs the operation sequence (drop an operation whenever the failure still reproduces) and shrinks amounts by halving, always re-running the candidate through the harness.FuzzFinding::to_regression_caseconverts the reduced finding into a permanentCT-REG-100..999case that pins the fixed behavior.
Scope and honesty
Fuzzing runs against the repository’s deterministic test doubles. It finds bugs in the scenario layer — broken invariants, unexpected acceptances, verification binding slips, panics, leaks. It does not validate the underlying Confidential Token implementation or any real prover; that requires wiring the real simulator/prover and is future work behind the adapter contracts.