SLH-DSA Signature Precompile
Native precompile for NIST FIPS 205 SLH-DSA (SPHINCS+) hash-based post-quantum signatures
Abstract
This LP specifies a precompiled contract for verifying SLH-DSA (Stateless Hash-based Digital Signature Algorithm) signatures as standardized in NIST FIPS 205. The precompile implements SLH-DSA-192s (security level 3, small variant) verification at address 0x0200000000000000000000000000000000000007, providing stateless hash-based quantum-resistant signatures with ~15ms verification performance.
Motivation
SLH-DSA (formerly SPHINCS+) provides unique security properties compared to ML-DSA:
- Hash-based security: Security relies only on hash function collision resistance, not structured lattice problems
- Conservative security: More conservative post-quantum assumption than lattice-based schemes
- Stateless: No state management required (unlike legacy hash-based schemes like XMSS)
- Long-term confidence: Hash functions have decades of cryptanalytic history
- Backup option: Provides alternative to ML-DSA if lattice problems are broken
Use Cases
- Ultra-long-term archives: Documents meant to remain secure for 50+ years
- Diversified security: Use alongside ML-DSA for defense-in-depth
- Conservative applications: When lattice security is questioned
- Audit trails: Permanent, hash-based signatures for compliance
Specification
Precompile Address
0x0200000000000000000000000000000000000007
Input Format
| Offset | Length | Field | Description |
|---|---|---|---|
| 0 | 48 | publicKey | SLH-DSA-192s public key |
| 48 | 32 | messageLength | Message length as big-endian uint256 |
| 80 | 16224 | signature | SLH-DSA-192s signature |
| 16304 | variable | message | Message to verify |
Total minimum size: 16304 bytes (without message)
Output Format
32-byte word:
0x...0001- signature valid0x...0000- signature invalid
Gas Cost
gas = BASE_COST + (messageLength * PER_BYTE_COST)
Where:
BASE_COST = 500,000 gas (higher due to 15ms verification time)
PER_BYTE_COST = 50 gas (higher due to multiple hash operations)
Solidity Interface
interface ISLHDSA {
/**
* @dev Verifies an SLH-DSA-192s signature
* @param publicKey The 48-byte SLH-DSA-192s public key
* @param message The message that was signed
* @param signature The 16224-byte SLH-DSA-192s signature
* @return valid True if signature is valid
*/
function verify(
bytes calldata publicKey,
bytes calldata message,
bytes calldata signature
) external view returns (bool valid);
}
Rationale
Why SLH-DSA-192s?
SLH-DSA variants:
- 128s/128f: Level 1 (128-bit) - Small/Fast
- 192s/192f: Level 3 (192-bit) - Recommended - Balanced
- 256s/256f: Level 5 (256-bit) - Maximum security
We chose 192s (small, not fast) because:
- NIST level 3 matches our ML-DSA choice
- "Small" variant has smaller signatures (16KB vs 35KB for 192f)
- Verification time difference is minimal (15ms vs 12ms)
- Signature size is more important than signing speed for blockchain use
Gas Cost Justification
- Verification time: ~15ms on Apple M1
- Compared to ML-DSA: 139x slower (15ms vs 108μs)
- Base cost: ML-DSA is 100K gas, so 500K is 5x (conservative multiplier)
- Per-byte cost: 50 gas/byte due to multiple SHAKE-256 hashes
Why Both ML-DSA and SLH-DSA?
Having both provides:
- Algorithm diversity: If lattices are broken, hash-based still works
- Different trust assumptions: Lattices vs hash functions
- Use case optimization: ML-DSA for speed, SLH-DSA for conservatism
- Hybrid schemes: Can require both for maximum security
Backwards Compatibility
This LP introduces a new precompiled contract at a previously unused address. There are no backwards compatibility concerns:
- New functionality: The precompile address
0x0200000000000000000000000000000000000007has no prior use - No state changes: The precompile is stateless and read-only
- Optional adoption: Contracts may choose to use SLH-DSA alongside existing signature schemes
- Activation: Requires network upgrade (Quantum hard fork) for coordinated deployment
Migration Path
- Phase 1: Deploy precompile at activation height
- Phase 2: Contracts integrate SLH-DSA alongside ML-DSA (LP-311)
- Phase 3: Hybrid verification patterns adopted for critical applications
Security Considerations
Hash-Based Security
SLH-DSA security depends solely on:
- SHAKE-256 collision resistance
- No structured problems (unlike lattices)
- Post-quantum proven security reductions
Signature Size Trade-off
Large signatures (16KB) may impact:
- Transaction size limits
- Storage costs
- Bandwidth requirements
Mitigation: Use SLH-DSA selectively for high-value operations only.
Performance Impact
15ms verification is 139x slower than ML-DSA:
- Use for critical operations where conservatism is needed
- Batch verifications where possible
- Consider async verification for UX
Test Cases
Test Vector 1: Valid SLH-DSA-192s Signature
publicKey: 0x<48 bytes of SLH-DSA public key>
message: "Quantum-resistant hash-based signature"
signature: 0x<16224 bytes of SLH-DSA signature>
Expected: 0x...0001 (valid)
Expected Gas: ~502,100 gas
Test Vector 2: Invalid Signature
publicKey: 0x<48 bytes>
message: "Test message"
signature: 0x<16224 bytes of WRONG signature>
Expected: 0x...0000 (invalid)
Test Vector 3: Large Message
publicKey: 0x<48 bytes>
message: 0x<10KB data>
signature: 0x<16224 bytes>
Expected Gas: ~1,012,000 gas (500K base + 512K for 10KB message)
Reference Implementation
Implementation Status: ✅ COMPLETE
See: precompiles/slhdsa/
Key Files:
contract.go- Core precompile implementation (114 lines)module.go- Precompile registration (51 lines)contract_test.go- Comprehensive test suite (130 lines)ISLHDSA.sol- Solidity interface and library (133 lines)README.md- Complete documentation (329 lines)
Cryptography:
- Implementation: Uses native Go SPHINCS+ implementation
- Standard: NIST FIPS 205 compliant
- Variant: SLH-DSA-128s (32-byte public keys, 7,856-byte signatures)
Test Results: All tests passing with comprehensive coverage:
- Valid signature verification
- Invalid signature rejection
- Tampered message detection
- Input validation
- Gas cost verification
- Edge cases
Performance Benchmarks (Apple M1):
- Verification time: ~286μs for small messages
- Gas cost: 15,000 base + 10 gas/byte message
- Memory usage: Minimal (~8KB per operation)
Economic Impact
Comparison to ML-DSA
| Metric | SLH-DSA-128s | ML-DSA-65 | Ratio |
|---|---|---|---|
| Public Key | 32 bytes | 1,952 bytes | 61x smaller |
| Signature | 7,856 bytes | 3,293 bytes | 2.4x larger |
| Verify Time | ~286μs | ~108μs | 2.6x slower |
| Base Gas | 15,000 | 100,000 | 6.7x cheaper |
Use Case Guidance:
- SLH-DSA: Long-term archives, ultra-conservative applications
- ML-DSA: General-purpose, better performance, smaller signatures
Gas Cost Impact
SLH-DSA is CHEAPER than ML-DSA for small messages due to lower base cost:
- 32-byte message: 15,320 gas (SLH-DSA) vs 100,320 gas (ML-DSA)
- 1KB message: 25,240 gas (SLH-DSA) vs 110,240 gas (ML-DSA)
However, larger signatures increase storage costs.
Open Questions
-
Should we support other SLH-DSA variants?
- 192s/192f for higher security?
- 256s/256f for maximum security?
- Current implementation uses 128s for efficiency
-
Signature aggregation?
- Unlike BLS, SPHINCS+ signatures don't aggregate
- Multiple signatures require multiple verifications
- Could implement Merkle aggregation at application layer
-
Caching strategies?
- Should verification results be cached?
- Trade-off: gas savings vs security concerns
Implementation Notes
Key Size Discrepancy
The spec originally referenced 48-byte keys (SLH-DSA-192s), but the implementation uses:
- 32-byte public keys (SLH-DSA-128s)
- 7,856-byte signatures (SLH-DSA-128s "small" variant)
This was chosen for:
- Smaller public keys (better for storage)
- Still provides 128-bit post-quantum security
- Smaller signatures than "fast" variant (7,856 vs 17,088 bytes)
Integration with MPC/Threshold
Unlike ML-DSA, SPHINCS+ is stateless hash-based:
- No threshold variant exists
- Each signer must have full secret key
- For threshold use cases, use Ringtail (LP-320) instead
References
- NIST FIPS 205: https://csrc.nist.gov/pubs/fips/205/final
- SPHINCS+ Specification: https://sphincs.org/
- Implementation:
precompiles/slhdsa/ - LP-311: ML-DSA Precompile (complementary PQ signature)
- LP-320: Ringtail Threshold (PQ threshold variant)
Copyright
Copyright and related rights waived via CC0.