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

HashSigs RHDL

A contributor's guide to a profile-separated WOTS+ implementation authored in Rust/RHDL, emitted as Verilog, and evaluated one evidence tier at a time.

This workspace implements the non-Solana WOTS+ technology behind a pinned HashSigsRS revision. The software oracle and hardware models share the same parameters—n = 32, w = 16, and 67 chains—but they expose two intentionally incompatible hash profiles.

LEGACY_KECCAK

Compatibility

Byte-compatible with the pinned upstream vectors. It uses legacy Keccak-256 padding, not SHA3-256.

HASHSIGS_SHA256_GENERIC_V1

Hardware performance

The active three-lane signer and verifier use SHA-256. Their keys and signatures are not compatible with the legacy profile.

One private key signs one message

WOTS is a one-time signature. Reusing a private key can reveal enough chain material to enable a forgery. Consuming Rust types reduce accidental reuse, but durable key lifecycle remains a system responsibility.

What is active now

The production SHA-256 signer is three lane-local clusters with four live WOTS contexts per cluster: three lanes × four contexts = twelve contexts. The production SHA-256 verifier has the same 3×4 topology and adds fail-closed tag, timing, framing, and peer-abort handling.

An earlier nine-context/three-lane transport fabric remains useful as a tested prototype and library component. It is not the active production signer or verifier topology.

The hardware verifier supports only HASHSIGS_SHA256_GENERIC_V1. Legacy Keccak verification is provided by the software reference implementation; the site does not imply a legacy hardware verifier.

Choose a path

Contribute code

Read the active system map, then follow the leaf-to-top workflow.

Review security

Start with the cryptographic contract and security policy.

Audit a claim

Use the evidence ladder, then open the generated evidence matrix.

The API portal provides project navigation and crate cards. The standard Rustdoc index provides a native workspace crate list and styling, search, item pages, and source browser. The evidence matrix is generated from a checked manifest so a number, source revision, tier, claim, and nonclaim stay together.

Start here

HashSigs RHDL is easiest to understand in four layers:

  1. Cryptographic contract. Learn the two profiles, WOTS parameters, message digest boundary, and one-time-key requirement.
  2. Task graph. Follow one signer or verifier job through contexts, tags, hash lanes, result framing, and backpressure.
  3. Source hierarchy. Move from host-side oracle types to leaf kernels, cluster controllers, production tops, and deterministic RTL export.
  4. Evidence. Ask what was actually executed: source simulation, generated RTL, synthesis, route, or a card.

The project is not a Solana integration. It also does not implement a Merkle tree or turn WOTS into a many-time signature. Applications that need many signatures must supply a reviewed one-time-key allocation and authentication scheme above this primitive.

Fast orientation

QuestionAnswer
What is signed?An already-hashed, domain-separated 32-byte message digest
Signature size2,144 bytes: 67 × 32-byte chain values
Public key wire size64 bytes: public seed plus endpoint hash
Fused signer output2,208 bytes in 35 512-bit beats
Active signerSHA-256, three clusters, four contexts each
Active hardware verifierSHA-256 only, three clusters, four contexts each
Legacy compatibilitySoftware oracle plus Keccak/RHDL compatibility tests
Hardware languageCryptographic datapaths are Rust/RHDL; Verilog is generated

Next, make a first change in 30 minutes, choose a reading path, or build locally.

Make a first change in 30 minutes

This path is for a small, reviewable Rust/RHDL change. It is an orientation exercise, not a promise that every hardware change can be completed in half an hour. Read Build and inspect locally first if the workspace is not already available.

Completion warning: the highest passed signer-performance tier is generated RTL. The reported 481.6875-cycle sustained interval and its 519,008.693-results/s normalization at 250 MHz are not measured U280 results. U280 synthesis, route, and card execution remain pending, so the project must not be described as hardware-complete.

Minute 0–5: choose the cryptographic contract

Choose the profile before interpreting a key, signature, or hash. The two profiles are separate Rust types and separate compatibility promises.

ProfileCompatibility promiseActive hardware boundaryNever infer
LEGACY_KECCAK / LegacyKeccakByte-compatible with pinned HashSigsRS commit 2d315dd4168804b7cbc51c51a1bf7ca27bf74140; legacy Keccak 0x01 domain byteKeccak compatibility engine; no active hardware verifierSHA3-256 behavior or compatibility with the SHA-256 profile
HASHSIGS_SHA256_GENERIC_V1 / HashSigsSha256GenericV1Deliberately incompatible SHA-256 profile using the same WOTS parametersActive 3×4 signer and fail-closed 3×4 verifierPinned HashSigsRS key or signature compatibility

There is no automatic profile fallback. A surrounding protocol must authenticate the profile before it parses untagged bytes. See Two incompatible profiles for the full boundary table and vector provenance.

Minute 5–10: find the owning source

Start at the narrowest owner. Do not edit generated Verilog; change its Rust/RHDL producer and regenerate only through the documented gate.

Intended changeOwning sourceFirst focused gate
Profile-safe wire typescrates/hashsigs-types/src/lib.rscargo test -p hashsigs-types --locked -j1
Legacy software compatibilitycrates/hashsigs-reference/src/lib.rscargo test -p hashsigs-reference --test upstream_compatibility --locked -j1
Legacy Keccak datapathcrates/keccak-rhdl/src/cargo test -p keccak-rhdl --test compatibility --locked -j1
SHA-256 primitive, lane, or farmcrates/sha256-rhdl/src/cargo test -p sha256-rhdl --locked -j1
WOTS digits, tags, or block constructioncrates/wots-rhdl/src/blocks.rscargo test -p wots-rhdl --test tag_and_blocks --locked -j1
Signer task graphcrates/wots-rhdl/src/engine.rscargo test -p wots-rhdl --test engine --locked -j1
Four-context signer clustercrates/wots-rhdl/src/cluster.rscargo test -p wots-rhdl --test cluster --locked -j1
Three-cluster signer topcrates/wots-rhdl/src/top.rscargo test -p wots-rhdl --test top --locked -j1
SHA-256 verifier context or topcrates/wots-rhdl/src/verify/cargo test -p wots-rhdl --test verify_sha --locked -j1 or --test verify_top
RTL registry and export gatescrates/rhdl-gen/src/cargo test -p rhdl-gen --test cli --locked -j1

Use the complete Source map when a change crosses one of these boundaries. U280 scripts and constraints live under fpga/u280/, but they are evidence infrastructure rather than a suitable first cryptographic change.

Minute 10–20: make one test-backed change

  1. Read the owning module’s public contract and its focused test.
  2. Add or update an expectation derived from a pinned vector or independent software oracle—not a second call into the datapath under test.
  3. Keep the cryptographic datapath in Rust/RHDL. Shell adapters, constraints, Tcl, and testbench wrappers are separate integration boundaries.
  4. Keep profile types explicit. A convenience conversion must not make legacy and SHA-256 keys or signatures interchangeable.
  5. Keep the patch inside one source owner unless the test demonstrates why a boundary must move.

Minute 20–30: run the narrow gate and report honestly

Run the focused command from the ownership table, then expand only as the change requires. The broader order is leaf crate, owning integration test, workspace tests, generated-RTL equivalence, synthesis, route, then card execution. Some full-lane and descriptor tests are intentionally ignored by default; a skipped expensive test is not a pass.

In the handoff, record:

  • the profile and source owner changed;
  • the exact commands actually run and their outcomes;
  • the highest evidence tier reached;
  • every relevant test or hardware gate not run; and
  • whether generated artifacts were refreshed.

The Evidence ladder defines what each result can establish. Do not promote a source-simulation result into an RTL claim or a normalized RTL rate into an FPGA claim.

Hardware target box

These are gates for a future exact U280 artifact chain, not properties already proved by the current evidence set.

GateExact project boundary
250 MHz basis4.000 ns; 500,000 fused results/s permits at most 500 cycles/result
Current generated-RTL interval23,121 cycles / 48 results = 481.6875 cycles/result; 519,008.693 results/s when normalized at 250 MHz only
Clock goal3.333 ns / 300 MHz in a separate run; the same rate target permits 600 cycles/result only after that clock is justified
LUT limitAt most 200,000
Register limitAt most 300,000
DSP limitAt most 4,000; this is the absolute project ceiling

The 250 MHz run is the normalization basis and first hardware gate. The 300 MHz goal does not replace it and cannot be claimed from synthesis estimates alone. Every future remote U280 Vivado, Vitis, XRT, or card flow must first have explicit ownership in both coordination ledgers and enter through the checked-in U280 lock wrapper. It ignores caller-controlled HOME, uses the effective user’s canonical passwd-home lock, and fails immediately rather than waiting. The ledger acknowledgment and same-UID advisory lock prevent accidental competing work; they are not cryptographic ledger proof or a boundary against a malicious same-UID process. If the lock cannot be acquired immediately, stop; do not wait, probe another owner’s work, or start a competing flow. See Read throughput correctly and the U280 evidence workflow before staging any hardware run.

Reading paths

New Rust/RHDL contributor

  1. Make a first change in 30 minutes
  2. WOTS+ in this project
  3. Active system map
  4. RHDL and generated Verilog
  5. Source map
  6. Test from leaf to top

Cryptography or protocol reviewer

  1. Two incompatible profiles
  2. One-time-key lifecycle
  3. Streams and packed interfaces
  4. SHA-only hardware verifier
  5. Security policy

FPGA, timing, or resource contributor

  1. Production signer
  2. Hash engines
  3. Read throughput correctly
  4. Generate and validate RTL
  5. U280 evidence workflow

Evidence auditor

  1. Evidence ladder
  2. Generated evidence matrix
  3. The source evidence record linked by the matrix
  4. The exact artifact manifest and checksums named by that record

No reading path treats a normalized simulator rate as measured FPGA throughput.

Build and inspect locally

The pinned Rust toolchain is 1.96. Use one Cargo job for memory-intensive RHDL graphs and Bun for all JavaScript or TypeScript commands.

Fast checks

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

Expensive production descriptor and full-source tests are ignored by default. Run an ignored test only through the command documented by its evidence page.

Documentation

Install the verified mdBook 0.5.4 binary, then run:

bun install --frozen-lockfile
bun run docs:test
bun run docs:build:no-api
bun run docs:check

docs:build:no-api builds the guide and evidence pages without compiling Rust. The publication build uses bun run docs:build, which runs standard cargo doc --workspace --no-deps for /rustdoc/ and a second, presentation-only Rustdoc build for the /api/ crate portal. Generated output lives in site/ and must not be edited or committed.

For the final local publication gate, run the build and release audit in one ordered command:

bun run docs:release

That command requires the emitted full commit/tree identity to match the clean checkout and rejects a placeholder or stale Rustdoc tree. The build writes separate /api/build-metadata.json and /rustdoc/build-metadata.json inventories whose aggregate digests cover every file in their respective trees; the release checker recomputes both digests and binds them to the publication commit and tree.

Preview the static Pages output without authenticating or touching a remote account:

bun run docs:preview

An unknown path must return the top-level 404.html; there is deliberately no single-page-app catch-all rewrite.

Cryptographic contract

This project implements a custom HashSigsRS WOTS+ construction with a typed profile boundary. The contract is smaller than an application signature system:

  • input is one 32-byte message digest;
  • a WOTS private key signs at most once;
  • the signature contains one value from each of 67 hash chains;
  • the public key contains a 32-byte public seed and a 32-byte hash of all chain endpoints;
  • profile identity is external metadata, not a byte embedded in the key.

The contract does not allocate one-time keys, authenticate a tree root, define an application prehash, or provide a many-time signature protocol.

Read WOTS+ in this project for the calculation, then two incompatible profiles before handling serialized values.

WOTS+ in this project

The security parameter is n = 32 bytes and the Winternitz base is w = 16. A 256-bit message digest becomes 64 hexadecimal digits. Three additional hexadecimal digits encode the checksum, producing 67 chains in total.

32-byte digest → 64 base-16 digits
checksum       →  3 base-16 digits
total          → 67 chain digits

For a message digit d, signing advances that chain from its private segment to position d. Verification advances the signature value from d to endpoint 15. Hashing the 67 endpoints produces the public-key hash.

Domain inputs

The pinned construction derives its function key, masks, and secret segments through domain-separated PRF inputs. The compatibility profile must retain the upstream byte order and legacy Keccak padding exactly. The SHA-256 profile uses the same WOTS parameters and logical domains but produces unrelated keys and signatures.

Fixed signer work

The fused SHA-256 private-seed signer computes the signature and corresponding public key together. Advancing every chain to its endpoint keeps the hardware work fixed and allows the signature value at the message digit to be captured along the way. The complete operation costs exactly 1,258 SHA-256 compression blocks.

Fixed work is an implementation property, not proof of side-channel safety. Memory addresses, enables, arbitration, reset behavior, physical placement, and power still require separate analysis.

Serialized profile identity

Keys and signatures contain no in-band profile tag. Store or authenticate the profile identifier next to every serialized value. Length is not a valid profile detector because both profiles use the same WOTS parameters.

Two incompatible profiles

LEGACY_KECCAK

This profile reproduces the pinned HashSigsRS commit 2d315dd4168804b7cbc51c51a1bf7ca27bf74140 construction byte for byte. Its hash is Keccak-256 with the legacy 0x01 domain byte. It is not standardized SHA3-256, whose domain encoding differs.

The five checked-in upstream vectors bind this compatibility claim. Legacy verification exists in the software reference implementation. There is no active legacy Keccak hardware verifier top.

HASHSIGS_SHA256_GENERIC_V1

This profile instantiates the same WOTS parameters with SHA-256. It is the active hardware-performance profile and owns the three 64-stage compression lanes, production signer, and fail-closed hardware verifier.

It is not key- or signature-compatible with LEGACY_KECCAK. Calling it “generic” does not make its byte strings portable to another WOTS parameter set or standard.

Boundary table

PropertyLegacy KeccakSHA-256 generic v1
Rust profile typeLegacyKeccakHashSigsSha256GenericV1
Stable profile nameLEGACY_KECCAKHASHSIGS_SHA256_GENERIC_V1
Hash paddingLegacy Keccak 0x01SHA-256 padding
Pinned upstream compatibilityYesNo; deliberately incompatible
Production hardware signerCompatibility engine exists, not performance topActive 3×4 top
Production hardware verifierNoActive 3×4 top
Software sign/verifyYesYes

Never add an automatic fallback that tries both profiles. A protocol must select one authenticated profile before parsing untagged bytes.

One-time-key lifecycle

WOTS exposes values from hash chains. Two signatures from the same private key can expose complementary positions and enable an attacker to construct a value needed for another message. The safe rule is exact: one private key, at most one signed message.

What the Rust API helps with

The software reference uses non-Clone, consuming private-key values for signing. Profile parameters are also separate Rust types. These choices prevent several accidental mistakes inside one process.

They do not prevent:

  • reconstructing the same key from a reused seed;
  • restoring an old database snapshot;
  • two machines allocating the same one-time index;
  • replaying a hardware request after uncertain completion;
  • copying raw private material before it enters the typed API.

System responsibility

A deployment needs an atomic allocator and durable state transition such as:

unused → reserved → consumed

Do not return reserved to unused after an ambiguous timeout. If the system cannot prove that no signature was produced, burn that key.

Bind the allocation identity, cryptographic profile, application domain, and message digest in authenticated metadata. Backup and disaster-recovery procedures must preserve consumed state.

Reset is not key rollback

Hardware reset invalidates in-flight ownership and flushes valid state. It does not make an already accepted private key safe to reuse, and it does not claim physical scrubbing of every wide inactive register or memory bit.

Standards and nonclaims

This repository uses primary standards to define hash behavior and to explain what its custom construction is not:

  • FIPS 180-4 defines SHA-256.
  • FIPS 202 defines SHA-3; the legacy profile intentionally uses older Keccak padding instead.
  • RFC 8391 specifies XMSS.
  • FIPS 205 specifies SLH-DSA.

HashSigs RHDL is not an implementation of RFC 8391 or FIPS 205. It has no Merkle authentication path, hypertree, or standardized parameter-set encoding. It must not be presented as a drop-in standardized post-quantum signature.

Hash-based one-way assumptions are relevant to post-quantum analysis, but that does not substitute for review of this construction, parameter selection, one-time-key management, implementation leakage, or the surrounding protocol.

Architecture

The performance design is a tagged task graph. It does not dedicate one complete hash engine to one signature, and “pipeline” does not mean one linear register chain from input to output.

The active SHA-256 hierarchy has three repeated lane-local clusters. Each cluster owns four independent WOTS contexts, one exact-64-cycle compression lane, request arbitration, response routing, and a bounded result framer. A narrow global top distributes complete jobs and merges complete results.

                         one input stream
                                │
                  rotating whole-frame admission
                    ┌───────────┼───────────┐
                    ▼           ▼           ▼
               cluster 0   cluster 1   cluster 2
               4 contexts  4 contexts  4 contexts
               1 SHA lane  1 SHA lane  1 SHA lane
                    └───────────┼───────────┘
                         result-frame merge
                                │
                         one output stream

The signer and verifier reuse this 3×4 shape but have different context state, work accounting, framing direction, and fault rules.

Read the active system map before opening the detailed signer or verifier pages.

Active system map

Production signer

Sha256SignerTop specializes the production top around three replicated Sha256LaneLocalCluster instances. Each cluster has four SingleContextWorkEngine contexts and one 64-round SHA-256 compression lane.

The global top selects a cluster only for beat zero, then holds that cluster for the complete frame. Output frames also remain noninterleaved. Local result capture can release a context before a stalled global consumer accepts the final beat; registered ownership preserves the held result.

Production verifier

Sha256VerifierTop specializes three Sha256VerifierCluster instances. Each cluster has four verifier contexts, one compression lane, and an expected-tag transport that aligns each issued token with its exact 64-cycle return.

Any malformed, missing, extra, mistimed, misrouted, or rejected return poisons the cluster. The top registers global poison, broadcasts peer abort, drains identified error completions, and does not silently reuse a suspect context.

What is historical

The ShaTransportFabric module models nine contexts sharing three lanes and has extensive fairness and tag-routing tests. It was an important prototype for parallel scheduling, but the active signer and verifier use twelve contexts arranged as three autonomous four-context clusters.

Do not copy the historical 9-context count into production throughput, state, or resource calculations.

Profile coverage

LayerLegacy KeccakSHA-256 generic v1
Software oracleSign and verifySign and verify
Hash RHDLIterative Keccak and primitive export64-stage compression lane and farm
Production hardware signerCompatibility engine, not active performance topActive 3×4 signer
Production hardware verifierNot implementedActive 3×4 fail-closed verifier

Evidence boundary

The hierarchy described here is source structure. Mapped instance counts, resource use, timing, placement, route, and physical throughput require the corresponding higher evidence tier.

Production signer

The SHA-256 signer accepts one fused private-seed job and returns the signature plus public key produced from that same one-time key.

Work per job

Each job consumes exactly 1,258 SHA-256 compression blocks:

  • one private-seed hash;
  • one public-seed PRF;
  • sixteen mask PRFs;
  • 67 secret PRFs;
  • two blocks for each 64-byte secret-segment hash;
  • 67 × 15 chain transitions; and
  • 34 blocks for the 2,144-byte endpoint hash.

The context captures each signature segment when its chain reaches the message digit, while continuing to endpoint 15 for public-key derivation. Fixed work removes message-digit variation from signer task count.

One cluster

Four contexts share one compression lane. Context state records task dependencies, expected tags, retained signature banks, endpoint state, and result ownership. The cluster:

  1. allocates a free context to a complete input job;
  2. issues ready tasks fairly without breaking dependencies;
  3. routes exact-tag lane returns to the owning context;
  4. captures one finished context into a bounded 35-beat framer; and
  5. releases the context exactly once on a successful final transfer or an identified error completion.

Global top

The top rotates whole-job admission over three clusters. It never stripes one job across clusters. The registered output merge holds a complete beat stable under backpressure and keeps frames noninterleaved.

There are twelve live contexts, not nine. Three compression lanes can each accept one block per cycle after fill, but scheduler dependencies and framing determine the observed result interval.

Reset and faults

Reset flushes valid ownership, requests, retained frames, releases, and errors. Data registers whose valid bits are clear need not hold a defined value. A job accepted before an uncertain reset must still be treated as a consumed one-time key by the surrounding system.

Cluster faults become identified error completions. The top does not convert a fault into a successful frame and does not release credit more than once.

Current evidence

The signer has production source simulation, finite generated-RTL equivalence, and sustained generated-RTL cycle evidence. Open the evidence matrix for exact commits and nonclaims. Those tiers alone do not establish a U280 clock, resource count, route, or card rate.

SHA-only hardware verifier

The active hardware verifier implements HASHSIGS_SHA256_GENERIC_V1. It does not accept a legacy Keccak signature. Legacy verification remains a software reference operation.

Input and result

One canonical verifier frame is 2,240 bytes, exactly 35 512-bit beats:

signature (2,144) || public seed (32) || public-key hash (32) || message (32)

The message is already a 32-byte digest. Every beat has a full keep mask, and last is accepted only on beat 34. Ownership is released by the fixed accepted beat count, never by trusting an early unvalidated last.

The result reports the original job identity, a verified decision, and an error class. A cryptographically invalid but well-formed signature is different from a framing, transport, or audit failure.

Message-dependent work

Verification starts each chain at the signature’s message digit and performs only the remaining real transitions to endpoint 15. It emits:

  • 16 mask jobs;
  • 45 through 990 chain jobs, depending on the digest digits; and
  • 34 endpoint-hash compression jobs.

The complete task count is therefore 95 through 1,040 SHA-256 compression operations. A skipped chain transition is a bypass, not a fake lane request.

Expected-tag transport

One cluster contains four verifier contexts and one exact-64-cycle compression lane. A speculative launch register accepts a context request only when the unchanged payload is actually launched. The transport writes its full tag into a 64-entry expected-return memory and advances across both tokens and bubbles.

On return, the transport checks timing, exact tag equality, task format, and physical ownership before routing the digest. This catches loss, extras, mistiming, malformed tags, wrong-context returns, and even a perfect swap of two otherwise valid in-flight tags.

Fail-closed top

Three four-context clusters sit behind a global top. A local integrity failure latches global poison. The top stops clean admission, broadcasts a registered peer abort, waits for contained in-flight effects, and drains identified error results. Result selection depends on registered validity rather than payload data, avoiding a fault-to-abort-to-fault combinational loop.

Current evidence

The full three-lane verifier has Rust/RHDL source simulation and modular descriptor evidence. It does not yet have linked generated-RTL simulation, Vivado synthesis, routed timing, resource, throughput, or card evidence. The evidence matrix preserves that lower boundary even though the signer has been promoted further.

Hash engines

SHA-256 performance lane

One CompressionLane contains a 64-stage round pipeline. Each accepted token carries:

  • eight working words;
  • a sixteen-word rolling message-schedule window;
  • the original chaining value for feed-forward;
  • a 32-bit opaque task tag; and
  • a valid bit.

The original chaining value is aligned in synchronous memory while the round state moves through the pipeline. A valid result appears after exactly 64 cycles. Reset clears validity and due ownership; wide datapath registers are intentionally resetless where validity makes their contents unobservable.

ThreeLaneCompressionFarm is a standalone generation and equivalence target: it elaborates three independent lane instances from one repeated RHDL prototype and can exercise all three in parallel. It is not instantiated by the production signer.

The production signer instead has three autonomous four-context clusters. Each cluster owns one complete compression lane shared by its four contexts, for three independent lane instances in the authored hierarchy. A single textual lane-module definition does not establish mapped hardware. Only synthesis can report the physical resource implementation.

Legacy Keccak compatibility engine

The legacy profile uses Keccak-256 with a 136-byte rate and 0x01 domain byte. The area-oriented IterativeKeccak stores one 1,600-bit state and applies one of 24 rounds per cycle. Complete combinational round and permutation exports exist as correctness or lowering artifacts, not as the selected high-throughput architecture.

SHA3-256 uses a different domain encoding and produces unrelated digests. A refactor must never replace legacy Keccak with SHA3 under the same profile name.

DSP interpretation

Source annotations and arithmetic structure may encourage DSP inference, but a DSP count is a synthesis result. Generated Verilog simulation cannot establish whether Vivado maps additions, schedule arithmetic, or other operations into DSP48E2 blocks.

Streams and packed interfaces

Signer input

The production signer accepts one job through a ready/valid handshake. The payload contains a profile-specific private seed, the already-hashed message, and an opaque job identifier. An offer remains stable until accepted.

Profile selection is a build/type boundary. There is no runtime profile mux in the SHA-256 production top.

Signer output

One fused result is 2,208 bytes:

FieldBytes
WOTS signature2,144
Public seed32
Public-key endpoint hash32
Total2,208

At 64 bytes per transfer this is 35 beats. The last beat has only the remaining bytes marked valid by its keep mask. The job and cluster identity remain fixed for the entire frame; frames never interleave.

Verifier input

One verifier frame is also 35 beats but has a different payload:

FieldBytes
WOTS signature2,144
Public seed32
Expected public-key hash32
Message digest32
Total2,240

Every verifier byte lane is valid. last is canonical only on beat 34.

Backpressure

Ready/valid transfer occurs only when both signals are asserted. A producer holds valid data stable while ready is low. The global signer output is a registered elastic slot, so output backpressure must not mutate data, identity, keep, or last.

Packed Verilog ports

RHDL flattens typed Rust structures into packed Verilog vectors. The RTL generator derives bit ranges from Digital metadata and records widths in the manifest; testbenches must not duplicate handwritten offsets. The generated signer clock/reset is a two-bit packed port whose bit zero is clock and bit one is active-high synchronous reset.

RHDL and generated Verilog

Cryptographic datapaths are authored in Rust against pinned RHDL commit c99d5cc53269a247bbc675d0fbd766991d409f56. Generated Verilog is a deterministic artifact, not the place to implement or optimize the algorithm.

Why the production bundle is modular

Lowering a complete 64-stage SHA-256 lane and the full signer graph in one process requires a large host-memory peak. The production gate instead:

  1. lowers the exact full compression lane;
  2. lets that process exit and release its address space;
  3. lowers a typed signer skeleton with one unresolved lane prototype;
  4. checks the reachable module graph and cardinality;
  5. links the lane definition and skeleton without editing either; and
  6. asks an external parser and simulator to elaborate the complete bundle.

The vendored RHDL patch adds a narrow external-module path and a repeated synchronous hierarchy primitive. It does not weaken the checked public HDL entry point, and it contains no cryptographic algorithm rewrite.

Evidence consequences

  • A descriptor or rendered module is source-structure evidence.
  • Parser acceptance is generated-source elaboration evidence.
  • A self-checking Verilator trace is finite generated-RTL equivalence evidence.
  • None of those reports mapped LUTs, registers, BRAM, URAM, DSPs, timing, route, or a card measurement.

The generator manifest binds source identity, profile, target, widths, file lengths, checksums, and validation boundary. A production evidence bundle also binds lowering logs, testbench, simulator logs, and the exact PASS marker.

Source map

Start in the owning Rust module, then follow tests and evidence outward.

AreaOwning sourcePrimary tests or records
Profile-safe wire typescrates/hashsigs-types/src/lib.rsReference and compile-time profile tests
Software sign/verify oraclecrates/hashsigs-reference/src/lib.rsUpstream compatibility tests
Legacy Keccakcrates/keccak-rhdl/src/tests/compatibility.rs
SHA-256 primitivescrates/sha256-rhdl/src/lib.rsCrate unit tests
64-stage lane and farmcrates/sha256-rhdl/src/lane.rs, farm.rsGenerated-RTL lane/farm evidence
WOTS block constructioncrates/wots-rhdl/src/blocks.rstag_and_blocks.rs
Signer context task graphcrates/wots-rhdl/src/engine.rsengine.rs, task_audit.rs
Four-context signer clustercrates/wots-rhdl/src/cluster.rscluster.rs
Three-cluster signer topcrates/wots-rhdl/src/top.rstop.rs, ignored top_full.rs
Verifier contextcrates/wots-rhdl/src/verify/sha.rsverify_sha.rs
Verifier expected-tag transportcrates/wots-rhdl/src/verify/transport.rsverify_transport.rs
Verifier cluster and topverify/cluster.rs, verify/top.rsverify_cluster.rs, verify_top.rs
RTL registry and gatescrates/rhdl-gen/src/CLI integration tests and evidence records
U280 OOC flowfpga/u280/Staged manifest plus Vivado reports

The Rust API exposes item-level contracts and source pages. Evidence records link to their producing source document; the guide summarizes but does not replace those records.

Evidence

The public evidence matrix is generated from docs/evidence/manifest.json. It is the canonical index of measured claims; the detailed Markdown records remain the narrative audit trail.

Each manifest record keeps these facts together:

  • source commit and dirty state;
  • cryptographic profile and topology;
  • evidence tier and producing command;
  • tool versions and artifact checksums where available;
  • measurements with units and context;
  • claims the record supports;
  • claims it explicitly does not support; and
  • the next gate required for promotion.

The matrix includes pending higher tiers so absence is visible. A pending U280 row is not weaker hardware evidence—it is no hardware evidence yet.

Read the evidence ladder before converting cycles to a rate.

Evidence ladder

Current completion boundary: generated RTL is the highest passed signer-performance tier. The U280 250 MHz and 300 MHz synthesis and route records, plus programmed-card execution, are pending. Until those exact artifact chains pass, do not describe the project as synthesized, routed, timed at either target clock, card-validated, or hardware-complete.

TierWhat it can establishWhat remains outside the tier
0. ModelDependency arithmetic, bounds, or a software oracleRHDL behavior and all implementation claims
1. Source simulationRust/RHDL behavior and modeled cycle eventsEmitted RTL, mapped resources, timing, route, hardware
2. Generated RTLLowering equivalence for an executed traceFormal proof, synthesis, clock, mapping, route, card
3. U280 synthesisMapping and estimated timing for an exact top and constraintPlacement, route, shell, physical clock, card rate
4. U280 routeResource and timing of a completely routed exact designShell/card behavior unless included and executed
5. Card executionValidated runtime behavior and throughput for the tested setupUntested workloads, clocks, shells, or revisions

Promotion moves one exact source and artifact chain upward. It cannot combine a cycle interval from one commit with timing from another, or a routed core from one top with a shell from another.

Negative results

A failed synthesis, placement, or route attempt remains useful when it names the exact source, tool, constraint, failure, and reports. Retaining it prevents future readers from treating “Vivado exited” as “timing closed.”

Dirty source

Dirty-source evidence is permitted only when every differing source file and checksum is recorded. A clean source commit is preferred for promotion and deployment. The manifest displays dirty state rather than hiding it.

Four-state and formal boundaries

Verilator’s ordinary two-state simulation does not prove unknown propagation. A deterministic testbench is not a formal proof. These limitations remain nonclaims even when every expected output in that trace matches.

Read throughput correctly

At 250 MHz, 500,000 results per second permits 500 cycles per result:

250,000,000 cycles/s ÷ 500,000 results/s = 500 cycles/result

At 300 MHz the same result-rate target permits 600 cycles per result. This does not make 300 MHz easier to route; it only changes the cycle budget after that clock has been justified.

Current generated-RTL interval

The sustained signer trace measured one aggregate interval spanning 48 steady completions in 23,121 cycles:

23,121 ÷ 48 = 481.6875 cycles/result

Normalizing that interval at 250 MHz gives 519,008.693 results/s. This is a useful architecture result because it is below the 500-cycle budget. It remains a normalized generated-RTL rate, not a measured U280 rate, until the exact RTL meets 250 MHz through the required hardware gates.

Service interval versus latency

One signature requires 1,258 compression blocks. Three filled lanes have a theoretical service capacity of three blocks per cycle. Individual job latency is much longer because dependencies, 64-stage lane latency, context scheduling, and output framing remain. Saturated completion interval—not first-job latency—is the relevant throughput metric.

Output traffic

The 2,208-byte fused result produces 1.104 GB/s at 500,000 results/s before shell protocol overhead. A core timing result does not prove the shell or memory system can sustain that traffic.

Contributor workflow

Work from the smallest independently checkable boundary outward:

  1. software oracle or arithmetic property;
  2. leaf RHDL kernel;
  3. stateful component;
  4. cluster;
  5. production top source simulation;
  6. generated-RTL parser and self-checking simulation;
  7. isolated synthesis;
  8. placement and route; and
  9. shell/card execution.

Stop when the evidence required by the change is satisfied. A documentation or software-type change does not authorize an expensive implementation run, while a timing claim cannot stop at source simulation.

The full contribution policy is rendered under Project → Contributing.

Test from leaf to top

Start focused

Run the owning crate and exact test target before the workspace:

cargo test -p hashsigs-types --locked -j1
cargo test -p hashsigs-reference --locked -j1
cargo test -p keccak-rhdl --locked -j1
cargo test -p sha256-rhdl --locked -j1
cargo test -p wots-rhdl --locked -j1

For WOTS changes, select the narrow integration test that owns the boundary: digits and blocks, task audit, context engine, transport, cluster, signer top, or verifier top.

Independent expectations

Expected hashes and signatures must come from an independent software oracle or pinned vector, not from a second call into the hardware logic under test. Control tests should use asymmetric tags and payloads so swaps and truncation do not accidentally pass.

Protocol cases

Exercise at least:

  • reset while work is live and post-reset quiescence;
  • valid held while ready is low;
  • bubbles and adjacent tokens;
  • full-width tag preservation;
  • saturation and a rejected extra offer;
  • malformed keep, last, identity, or generation;
  • stale, duplicate, missing, mistimed, and misrouted returns;
  • held result data under output backpressure; and
  • exact single credit release.

Expensive tests

Production full-lane source simulation and modular descriptor generation are ignored by default. Their evidence pages specify one-job concurrency, memory strategy, expected marker, and retained artifacts. Do not infer a pass because an ignored test was skipped.

Generate and validate RTL

rhdl-gen is the deterministic boundary between Rust/RHDL and generated Verilog. It does not synthesize or execute hardware.

Registry and quick checks

cargo run --locked -j1 -p rhdl-gen -- list
cargo run --locked -j1 -p rhdl-gen -- generate sha256-round --output generated
cargo run --locked -j1 -p rhdl-gen -- check

The registry keeps profile and top identity explicit. Generated files have adjacent manifests with source revision, dirty state, profile, target, checksum, and evidence tier.

Complete SHA lane and farm

The opt-in check --full gate renders complete SHA structures and uses Verilator for lint, elaboration, and self-checking arithmetic traces. Accepted warnings remain recorded; -Wno-fatal is not a warning-clean claim.

Production signer

The check --signer-full gate lowers the lane and unresolved signer skeleton in separate processes, validates the reachable hierarchy, links exact read-only sources, and runs a finite self-checking trace. Preserve the output only when an evidence record needs its manifests and logs.

The separate signer-throughput command consumes a previously successful finite-equivalence bundle. It revalidates that chain and measures a longer always-ready trace without re-lowering or editing RTL.

See the rhdl-gen API and generated evidence matrix for the current exact command and boundaries.

U280 evidence workflow

The U280 flow evaluates the exact generated production signer top out of context. It is not a Vitis kernel shell and cannot establish card throughput.

The separate Phase-A card path wraps the same Rust/RHDL signer in an AXI-Lite benchmark kernel. Its XO is explicitly user_managed so the host can own the register protocol through xrt::ip. Vitis links exactly one CU, and the host accepts only hashsigs_wots_sha256_benchmark_kernel:{hashsigs_wots_sha256_benchmark_kernel_1}. The exact clock/name contracts are fpga/u280/phase_a/link_250.cfg and fpga/u280/phase_a/link_300.cfg; they are not interchangeable with this raw-crypto OOC flow. Packaging, source-digest, and non-overwrite rules are in fpga/u280/README.md, while the register and one-time range contract is in fpga/u280/BENCHMARK_ABI.md.

Preserve provenance

Stage only a checksum-validated linked signer bundle whose generated-RTL gate passed. The staging manifest binds the RTL, source evidence manifests, Tcl, XDC, target part, and checksums. Use a new staging and run directory for every source or constraint variant.

The preserved 6801a66-41fe7ba3-20260715T1103PDT stage is superseded and unlaunchable because its managed XDCs contain unsupported Tcl control flow. It remains a forensic artifact only; do not mutate, execute, or promote it. A run must use a fresh schema-v2 stage with flow_variant=baseline.

bun run stage:u280 -- <preserved-generated-rtl-evidence> <new-stage-directory>

The stage must be read-only and contain exactly one linked Verilog bundle. The flow accepts only xcu280-fsvh2892-2L-e; it rejects a different part, a renamed or altered clock constraint, extra RTL, a dirty flow checkout, or a checker whose commit and tree differ from the staged flow identity.

Run sequentially

Before any remote U280 Vivado, Vitis, XRT, or card action, record explicit ownership in both coordination ledgers and use the wrapper to obtain the nonblocking lock at the effective user’s canonical passwd login home plus .cache/rhdl-fpga/u280.lock. Caller-controlled HOME never selects the lock namespace. Failure to acquire the lock immediately means stop. Do not wait for it, probe the owner, inspect the owner’s process, or start a competing flow. Ledger ownership without the lock, or the lock without both ledger entries, is insufficient.

The checked-in wrapper is the only supported launch entry point. Set its acknowledgment inline only after both ownership entries exist, and pass the approved executable by absolute path:

HASHSIGS_U280_COORDINATION_ACK=both-ledgers-recorded \
  tools/with-u280-lock.sh /absolute/path/to/approved-executable <arguments>

tools/with-u280-lock.sh delegates to a descriptor-rooted helper. The helper walks the passwd-home path with O_NOFOLLOW, validates effective-user ownership and rejects group- or other-writable lock-path objects, takes LOCK_EX|LOCK_NB on the already-open file, and reopens every path component to compare identities. Privileged Bash startup ignores BASH_ENV and imported functions; the Python helper also removes Bash/POSIX startup hooks, option injection, and exported Bash functions from the guarded child’s environment, then validates its own owner, mode, type, and link count. ELF commands are launched through their retained descriptor, while script launchers are checked against a retained inode immediately before and after spawn. The helper then remains as a supervisor that retains the locked fd while the exact absolute command runs in a foreground process group; closing inherited non-stdio descriptors inside the tool cannot release the supervisor’s lock. Termination signals are forwarded to that process group. There is no lock wait or unlocked fallback. The Vitis run action additionally rejects a bare invocation unless that inherited fd matches the canonical path’s device, inode, and /proc/self/fd target.

The approved tool must remain in the foreground and wait for its subprocesses; backgrounding, double-forking, or daemonizing a hardware job is unsupported. Launch remote flows in a dedicated systemd service with KillMode=control-group, so an abnormal supervisor termination cannot leave an untracked descendant using the card after the lock descriptor disappears.

The acknowledgment is a human assertion that both ledger entries exist; it is not cryptographic verification. The advisory lock and inherited-context check prevent accidental contention among cooperating processes. They do not defend against a malicious process already executing as the same UID, which can deliberately violate any same-user advisory protocol.

  1. Synthesize at the 4.000 ns / 250 MHz basis.
  2. Inspect mapping, DRC, and resource limits before placement.
  3. Place and route that exact variant.
  4. Repeat the 3.333 ns / 300 MHz goal in a separate run only after the first run is understood.

Do not run competing high-memory Vivado jobs on a shared host. Worker count is an explicit input and does not exceed the flow’s cap.

The exact Vivado 2023.2 commands, empty-directory rule, console capture, and archive inventory are published in the privacy-sanitized flow narrative. Run synthesis and full implementation in different directories; never resume one phase by adding files to the other phase’s result.

Validate outside Vivado

Vivado process success is an input to the evidence checker, not the verdict. After a run has written vivado.console.log and vivado.exit-status, validate the stage and result together:

bun run tools/check-u280-reports.ts -- \
  <stage-directory> <result-directory> synth <synthesis-evidence.json>

bun run tools/check-u280-reports.ts -- \
  <stage-directory> <result-directory> full <route-evidence.json>

The checker creates its read-only JSON manifest only after every applicable gate passes. It streams checkpoints into the result checksum inventory rather than loading large DCP files into memory.

The manifest distinguishes a statically declared managed XDC, a Vivado read_xdc call that applied it, and a post-synthesis gate that observed the exact clock, top-level port inventory, valid/invalid constraint export, and I/O-delay coverage. None of these states is card or hardware evidence.

Passing gates

For the crypto hierarchy, the project limits are:

  • no more than 200,000 LUTs;
  • no more than 300,000 registers; and
  • no more than 4,000 DSPs; this is the absolute project ceiling.

A routed timing pass requires a completely routed design, no route errors, setup WNS at least zero with TNS zero, hold WHS at least zero with THS zero, pulse-width WPWS at least zero with TPWS zero, and zero findings in all twelve verbose check_timing categories. The report must repeat the staged core_clk period and exact design/device identity. The checker also requires post_synth_applied_constraints.xdc and the deterministic post_synth_constraints_observed.rpt; unsupported XDC commands, any invalid constraint, an unexpected port, or a missing/partial I/O delay fails. Enabled Error/Fatal DRC violations, unresolved black boxes, missing reports, report-command errors, resource overruns, or a nonzero Vivado exit all fail the gate. Process exit zero alone is never a pass.

Publish the right claim

  • Synthesis reports mapping and estimated timing.
  • A completely routed OOC result reports the exact crypto top without a shell.
  • A shell route includes shell resources and timing.
  • Only validated execution on a programmed card reports hardware throughput.

Archive reports and checkpoints with the staged manifest; never combine a simulator interval with an unrelated routed revision.

Build this documentation

The publication is a deterministic static assembly:

docs/book/                    mdBook guide source
crate-level Rust comments     themed API + standard Rustdoc source
docs/evidence/manifest.json   evidence index source
docs/site/                    404, policy metadata, headers, redirects
            │
            └── bun run docs:build ──> site/

The build requires mdBook 0.5.4 and checks that exact version. It generates the guide at /, the project API portal and themed Rustdoc at /api/, a separate standard Rustdoc tree at /rustdoc/ with a native workspace crate index, evidence pages at /evidence/, a sitemap, and the top-level static policy files.

Local validation

bun install --frozen-lockfile
bun run docs:test
bun run docs:build:no-api
bun run docs:check

The no-API build is the lightweight content loop. A publication candidate uses the single sequential gate bun run docs:release; it runs a fresh Rustdoc build and then the release checker, stopping if either step fails. The build emits site/build-metadata.json with the full source commit, full source tree, dirty state, and API mode. Fresh Rustdoc also carries an independent file-count and aggregate tree digests at site/api/build-metadata.json and site/rustdoc/build-metadata.json. Release mode recomputes both inventories, requires the same crate roots in both trees, and requires all metadata files to name the same clean commit and tree. Release mode requires a clean current checkout, exact commit/tree agreement, dirty=false, and api_mode=fresh-rustdoc. Because site/, the Cargo documentation target, and installed Bun packages are ignored, generated output cannot make this provenance check circular.

docs:check rejects missing expected routes or fragments, broken local links, a soft-404 meta refresh, unrendered Mermaid, leaked coordination/local paths, malformed evidence, inaccessible producing narratives, and Markdown link syntax accidentally trapped inside raw HTML. Every evidence record links to a generated privacy-sanitized projection of its producing narrative. That projection keeps the repository-relative source path and cryptographic subject commit separately from the narrative checkout commit and dirty state. Its digest identifies the pre-sanitization narrative bytes read by that documentation build—not necessarily the narrative at the subject commit—and every local-path or private-host substitution is visibly labeled.

The checker also audits every iframe title, the no-JavaScript table-of-contents document title, the same-origin framing headers, and high-risk machine-local identifiers in rendered Rust source pages.

Cloudflare Pages

wrangler.jsonc uses the shipped Wrangler v4 schema and identifies ./site as pages_build_output_dir. The project is static and has no bindings or Functions. _redirects contains only named legacy routes and no catch-all. Cloudflare Pages therefore uses the real top-level 404.html for unknown paths.

The repository does not contain account IDs, API tokens, or DNS credentials. Deployment and custom-domain attachment are separate authorized operations.

Release deployment transaction

Build and validate a release from the exact clean commit first:

bun run docs:release
git rev-parse HEAD
bun run docs:deploy --commit <the-full-40-character-HEAD-above>

docs:deploy does not build or repair the site. Before opening any credential file, it requires a completely clean checkout, an exact --commit match, fresh Rustdoc metadata bound to that commit and tree, canonical evidence bytes, a symlink-free site/, a passing release checker, and the pinned local Wrangler. It invokes bunx --no-install wrangler as an argument vector, never through a shell.

At runtime only, the tool opens the fixed KEYS file in the deployment user’s home directory without following symlinks. The file must be owned by the invoking user, have mode 0600, have one hard link, and contain exactly one assignment for each required entry:

SAHASTA_PERSONAL_CLOUDFLARE_ACCOUNT_ID=<account-id>
SAHASTA_PERSONAL_CLOUDFLARE_API_TOKEN=<API-token>

The file is parsed as data and is never sourced. Inherited Cloudflare, CF_*, and Wrangler environment variables are removed before the local Wrangler process receives only the verified account and token. Neither value is printed.

The transaction verifies the token through the account-scoped endpoint, idempotently inspects or creates project hashsigsdocs with production branch main, deploys the explicit clean commit, and independently checks that the successful canonical deployment has that commit. It then attaches and polls hashsigsdocs.sahastasai.com through the Pages custom-domain API.

The immutable deployment URL is checked before domain attachment. The tool then checks hashsigsdocs.pages.dev and the custom hostname. Each smoke verifies metadata and evidence byte equality, core routes and named redirects, the real 404 response, security headers, the no-JavaScript table of contents, immutable Rustdoc caching, and conditional ETag behavior.

Rollback is deliberately narrow. A content mismatch can restore the previously successful production deployment, but only after confirming that the failed deployment is still canonical. API failures, DNS or network reachability, domain activation failures, and concurrent deployments never trigger an automatic rollback. Those failures stop with the current remote state intact for an operator to inspect.

Reference

Use the API portal for a project-oriented crate entry point, or open the standard Rustdoc for Cargo/Rustdoc’s native crate index, search, source pages, and item-level documentation. This section keeps the cross-crate values and vocabulary needed to read more than one module.

The guide, API portal, and standard Rustdoc deliberately keep separate search indexes. Rustdoc remains the authority for public Rust signatures.

Parameters and byte sizes

NameValueMeaning
HASH_BYTES32Hash output and WOTS security parameter n
WINTERNITZ_W16Number of positions in one chain
CHAIN_STEPS15Maximum transitions per chain
MESSAGE_DIGITS64Base-16 digits in a 256-bit message
CHECKSUM_DIGITS3Base-16 checksum digits
CHAIN_COUNT67Total signature chains
MASK_COUNT16Reachable upstream mask indices 0 through 15
SIGNATURE_BYTES2,14467 × 32-byte chain values
PUBLIC_KEY_BYTES64Public seed and endpoint hash
FUSED_OUTPUT_BYTES2,208Signature plus public key
Signer output beats35512-bit transfers, partial final keep
Verifier input bytes2,240Signature, public key, and message digest
Verifier input beats35512-bit transfers, all lanes valid
SHA signer blocks1,258Fixed fused private-seed work
Active clusters3Signer and verifier
Contexts per cluster4One lane shared locally
Active contexts12Three clusters × four contexts
SHA lane latency64 cyclesExact tag-preserving compression latency

These constants describe authored protocol and source geometry. LUTs, registers, DSPs, RAM, frequency, and physical latency come from higher evidence tiers.

Terminology

  • Chain digit: One hexadecimal message or checksum digit selecting a WOTS signature position.
  • Compression block: One 512-bit SHA-256 block processed through all 64 rounds and feed-forward.
  • Context: Retained state for one live signer or verifier job sharing a hash lane.
  • Evidence tier: The execution boundary that directly supports a claim: model, source, generated RTL, synthesis, route, or card.
  • Fused output: The 2,208-byte signature and public key derived from the same one-time private seed.
  • Generation: A context-reuse epoch encoded into tags so a stale return cannot be accepted as new work.
  • Lane: One exact-64-cycle SHA-256 compression pipeline with opaque tag transport.
  • Legacy Keccak: Keccak-256 with the older 0x01 domain byte used by pinned HashSigsRS. It is not SHA3-256.
  • Nonclaim: A boundary the evidence explicitly does not establish.
  • One-time key: A WOTS private key that may sign at most one message.
  • Profile: The authenticated hash choice and byte domain. The two profiles have distinct Rust types but equal serialized lengths.
  • Topology 3×4: Three autonomous lane-local clusters with four contexts each; the active signer and verifier structure.

Project

Project policy is part of the developer interface. These pages are rendered and link-checked rather than exposed as missing raw Markdown routes.

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.

Security policy

Project status

HashSigs RHDL is research hardware and has not received an independent cryptographic or side-channel audit. It implements the custom WOTS+ construction used by a pinned HashSigsRS revision. It is not XMSS, SLH-DSA, FIPS 205, or a many-time signature system.

Do not use this repository as the sole protection for production secrets until its protocol, generated RTL, integration shell, physical implementation, key lifecycle, and side-channel behavior have been reviewed for that deployment.

Critical operating requirements

  • Never reuse a WOTS private key. One private key signs at most one message. Reuse can reveal enough chain material to enable a forgery.
  • Bind the profile identifier outside serialized keys and signatures. LEGACY_KECCAK and HASHSIGS_SHA256_GENERIC_V1 have the same lengths but are cryptographically incompatible.
  • Supply a collision-resistant, domain-separated 32-byte application digest. WOTS does not hash an arbitrary-length application message for the caller.
  • Treat reset and zeroization as defined hardware boundaries. Reset invalidates ownership; it does not imply that every unused data register or memory bit was physically scrubbed.
  • The current hardware verifier supports the SHA-256 profile only. Legacy Keccak verification is available through the software reference path, not the active RHDL verifier top.

Supported versions

Security fixes are applied to the current main branch. No older release line is currently maintained.

Reporting a vulnerability

The canonical contact and policy location is https://hashsigsdocs.sahastasai.com/project/security. It will name a verified private reporting channel when one is available. Until that channel is published, do not send sensitive vulnerability details through a public issue or pull request.

An operational private channel is a prerequisite for inviting confidential reports, not something this document guesses. When available, a report should include the affected commit and profile, whether the problem is in software, RHDL source, generated RTL, FPGA integration, or documentation, and a minimal reproduction when safe. Do not include real private keys, credentials, or unrelated host data.

Evidence corrections

An incorrect performance or hardware claim can be reported through the same private channel when disclosure could expose a security weakness. Ordinary documentation corrections may use a pull request. Evidence is downgraded until the exact producing artifact has been revalidated.

Changelog

All notable project and documentation changes are recorded here. The project does not yet publish a stable API release.

Unreleased

Added

  • A hybrid developer site with an mdBook guide, fresh workspace Rustdoc under /api/, and manifest-generated evidence pages under /evidence/.
  • A canonical evidence schema that keeps claims and nonclaims attached to their producing source revision and tier.
  • Real 404, robots, sitemap, security-contact, header, and redirect artifacts for static Cloudflare Pages hosting.
  • Contributor and security policies.

Evidence status

  • The production SHA-256 signer has source-simulation, finite generated-RTL equivalence, and sustained generated-RTL cycle evidence.
  • The SHA-256 verifier top has source/RHDL simulation evidence only.
  • U280 synthesis, routed timing, and card execution remain separate gates and are not implied by the documentation build.

0.1.0 — development baseline

  • Added type-separated legacy Keccak and SHA-256 profiles.
  • Matched the five pinned HashSigsRS legacy vectors.
  • Added Rust/RHDL SHA-256 lanes, the active three-cluster-by-four-context signer and verifier tops, deterministic RTL generation, and evidence-producing simulation gates.

Architecture decisions

Architecture decisions record stable boundaries and the alternatives rejected at the time. They are not evidence that an implementation met timing or ran on hardware.

ADR 0001: Separate compatibility and performance profiles

ADR 0001: Separate compatibility and performance hash profiles

  • Status: accepted
  • Date: 2026-07-14

Decision

The workspace exposes two incompatible, compile-time-selected profiles. LEGACY_KECCAK uses legacy Keccak-256 padding and must reproduce the pinned HashSigsRS vectors byte for byte. HASHSIGS_SHA256_GENERIC_V1 instantiates the same upstream generic WOTS construction with SHA-256 and is the primary throughput target.

Profile identity is part of key, signature, vector, generated-RTL, and evidence metadata. No API or hardware top may silently interpret one profile as the other.

Rationale

The user explicitly permits a secure hash choice for the performance target. An unrolled Keccak farm needs at least 57 round cells and has an unproven path under the 200,000-LUT cap. Three fully pipelined SHA-256 lanes have adequate theoretical throughput at 250 MHz and allow arithmetic to use U280 DSP48E2 resources. These are architecture projections until Vivado evidence exists.

Security boundary

Both profiles remain the custom upstream WOTS+ construction. They are not XMSS, SLH-DSA, or FIPS 205, and each private key is strictly one-time.

License

The HashSigs RHDL workspace is distributed under the GNU Affero General Public License, version 3 or later. It is provided without warranty.

                GNU AFFERO GENERAL PUBLIC LICENSE
                   Version 3, 19 November 2007

Copyright (C) 2007 Free Software Foundation, Inc. https://fsf.org/ Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

                        Preamble

The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software.

The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program–to make sure it remains free software for all its users.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.

Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software.

A secondary benefit of defending all users’ freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public.

The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version.

An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license.

The precise terms and conditions for copying, distribution and modification follow.

                   TERMS AND CONDITIONS
  1. Definitions.

“This License” refers to version 3 of the GNU Affero General Public License.

“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.

“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.

To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.

A “covered work” means either the unmodified Program or a work based on the Program.

To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.

To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.

An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.

  1. Source Code.

The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.

A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.

The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.

The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work’s System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.

The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.

The Corresponding Source for a work in source code form is that same work.

  1. Basic Permissions.

All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.

You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.

Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.

  1. Protecting Users’ Legal Rights From Anti-Circumvention Law.

No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.

When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work’s users, your or third parties’ legal rights to forbid circumvention of technological measures.

  1. Conveying Verbatim Copies.

You may convey verbatim copies of the Program’s source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.

You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.

  1. Conveying Modified Source Versions.

You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:

a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.

b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7.  This requirement modifies the requirement in section 4 to
"keep intact all notices".

c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy.  This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged.  This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.

d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.

A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation’s users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.

  1. Conveying Non-Source Forms.

You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:

a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.

b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.

c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source.  This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.

d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge.  You need not require recipients to copy the
Corresponding Source along with the object code.  If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source.  Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.

e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.

A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.

A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.

“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.

If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).

The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.

Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.

  1. Additional Terms.

“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.

When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.

Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:

a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or

b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or

c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or

d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or

e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or

f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.

All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.

If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.

Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.

  1. Termination.

You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).

However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.

  1. Acceptance Not Required for Having Copies.

You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.

  1. Automatic Licensing of Downstream Recipients.

Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.

An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party’s predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.

You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.

  1. Patents.

A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor’s “contributor version”.

A contributor’s “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.

Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor’s essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.

In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.

If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient’s use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.

If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.

A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.

Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.

  1. No Surrender of Others’ Freedom.

If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.

  1. Remote Network Interaction; Use with the GNU General Public License.

Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph.

Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License.

  1. Revised Versions of this License.

The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation.

If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Program.

Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.

  1. Disclaimer of Warranty.

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  1. Limitation of Liability.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

  1. Interpretation of Sections 15 and 16.

If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.

                 END OF TERMS AND CONDITIONS

        How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.

<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year>  <name of author>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a “Source” link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements.

You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see https://www.gnu.org/licenses/.

Notices

HashSigs RHDL derives protocol behavior and test expectations from hashsigs-rs, copyright Quip Network contributors, licensed AGPL-3.0-or-later.

RHDL is copyright its contributors and licensed under the MIT License. The workspace pins both upstream revisions in Cargo.toml and records them in the evidence manifest.

Known gaps

The following boundaries remain open until a directly supporting evidence record is added:

Current U280 status

The generated evidence matrix is canonical. Its current hardware rows remain pending:

GateStatusClaim still unavailable
250 MHz / 4.000 ns synthesisPendingExact U280 mapping, resources, and estimated timing
250 MHz / 4.000 ns routePendingCompletely routed timing closure at the normalization clock
300 MHz / 3.333 ns synthesisPendingExact U280 mapping and estimated timing at the clock goal
300 MHz / 3.333 ns routePendingCompletely routed timing closure at the clock goal
Programmed-card executionPendingCard correctness, achieved clock, and measured throughput

The preserved 6801a66-41fe7ba3-20260715T1103PDT stage is unlaunchable and forensic only; it cannot fill any row. A future attempt must begin with a fresh schema-v2 baseline stage as described by the U280 evidence workflow.

Other open boundaries

  • The SHA-256 verifier lacks linked generated-RTL equivalence evidence.
  • U280 synthesis and routed timing must remain attached to the exact staged RTL and constraint that produced them.
  • A routed OOC crypto top is not a Vitis shell or card result.
  • Card execution must validate every returned signature before reporting measured throughput.
  • Arbitrary output backpressure is not covered by the current always-ready sustained signer benchmark.
  • Four-state unknown propagation and formal protocol proofs are not supplied by the two-state Verilator traces.
  • Physical side-channel behavior and complete stale-state scrubbing have not been audited.
  • No active legacy Keccak hardware verifier is implemented.
  • External source and contribution links are omitted until a public repository is verified, and no private vulnerability-reporting channel is currently advertised.

An open gap is not a failed claim. It is a boundary the project refuses to hide.