A comprehensive fuzzing framework for testing Secret Shared Validator (SSV) protocol implementations, with a focus on differential fuzzing between the Sigp Anchor (Rust) and go-ssv implementations. This project provides both traditional fuzzing targets and differential fuzzing capabilities to identify implementation discrepancies that could lead to network splits or consensus failures.
SSV (Secret Shared Validator) is a protocol that enables the distributed control and operation of an Ethereum validator. This fuzzing framework focuses on testing the robustness and security of different components of the SSV implementation, with two main approaches:
- Message validation
- QBFT consensus
- SSZ encoding/decoding
- Message receiving pipeline
Critical for network security: Compares behavior between Go and Rust SSV implementations to identify discrepancies that could cause:
- Network splits due to consensus disagreements
- Chain forks from encoding/validation differences
- Validator penalties from inconsistent message handling
Check out TROPHY.md to see real bugs and discrepancies discovered through differential fuzzing that have been fixed in both implementations.
- Rust (nightly toolchain)
- Go 1.21+ (required for differential fuzzing)
- AFL++ system package for fuzzing instrumentation
- System dependencies for compilation:
build-essential
(or equivalent C/C++ compiler)llvm-dev
andclang
(for LLVM instrumentation)
- cargo-afl - install with
cargo install cargo-afl
sudo apt update
sudo apt install build-essential llvm-dev clang
# Install Homebrew if you haven't already
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install required dependencies
brew install llvm clang
# Install AFL++ for system-level fuzzing support
brew install afl++
# Note: Xcode Command Line Tools are also required (usually installed automatically)
xcode-select --install
macOS-Specific Notes:
- Apple Silicon (M1/M2): The ring cryptographic library requires special compilation flags. Set these environment variables before building:
export CFLAGS_aarch64_apple_darwin="-mcpu=apple-m1" export RUSTFLAGS="-C target-cpu=apple-m1"
- Crash Reporter: macOS crash reporting can interfere with AFL++. You may see warnings about this when running fuzz targets, but they can be safely ignored in most cases.
sudo pacman -S base-devel llvm clang
Ensure you have a C compiler, LLVM development libraries, and clang installed.
Fuzzing requires the Rust nightly toolchain due to its use of unstable features. To install and set up the nightly toolchain:
# Install nightly toolchain
rustup toolchain install nightly
# Set nightly as default (optional)
rustup default nightly
# Or use nightly only for this project
rustup override set nightly
# Install AFL fuzzing tools
cargo install cargo-afl
If you encounter errors related to missing the nightly toolchain, follow the instructions above.
Clone the repository and build the project:
git clone <repository-url>
cd ssv-fuzz
# Build differential fuzzing Go libraries (required for differential targets)
cd diff_fuzzing
./build_libs.sh
cd ..
# Build the main project
cargo build --workspace --exclude fuzz
# Get the system ready for fuzzing
cargo afl system-config
# Build AFL++ instrumented fuzz targets
cd fuzz
cargo afl build --bin validate_ssv_message
cargo afl build --bin diff_fuzz_split
# (or use ./run_fuzzer.sh for interactive building)
validate_ssv_message
- SSVMessage validationqbft_target
- QBFT consensus mechanismcustom_ssz
- SSZ encoding/decodingreceive_target
- Message receiving pipelinecombine_signatures
- BLS signature combinationfuzz_key_id_try_from
- KeyId conversionfuzz_database_states
- Database states consistency
High Priority (Network Split Risk):
diff_fuzz_qbft
- QBFT consensus state machinediff_fuzz_ssv_message_encode_decode
- SSVMessage serializationdiff_fuzz_complete_message_validation
- Complete validation pipelinediff_fuzz_message_id_generation
- MessageID constructiondiff_fuzz_validator_consensus_data_decode_encode
- Validator consensus data
Medium Priority (Validator/Committee Issues):
diff_fuzz_signed_ssv_msg_decode_encode
- Basic signed message encodingdiff_fuzz_structured_signed_ssv_msg_decode_encode
- Structured message parsingdiff_fuzz_split
- Key splittingdiff_fuzz_partial_signature_validation
- Partial signature validationdiff_fuzz_committee_quorum_calculation
- Quorum calculationdiff_fuzz_message_validation_state
- Message validation state
Lower Priority (Performance/Edge Cases):
diff_fuzz_round_change_handling
- Round change mechanismdiff_fuzz_justification_validation
- Justification validation
The run_fuzzer.sh
script is the primary interface for all fuzzing operations:
./run_fuzzer.sh
Features:
- Target selection with interactive menu
- Integrated corpus generation
- Built-in crash analysis
- Build management with AFL++ instrumentation
- Session management and resuming
- Real-time monitoring and statistics
- Automatic directory structure setup
If you prefer manual control, you can configure the system for optimal performance:
# Optional: Configure system for optimal performance
cargo afl system-config # Run if you have root access
Then build and run targets manually:
# Build a specific target
cargo afl build --bin validate_ssv_message
# Run fuzzing (the script handles this automatically)
cargo afl fuzz -i afl_workdir/validate_ssv_message/input -o afl_workdir/validate_ssv_message/output target/debug/validate_ssv_message
The run_fuzzer.sh
script includes built-in corpus generation accessible from the menu. It provides target-specific optimization and structural variation for maximum AFL coverage.
For manual control:
cd corpus_generator
cargo run # Interactive mode
cargo run -- <target_name> # Generate for specific target
The fuzzing script automatically handles session resuming, input generation, and directory management.
For manual corpus management:
- Minimize corpus:
afl-cmin -i afl_workdir/<target>/output/queue -o minimized_corpus -- target/debug/<target>
- View statistics:
cargo afl whatsup -s afl_workdir/<target>/output
/fuzz
: Contains the fuzzing framework and targets/fuzz/fuzz_targets/standard/
: Standard fuzzing target implementations/fuzz/fuzz_targets/differential/
: Differential fuzzing target implementations/fuzz/Cargo.toml
: Dependencies for all fuzzing targets
/corpus_generator
: Intelligent test case generator for differential targets- Uses structural variation strategy for maximum coverage efficiency
- Supports all differential fuzzing targets with customized edge cases
/diff_fuzzing
: Differential fuzzing infrastructure/diff_fuzzing/src/lib.rs
: Rust FFI wrappers for Go functions/diff_fuzzing/sfuzz.go
: Go wrapper functions for SSV operations/diff_fuzzing/README.md
: Detailed differential fuzzing documentation
/afl_workdir
: AFL working directories (created by script)/afl_workdir/<target>/input
: Input test cases for each target/afl_workdir/<target>/output
: AFL fuzzing results
/src
: Main project source coderun_fuzzer.sh
: Interactive fuzzing script with differential target support
This project depends on components from:
- Sigp/Anchor - SSV protocol implementation
- Sigp/Lighthouse - Ethereum consensus client
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the same terms as the Sigp/Anchor project.