Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Contributing to HashSigs RHDL

HashSigs RHDL is a cryptographic hardware project. Changes must preserve the profile boundary, one-time-key safety, ready/valid behavior, and the distinction between evidence tiers. Start with the developer guide and the API documentation under /api/.

Before you start

  • Install Rust 1.96 through the pinned toolchain file.
  • Use Bun for every JavaScript or TypeScript command.
  • Use mdBook 0.5.4 for the guide. The documentation build rejects another version so navigation and rendered output remain reproducible.
  • Install Icarus Verilog and Verilator only for the RTL gates you intend to run.
  • Treat Vivado as a separate, resource-intensive evidence stage. Coordinate shared build hosts before starting it.

Do not start by editing generated Verilog. Cryptographic datapaths belong in Rust/RHDL; generated RTL is an artifact bound to the source commit and manifest.

Preserve the profile boundary

The workspace exposes two deliberately incompatible profiles:

  • LEGACY_KECCAK is byte-compatible with the pinned HashSigsRS revision and uses legacy Keccak-256 padding.
  • HASHSIGS_SHA256_GENERIC_V1 is the SHA-256 hardware-performance profile.

Never introduce a runtime fallback, infer a profile from serialized length, or accept one profile’s key or signature as the other. Add the profile identifier to protocol metadata whenever bytes leave the typed Rust boundary.

Security rules

  1. A WOTS private key signs at most one message. Tests and examples must never normalize private-key reuse.
  2. The 32-byte WOTS input is already a digest. Application-level prehashing and domain separation remain the caller’s responsibility.
  3. Secret-dependent branches, addresses, enables, iteration counts, and stalls require explicit review.
  4. Reset, backpressure, malformed frames, stale tags, and duplicate returns are correctness cases, not optional polish.
  5. Do not describe this custom construction as XMSS, SLH-DSA, FIPS 205, or a many-time signature system.

Read the security policy before changing a cryptographic or protocol boundary.

Change workflow

  1. Identify the owning crate and the evidence tier affected by the change.
  2. Add an independent software-oracle, known-answer, or protocol-invariant test.
  3. Implement the smallest Rust/RHDL change.
  4. Run focused unit and integration tests with one build job when memory use is material.
  5. Run strict formatting, Clippy, and Rustdoc checks.
  6. If lowering changed, regenerate and simulate the exact generated RTL.
  7. Regenerate Vivado evidence before changing a resource or timing statement.
  8. Update the canonical evidence manifest and guide only after the producing evidence page exists.

Useful baseline commands:

cargo fmt --all -- --check
cargo test --workspace --locked -j1
cargo clippy --workspace --all-targets --all-features --locked -j1 -- -D warnings
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --locked -j1
bun run docs:test
bun run docs:build:no-api
bun run docs:check

The production signer and verifier contain explicitly ignored, expensive gates. Run one only when its evidence page names it, and do not silently convert an ignored gate into ordinary CI.

Evidence changes

Every measured result must identify its source commit and dirty state, profile, topology, tool and version, target or simulator, constraint, artifact checksum, date, supported claims, and explicit nonclaims. A lower tier cannot inherit a claim from a higher tier or from a different source revision.

Keep negative results. A failed timing or route attempt is useful architecture evidence when its boundary is stated accurately.

Documentation changes

The guide is mdBook source under docs/book/; Rustdoc remains generated from crate documentation; /evidence/ is generated from docs/evidence/manifest.json. Do not hand-edit the generated site/ directory.

Documentation must not contain credentials, workstation paths, process IDs, private coordination notes, or links that pretend a missing page succeeded. Add a real page, redirect, or 404 instead.

Pull requests

Keep commits scoped, explain the evidence boundary, list commands actually run, and call out expensive gates not run. Reviewers should be able to distinguish a source claim, an emitted-RTL claim, a Vivado result, and a card measurement from the pull-request description alone.