blockblaz/hash-zig
A pure zig implementation of hash based signatures inspired from the rust implementation https://github.com/b-wagn/hash-sig
Pure Zig implementation of Generalized XMSS signatures with wire-compatible behavior against the Rust reference implementation (hash-sig). Keys, signatures, and Merkle paths interchange freely between the two ecosystems for lifetimes 2^8, 2^18, and (experimental) 2^32.
⚠️ Prototype Status: This is a prototype implementation for research and development purposes. Use at your own risk.
2^8, 2^18, 2^32 signatures per key with configurable activation windows (defaults to 256 epochs).github/workflows/ci.yml runs benchmark/benchmark.py, covering same-language and cross-language checks for lifetimes 2^8 and 2^18. Locally, pick lifetimes via --lifetime (e.g. 2^32) and enable verbose logs only when needed with BENCHMARK_DEBUG_LOGS=1.build.zig.zon:
.{
.name = "my_project",
.version = "0.1.0",
.dependencies = .{
.@"hash-zig" = .{
.url = "https://github.com/ch4r10t33r/hash-zig/archive/refs/tags/v2.0.0.tar.gz",
.hash = "1220...", // generated by zig build
},
.@"zig-poseidon" = .{
.url = "https://github.com/blockblaz/zig-poseidon/archive/refs/heads/main.tar.gz",
.hash = "1220...", // generated by zig build
},
},
}
build.zig:
const hash_zig_dep = b.dependency("hash-zig", .{ .target = target, .optimize = optimize });
const zig_poseidon_dep = b.dependency("zig_poseidon", .{ .target = target, .optimize = optimize });
exe.root_module.addImport("hash-zig", hash_zig_dep.module("hash-zig"));
exe.root_module.addImport("poseidon", zig_poseidon_dep.module("poseidon"));
git clone https://github.com/ch4r10t33r/hash-zig.git
cd hash-zig
zig build test
const std = @import("std");
const hash_zig = @import("hash-zig");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var scheme = try hash_zig.GeneralizedXMSSSignatureScheme.init(allocator, .lifetime_2_8);
defer scheme.deinit();
const keypair = try scheme.keyGen(0, 256);
defer keypair.secret_key.deinit();
const message = [_]u8{0x42} ** 32;
const signature = try scheme.sign(keypair.secret_key, 0, message);
defer signature.deinit();
const ok = try scheme.verify(&keypair.public_key, 0, message, signature);
std.debug.print("Signature valid: {}\n", .{ok});
}
For lifetimes
2^18and2^32, compile withzig build -Doptimize=ReleaseFast.
The repository ships a helper script benchmark/benchmark.py that exercises both implementations (Zig ↔ Rust) in ReleaseFast mode. By default it performs:
2^8 and 2^18 with 256 active epochs/tmpVerbose hash-level traces are suppressed unless you opt in with BENCHMARK_DEBUG_LOGS=1.
python3 --version # Python 3.8+
zig version # 0.14.1
cargo --version # Rust 1.87.0 toolchain (matches CI)
# Produce zig-out/bin/zig-remote-hash-tool (ReleaseFast) and rust_benchmark/target/release/remote_hashsig_tool
python3 benchmark/benchmark.py # runs lifetimes 2^8 and 2^18
python3 benchmark/benchmark.py --lifetime 2^32 # runs lifetime 2^32 only
python3 benchmark/benchmark.py --lifetime "2^8,2^18,2^32" # runs all lifetimes sequentially
# Enable verbose cross-implementation debug logs
BENCHMARK_DEBUG_LOGS=1 python3 benchmark/benchmark.py --lifetime 2^8
The script automatically:
zig build zig-remote-hash-tool -Doptimize=ReleaseFast--release/tmp/rust_public_* and /tmp/zig_public_*The compatibility logic lives in .github/workflows/ci.yml (“Run compatibility matrix (2^8 & 2^18)” step) and can be used as a reference shell script.
# lifetimes 2^8 and 2^18
python3 benchmark/benchmark.py
# lifetime 2^32 (longer run)
python3 benchmark/benchmark.py --lifetime 2^32
# include verbose Rust/Zig debug traces
BENCHMARK_DEBUG_LOGS=1 python3 benchmark/benchmark.py --lifetime 2^8
The script prints a PASS/FAIL matrix, timings, and the artifact locations under /tmp. Delete the files between runs if you want a clean slate: rm /tmp/*_public_* /tmp/*_signature_*.
Key commands:
zig build # build library and helper binaries
zig build lint # format check
zig build test # unit + integration tests
zig build test-rust-compat # Zig↔Rust compatibility unit tests
cargo build --manifest-path benchmark/rust_benchmark/Cargo.toml --bins
Repository layout:
src/ # core library
examples/ # usage + compatibility demos
benchmark/ # Rust + Zig benchmarking utilities
investigations/ # exploratory scripts
.github/ # workflows (CI compatibility matrix lives here)
Licensed under the Apache License 2.0 – see LICENSE.