A Rust implementation of the Poseidon hash function designed to work with the ZisK VM.
This project implements a custom Poseidon hash function that can be used within ZisK circuits. The implementation includes:
- Custom field arithmetic operations
- Simplified Poseidon hash algorithm
- Integration with ZisK for zero-knowledge proof generation
- Build system for generating input files
- Field Operations: Modular arithmetic with a Mersenne prime field modulus
- Poseidon Hash: Custom implementation with S-box and mixing layers
- ZisK Integration: Built to work with the ZisK zero-knowledge proof system
- Configurable Iterations: Supports variable number of hash iterations
poseidon_hasher/
├── src/
│ └── main.rs # Main ZisK circuit implementation
├── build.rs # Build script for input generation
├── Cargo.toml # Rust dependencies and project configuration
├── proof/ # Generated proofs and results
└── build/ # Build artifacts (generated input files)
Note: This is a ZisK-specific project that compiles to RISC-V architecture and generates zero-knowledge proofs.
Before building and running this project, ensure you have:
- Rust: Latest stable version
- cargo-zisk: ZisK CLI tool for building and proving
- ZisK: Zero-knowledge proof system installation
- MPI: For concurrent proof generation (optional)
- CUDA Toolkit: For GPU support (optional, NVIDIA only)
ziskos: ZisK proof systembyteorder: Byte order conversion utilities
To build the project for ZisK:
# Build for ZisK (RISC-V architecture)
cargo-zisk build --release
# The resulting ELF file will be generated in:
# ./target/riscv64ima-zisk-zkvm-elf/release/poseidon_hasherThe main circuit takes a number n as input and computes the Poseidon hash n times sequentially.
The input should be an 8-byte little-endian representation of a u64 integer.
The output consists of 8 32-bit values representing the final hash result.
Before generating a proof, test your compiled program using the ZisK emulator:
# Build and execute in one command
cargo-zisk run --release -i build/input.bin
# Or build first, then execute separately
cargo-zisk build --release
ziskemu -e target/riscv64ima-zisk-zkvm-elf/release/poseidon_hasher -i build/input.bin
# If you encounter step limit errors, increase max steps
ziskemu -e target/riscv64ima-zisk-zkvm-elf/release/poseidon_hasher -i build/input.bin -n 10000000000First time setup or after rebuilding:
cargo-zisk rom-setup -e target/riscv64ima-zisk-zkvm-elf/release/poseidon_hasher -k $HOME/.zisk/provingKeyVerify that all constraints are satisfied:
cargo-zisk verify-constraints -e target/riscv64ima-zisk-zkvm-elf/release/poseidon_hasher -i build/input.bin -w $HOME/.zisk/bin/libzisk_witness.so -k $HOME/.zisk/provingKeyGenerate the zero-knowledge proof:
cargo-zisk prove -e target/riscv64ima-zisk-zkvm-elf/release/poseidon_hasher -i build/input.bin -w $HOME/.zisk/bin/libzisk_witness.so -k $HOME/.zisk/provingKey -o proof -a -yVerify the generated proof:
cargo-zisk verify -p ./proof/vadcop_final_proof.bin -s $HOME/.zisk/provingKey/zisk/vadcop_final/vadcop_final.starkinfo.json -e $HOME/.zisk/provingKey/zisk/vadcop_final/vadcop_final.verifier.bin -k $HOME/.zisk/provingKey/zisk/vadcop_final/vadcop_final.verkey.jsonGet execution metrics and statistics:
# Execution metrics
cargo-zisk run --release -i build/input.bin -m
# Execution statistics
cargo-zisk run --release -i build/input.bin -xFor improved performance, you can generate proofs using multiple processes:
mpirun --bind-to none -np <num_processes> -x OMP_NUM_THREADS=<num_threads_per_process> -x RAYON_NUM_THREADS=<num_threads_per_process> target/release/cargo-zisk prove -e target/riscv64ima-zisk-zkvm-elf/release/poseidon_hasher -i build/input.bin -o proof -a -yNote: <num_processes> × <num_threads_per_process> should match your available CPU cores.
For NVIDIA GPUs, build ZisK with GPU support:
cargo build --release --features gpuGPU support can be combined with concurrent proof generation for maximum performance.
- Field Modulus: Uses 2^63 - 1 (Mersenne prime)
- Addition: Modular addition with overflow handling
- Multiplication: Modular multiplication using 128-bit arithmetic
- State Size: 3 field elements
- Rounds: 3 rounds with custom round keys
- S-box: x^5 transformation
- Mixing: Linear transformation layer
- Uses
#![no_main]andziskos::entrypoint!macro - Reads input using
read_input() - Sets output using
set_output()
The build.rs script generates input files for testing:
- Creates
build/input.binwith a default value of 20 iterations - Ensures proper directory structure
The project is specifically designed for ZisK:
- Uses
#![no_main]andziskos::entrypoint!macro - Compiles to RISC-V architecture for ZisK execution
- Integrates with ZisK's input/output system using
read_input()andset_output() - Generates zero-knowledge proofs for computational integrity
The project includes generated proofs in the proof/ directory:
result.json: Proof verification resultsvadcop_final_proof.bin: Final proof binaryproofs/: Additional proof artifacts
This project is open source and available under the MIT License.
Contributions are welcome! Please ensure all code follows Rust best practices and includes appropriate tests.