Go implementation of generalized XMSS with tweakable hashes and incomparable encodings (Winternitz & Target-Sum variants).
This is a port of the Rust implementation at b-wagn/hash-sig, implementing the cryptographic constructions from:
- "Hash-Based Multi-Signatures for Post-Quantum Ethereum" [DKKW25a]
- "LeanSig for Post-Quantum Ethereum" [DKKW25b]
- Generalized XMSS (Construction 3) signature scheme
- Tweakable hash functions with SHA-3 backend (Section 7.2)
- Incomparable encodings:
- Winternitz encoding (Construction 5)
- Target-Sum Winternitz encoding (Construction 6)
- Merkle tree construction (Construction 1)
- Hash chains (Construction 2)
- Parallel computation for improved performance
- Full test coverage with parity to Rust implementation
go get github.com/aerius-labs/hash-sig-gopackage main
import (
"crypto/rand"
"fmt"
"github.com/aerius-labs/hash-sig-go/encoding/winternitz"
"github.com/aerius-labs/hash-sig-go/internal/prf"
"github.com/aerius-labs/hash-sig-go/th/message_hash"
"github.com/aerius-labs/hash-sig-go/th/tweak_hash"
"github.com/aerius-labs/hash-sig-go/xmss"
)
func main() {
// Setup components
prfInstance := prf.NewSHA3PRF(24, 24)
thInstance := tweak_hash.NewSHA3TweakableHash(24, 24)
mhInstance := message_hash.NewSHA3MessageHash(24, 24, 48, 4)
// Create Winternitz encoding
checksumLen := winternitz.ComputeChecksumLength(48, 4)
encInstance := winternitz.NewWinternitzEncoding(mhInstance, 4, checksumLen)
// Create XMSS with log lifetime = 8 (256 epochs)
xmssInstance := xmss.NewGeneralizedXMSS(prfInstance, encInstance, thInstance, 8)
// Generate keys
pk, sk := xmssInstance.KeyGen(rand.Reader, 0, 256)
// Sign a message
message := make([]byte, 32)
rand.Read(message)
sig, err := xmssInstance.Sign(rand.Reader, sk, 0, message)
if err != nil {
panic(err)
}
// Verify signature
valid := xmssInstance.Verify(pk, 0, message, sig)
fmt.Printf("Signature valid: %v\n", valid)
}Build the CLI tool:
go build ./cmd/hashsig-cliGenerate keys:
./hashsig-cli keygen -out mykeySign a message:
./hashsig-cli sign -sk mykey.sk -epoch 0 -msg <hex_message> -out sig.binVerify a signature:
./hashsig-cli verify -pk mykey.pk -epoch 0 -msg <hex_message> -sig sig.binRun all tests:
go test ./...Run benchmarks:
go test -bench=. ./xmss- Chunk size w ∈ {1,2,4,8} bits
- Checksum length n₁ = ⌊log_{2^w}(n₀(2^w−1))⌋ + 1
- Always succeeds (no retries needed)
- Target sum T = ⌈δ·v·(2^w−1)/2⌉ with δ ∈ {1.0, 1.1}
- May require retries (probabilistic encoding)
- Reduces verifier hashing cost
- [DKKW25a] "Hash-Based Multi-Signatures for Post-Quantum Ethereum" https://eprint.iacr.org/2025/055.pdf
- [DKKW25b] "LeanSig for Post-Quantum Ethereum" https://eprint.iacr.org/2025/1332.pdf
Apache Version 2.0.