Overview
Thelight-hasher crate provides a generic Hasher trait for hash function usage on Solana, with implementations for Poseidon, Keccak-256, and SHA-256. It’s designed for use in Solana programs where compute budget is critical.
Crate: light-hasherLocation:
program-libs/hasher/Primary Hash: Poseidon over BN254
Key Features
Generic Interface
Trait-based design allows swapping hash functions
Poseidon
ZK-friendly hash used throughout Light Protocol
Zero Bytes
Precomputed zero-leaf hashes per hasher
Field Size
Utilities for BN254 field size truncation
Hasher Trait
Definition
Implementations
ID: 0
Algorithm: Poseidon hash over BN254 scalar field
Use case: Primary hash for Light Protocol (ZK-friendly)
Syscall:
Algorithm: Poseidon hash over BN254 scalar field
Use case: Primary hash for Light Protocol (ZK-friendly)
Syscall:
sol_poseidon (via syscall interface)ID: 1
Algorithm: Keccak-256
Use case: Ethereum compatibility, general hashing
Syscall:
Algorithm: Keccak-256
Use case: Ethereum compatibility, general hashing
Syscall:
sol_keccak256ID: 2
Algorithm: SHA-256
Use case: Legacy support, verifiable computation
Syscall:
Algorithm: SHA-256
Use case: Legacy support, verifiable computation
Syscall:
sol_sha256Poseidon Hash
Overview
Poseidon is a ZK-friendly hash function optimized for use in zero-knowledge proof systems:- Field: BN254 scalar field
- Width: 2-16 (for 1-15 inputs)
- Rounds: Optimized for security and efficiency
- Circuit-efficient: Few constraints in ZK proofs
Basic Usage
Field Size
Poseidon outputs must fit in the BN254 scalar field:21888242871839275222246405745257275088548364400416034343698204186575808495617
Poseidon Syscall
On Solana, Poseidon uses a syscall for efficiency:0: Circom parameters (default)1: x5 parameters
0: Big-endian (default)1: Little-endian
Hash Chain
Sequentially hash multiple values:Zero Bytes
Precomputed zero-leaf hashes for Merkle trees:Zero-Indexed Leaf
Initial value for indexed Merkle trees:DataHasher Trait
Hash structured data with discriminators:Error Codes
HasherError
| Error | Code | Description |
|---|---|---|
IntegerOverflow | 11001 | Integer overflow in computation |
InvalidNumberOfInputs | 11002 | Too many inputs (max 12) |
InvalidSliceLength | 11003 | Input slice wrong size |
ArithmeticUnderflow | 11004 | Arithmetic underflow |
BnInvalidPadding | 11005 | Invalid padding in BigNum |
PoseidonSyscallFailed | 11006 | Poseidon syscall error |
HashSetError | 11007 | Hash set operation failed |
AnchorSerializationError | 11008 | Serialization error |
PoseidonSyscallError
Detailed Poseidon syscall errors:| Error | Code | Description |
|---|---|---|
InvalidParameters | 1 | Invalid parameter selection |
InvalidEndianness | 2 | Invalid endianness flag |
InvalidNumberOfInputs | 3 | Input count out of range (1-12) |
EmptyInput | 4 | Input slice is empty |
InvalidInputLength | 5 | Input not 32 bytes |
BytesToPrimeFieldElement | 6 | Failed to convert to field element |
InputLargerThanModulus | 7 | Input exceeds field modulus |
VecToArray | 8 | Failed to convert vec to array |
U64Tou8 | 9 | Failed to convert u64 to u8 |
BytesToBigInt | 10 | Failed BigInt conversion |
InvalidWidthCircom | 11 | Invalid Circom width (2-16) |
Usage Examples
Hash Compressed Account
Merkle Tree Path Verification
Hash Chain for ZKP Batch
Multi-Hasher Support
Performance
Compute Units (approximate)
| Operation | Poseidon | Keccak | SHA-256 |
|---|---|---|---|
| Single hash | ~500 CU | ~100 CU | ~50 CU |
| Hash 2 values | ~700 CU | ~110 CU | ~60 CU |
| Hash 4 values | ~1100 CU | ~130 CU | ~80 CU |
Optimization Tips
Batch Hash Calls
Batch Hash Calls
Use
hashv instead of multiple hash calls:Minimize Input Count
Minimize Input Count
Poseidon cost increases with input count. Combine inputs when possible.
Use Zero Bytes
Use Zero Bytes
For Merkle trees, always use precomputed
zero_bytes() for empty subtrees.Choose Right Hasher
Choose Right Hasher
Use Poseidon only when ZK compatibility is needed. For general hashing, Keccak or SHA-256 are faster.
Feature Flags
Enables standard library features
Enables allocation without std
Enables Solana syscall integration
Enables SBF test utilities
Testing
Best Practices
Use Poseidon for ZK Circuits
Use Poseidon for ZK Circuits
Poseidon is optimized for zero-knowledge proofs. Use it for any data that will be verified in ZK circuits (compressed accounts, Merkle trees).
Consistent Byte Ordering
Consistent Byte Ordering
Always use little-endian for integers:
lamports.to_le_bytes()Include Discriminators
Include Discriminators
When hashing account data, always include the discriminator to prevent type confusion.
Validate Field Size
Validate Field Size
When passing hashes to ZK circuits, ensure they’re within the BN254 field using
hash_to_bn254_field_size_be.Resources
Source Code
View on GitHub
API Docs
Rust documentation
Poseidon Paper
Original Poseidon paper
Solana Syscalls
Solana syscall documentation