Forty-five of the fifty-six suite modules keyed off <name>Config and eleven did not, in three other spellings: Verify, Threshold, Encapsulate. The LP-4200 unified PQCrypto block carried four of those conventions across its eight addresses — two KEMs named differently (mlkemConfig beside hqcEncapsulate) and two threshold schemes named differently (pulsarVerify beside coronaThreshold) — so the block that exists to be one thing did not read as one thing. The deviations also named an OPERATION where a precompile belongs. HQC decapsulates as well as encapsulates and the Verify precompiles do more than verify, so hqcEncapsulate was the name of one entry point standing in for the whole module. A config key selects a precompile; it is not a method selector. All fifty-six are <name>Config now. There is no compatibility shim: an upgrade.json naming an old key is naming something that does not exist, which luxd already refuses loudly, and every chain config in the estate moves with this. Co-authored-by: Hanzo Dev <[email protected]>
SLH-DSA Signature Verification Precompile
Overview
This precompile implements SLH-DSA (Stateless Hash-Based Digital Signature Algorithm) signature verification as specified in FIPS 205.
Address: 0x0200000000000000000000000000000000000007
FIPS 205 - SLH-DSA
SLH-DSA (FIPS 205, formerly SPHINCS+) is a post-quantum digital signature scheme based on hash functions. It provides:
- Quantum Resistance: Secure against attacks by quantum computers
- Stateless Operation: No state management required (unlike XMSS)
- Minimal Assumptions: Security based only on collision-resistant hash functions
- Conservative Security: Well-understood hash-based construction
Parameter Sets
SLH-DSA supports 12 parameter sets across 3 security levels:
Category 1 (128-bit security)
| Parameter Set | Hash Function | Signature Size | Sign Speed | Verify Speed |
|---|---|---|---|---|
| SHA2-128s | SHA-256 | 7,856 bytes | Slow | Fast |
| SHA2-128f | SHA-256 | 17,088 bytes | Fast | Fast |
| SHAKE-128s | SHAKE256 | 7,856 bytes | Slow | Fast |
| SHAKE-128f | SHAKE256 | 17,088 bytes | Fast | Fast |
Category 3 (192-bit security)
| Parameter Set | Hash Function | Signature Size | Sign Speed | Verify Speed |
|---|---|---|---|---|
| SHA2-192s | SHA-256/512 | 16,224 bytes | Slow | Fast |
| SHA2-192f | SHA-256/512 | 35,664 bytes | Fast | Fast |
| SHAKE-192s | SHAKE256 | 16,224 bytes | Slow | Fast |
| SHAKE-192f | SHAKE256 | 35,664 bytes | Fast | Fast |
Category 5 (256-bit security)
| Parameter Set | Hash Function | Signature Size | Sign Speed | Verify Speed |
|---|---|---|---|---|
| SHA2-256s | SHA-512 | 29,792 bytes | Slow | Fast |
| SHA2-256f | SHA-512 | 49,856 bytes | Fast | Fast |
| SHAKE-256s | SHAKE256 | 29,792 bytes | Slow | Fast |
| SHAKE-256f | SHAKE256 | 49,856 bytes | Fast | Fast |
Trade-offs:
- "s" (small): Smaller signatures, slower signing (~300-600ms)
- "f" (fast): Larger signatures, faster signing (~10-50ms)
- Verification speed is similar for both variants (~300-600μs)
Performance Benchmarks
Apple M1 Max Results:
| Operation | SHA2-128s | SHA2-256s |
|---|---|---|
| Sign | ~309ms | ~603ms |
| Verify | ~286μs | ~593μs |
| KeyGen | ~35ms | ~71ms |
Verification Throughput:
- SHA2-128s: ~3,500 signatures/second
- SHA2-256s: ~1,700 signatures/second
Gas Costs
Gas = BaseGas + (MessageLength * PerByteGas)
BaseGas = 15,000
PerByteGas = 10
Examples:
- Empty message: 15,000 gas
- 100-byte message: 16,000 gas
- 1KB message: 25,240 gas
- 10KB message: 115,000 gas
Usage
Solidity Interface
interface ISLHDSA {
function verify(
bytes calldata publicKey,
bytes calldata message,
bytes calldata signature
) external view returns (bool valid);
}
Example Contract
import {SLHDSAVerifier} from "./ISLHDSA.sol";
contract MyContract is SLHDSAVerifier {
function processSignedData(
bytes calldata publicKey,
bytes calldata data,
bytes calldata signature
) external {
// Verify signature with automatic revert on failure
require(
verifySLHDSASignature(publicKey, data, signature),
"Invalid signature"
);
// Process data - signature is valid
// ...
}
}
Using the Library
import {SLHDSALib} from "./ISLHDSA.sol";
contract Example {
function verifyWithRevert(
bytes memory publicKey,
bytes memory message,
bytes memory signature
) public view {
// Automatically reverts if signature is invalid
SLHDSALib.verifyOrRevert(publicKey, message, signature);
}
function estimateVerificationGas(uint256 messageLength)
public
pure
returns (uint256)
{
return SLHDSALib.estimateGas(messageLength);
}
}
TypeScript/ethers.js
const SLHDSA_ADDRESS = '0x0200000000000000000000000000000000000007';
const SLHDSA = new ethers.Contract(
SLHDSA_ADDRESS,
['function verify(bytes,bytes,bytes) view returns(bool)'],
provider
);
const isValid = await SLHDSA.verify(publicKey, message, signature);
console.log('Signature valid:', isValid);
Input Format
The precompile expects input in the following format:
[mode(1 byte)] [pubKeyLen(2 bytes)] [publicKey] [msgLen(2 bytes)] [message] [signature]
Fields:
mode(1 byte): Parameter set identifier (0-11)- 0: SHA2-128s, 1: SHAKE-128s, 2: SHA2-128f, 3: SHAKE-128f
- 4: SHA2-192s, 5: SHAKE-192s, 6: SHA2-192f, 7: SHAKE-192f
- 8: SHA2-256s, 9: SHAKE-256s, 10: SHA2-256f, 11: SHAKE-256f
pubKeyLen(2 bytes, big-endian): Length of public keypublicKey(32, 48, or 64 bytes): The SLH-DSA public keymsgLen(2 bytes, big-endian): Length of messagemessage(variable): The message that was signedsignature(7856-49856 bytes): The SLH-DSA signature
Output Format
Single byte indicating verification result:
0x01: Signature is valid0x00: Signature is invalid
Security Considerations
Post-Quantum Security
SLH-DSA provides security against quantum computer attacks because:
- Based on hash functions (no algebraic structure to exploit)
- No known quantum algorithm for breaking collision resistance
- Conservative security assumptions
Hash Function Requirements
- SHA-2: Industry standard, widely deployed
- SHAKE: SHA-3 based, newer but standardized
Signature Size Trade-offs
Large signatures are a characteristic of hash-based schemes:
- Small variants ("s"): More efficient for storage
- Fast variants ("f"): Better for high-throughput signing
Recommended Parameter Sets
-
General use: SHA2-128s or SHA2-256s
- Smaller signatures, acceptable signing speed for most applications
-
High-throughput signing: SHA2-128f or SHA2-256f
- When signing speed is critical and storage is available
-
Conservative security: SHA2-256s
- Maximum security level, reasonable signature size
Comparison with Other Schemes
| Scheme | Type | Signature Size | Verify Time | Quantum Secure |
|---|---|---|---|---|
| ECDSA | Elliptic Curve | 65 bytes | ~88μs | ❌ |
| ML-DSA-65 | Lattice | 3,309 bytes | ~108μs | ✅ |
| SLH-DSA-SHA2-128s | Hash-based | 7,856 bytes | ~286μs | ✅ |
| SLH-DSA-SHA2-256s | Hash-based | 29,792 bytes | ~593μs | ✅ |
Trade-offs:
- SLH-DSA has larger signatures than ML-DSA
- SLH-DSA has slower verification than ML-DSA
- SLH-DSA has more conservative security assumptions
- SLH-DSA requires no state management
Implementation Details
- Library: Cloudflare CIRCL v1.6.1
- Standard: FIPS 205 (Final)
- Algorithm: SLH-DSA with FIPS 205 parameters
- Hash Functions: SHA-256, SHA-512, SHAKE256
- Security Levels: 128-bit, 192-bit, 256-bit
Error Handling
The precompile returns 0x00 (invalid) for:
- Invalid mode identifier
- Incorrect public key size
- Incorrect signature size
- Failed signature verification
- Malformed input
No exceptions are thrown - all errors result in 0x00 output.
Gas Optimization Tips
- Batch Verification: Group multiple verifications to amortize overhead
- Off-chain Verification: Verify off-chain when possible, only verify on-chain when necessary
- Signature Aggregation: Use BLS or other aggregatable schemes when applicable
- Parameter Selection: Use 128-bit security when 256-bit is not required
Migration from Classical Signatures
When migrating from ECDSA to SLH-DSA:
- Storage: Account for larger signatures in data structures
- Gas Costs: Budget for higher verification costs
- Signing Infrastructure: Update to support SLH-DSA key generation
- Backwards Compatibility: Support both schemes during transition
Testing
cd /Users/z/work/lux/standard
forge test --match-path "**/slhdsa/**"
References
- FIPS 205: Stateless Hash-Based Digital Signature Standard
- SLH-DSA Website
- Cloudflare CIRCL Library
- NIST PQC Standardization
License
Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved. See the file LICENSE for licensing terms.