Privacy-sanitized source narrative
Production signer generated-Verilog equivalence
This page publishes the producing narrative as escaped plaintext. It preserves repository provenance while withholding machine-local paths and private build-host labels.
Sanitization disclosure
This is a public projection, not a byte-identical copy when substitutions are listed. The pre-sanitization digest identifies the narrative bytes read from the documentation checkout; the cryptographic subject commit is recorded separately.
- 1 environment home-directory path occurrence(s) replaced with
[local-home-path]. - 1 home-directory path occurrence(s) replaced with
[local-home-path].
Provenance
The digest identifies the narrative bytes read by this documentation build before substitutions. It does not assert that those narrative bytes existed at the cryptographic subject/source commit.
Producing narrative
# WOTS production signer generated-Verilog equivalence — 2026-07-15
## Evidence tier and boundary
Generated-Verilog deterministic simulation. The externally composed production
signer bundle matched twelve independent `Sha256GenericWots` oracle results and
passed the finite reset, saturation, framing, backpressure, result-credit, and
quiescence checks described below.
This is lowering-equivalence evidence for one deterministic finite trace. It is
not a formal proof, a sustained-throughput measurement, synthesis, timing,
placement, routing, LUT/register/BRAM/DSP utilization, side-channel evidence,
or U280 execution evidence. In particular, the source-model throughput remains
a model until the later Vivado and card gates pass.
## Reproduction
```console
cargo run --release --locked -j1 -p rhdl-gen -- check --signer-full \
--temp-root "[local-home-path]" --keep
```
The command exited with status 0 after 1,003.21 seconds. The preserved workspace
is
`[local-home-path]`.
The path is host-local; the checksums below identify the exact immutable files.
The driver lowered the full RHDL SHA-256 lane in one child process, waited for
that process to exit, then lowered the unresolved RHDL signer skeleton in a
second process. This prevents the two multi-gigabyte RHDL graphs from occupying
one address space at the same time. The driver then validated and linked the
two read-only sources before invoking Verilator. No generated Verilog was
hand-edited.
## Provenance
- Source commit: `dbd18593527673be2a93d7067ee03667892c582a`
- Source dirty: `false`
- Profile: `HASHSIGS_SHA256_GENERIC_V1`
- RHDL revision: `c99d5cc53269a247bbc675d0fbd766991d409f56`
- HashSigsRS revision: `2d315dd4168804b7cbc51c51a1bf7ca27bf74140`
- Verilator: `5.048 2026-04-26 rev v5.048`
- Generator version: `0.1.0`
- Lint and native-build concurrency: one thread
The bundle manifest derives, rather than hand-codes, packed interface widths:
signer clock/reset 2 bits, input 547 bits, output 677 bits; lane clock/reset 2
bits, input 801 bits, output 289 bits.
## Immutable artifacts
| Artifact | Size / lines | SHA-256 |
|---|---:|---|
| Full lane RTL | 1,001,581 bytes / 28,223 | `615a4e89519a5aadec2bc17a6b59833fd4bf51dc123f44d378e6f0fb7866610d` |
| Signer skeleton RTL | 2,009,645 bytes / 61,538 | `caa554e1b0eed1431038a7c816b7dc9a2b6e9a55377a1caa27d69ab0a02b0087` |
| Linked signer bundle | 3,011,226 bytes / 89,761 | `41fe7ba31ec811b6a69ebcb9d2e76af512b0b49af99b7c83389d5cf97b978e68` |
| Bundle manifest | 2,232 bytes | `3cebfb959a50f6405952f8005f185dc7077c0bdfc1f251b1ba39661fe150c054` |
| Self-checking testbench | 295,695 bytes / 913 | `f7fc208510018b428440025dd1f84c3e18cbf33016d4d24c8ab8cf7e7b0d4733` |
| Lane lowering log | 501 bytes | `0cc9c8fb9a4ab44effa813cf36bacf2aa8001d5a10e215e1fb6b9a9def5d4379` |
| Skeleton lowering log | 511 bytes | `8e00e82c62276d6a2a294783ddc3d8771bca1bd95366ced5558003ffa9e967ba` |
| Verilator lint log | 2,920,748 bytes | `3d68bfcbbccf7eff90b2a3b66019ec9b18a71f884ba39251fc81fdf691a67c56` |
| Verilator build log | 29,100 bytes | `5fa603f189402d380449822f4d432eb62b484b1098a453906b0df547b8c0ee77` |
| Verilator simulation log | 597 bytes | `2bb980e2e1e75a5921984ed14036b5e7fb65dc60e54b9be4cc16f9d2667e18fa` |
| Final evidence manifest | 1,830 bytes | `5fb20020be4957b0d2fa83d77a42529e59bd2cc2da05a36cc9bd308a8a90b467` |
The final evidence manifest independently binds the source commit, profile,
PASS marker, bundle manifest, testbench, both lowering logs, and all three
Verilator logs. A root-side recomputation matched every recorded digest and
byte length; all files in the table were mode `0444` after completion.
Read-only permissions plus checksums detect ordinary mutation; they are not
filesystem-enforced immutability. The manifest does not hash the generator
executable itself. This run mitigates stale-binary risk through the observed
locked Cargo build and the parent/child source-commit checks, but a future
artifact format should bind an executable or embedded build-commit digest too.
## Structural result
The linked bundle contains 233 Verilog module definitions. Graph traversal from
`wots_sha256_signer_top` found one reachable cluster-instance parent,
`wots_sha256_signer_top_clusters`, containing exactly `c0`, `c1`, and `c2` and
no extra or duplicate prototype sites. The shared cluster prototype reaches
one canonical unresolved lane site. The skeleton contains no lane definition;
the final bundle contains exactly one `sha256_compression_lane` definition.
Unreachable lookalike modules cannot satisfy this gate.
The checker reasons over module-definition reachability rather than a complete
elaborated-instance graph. An independent artifact audit therefore also traced
the effective hierarchy and confirmed exactly three cluster-prototype paths
and three full-lane paths. It confirmed that the bundle bytes are exactly the
lane source followed by the skeleton source, with no third edited fragment.
This structural result proves the intended generated-source composition. It
does not prove how Vivado will map the three instances physically.
## Lint and simulation results
Verilator lint/elaboration passed in 109.461 seconds. The accepted warning
inventory is 8,397 total:
- 5,500 `UNUSEDSIGNAL`;
- 2,858 `UNUSEDPARAM`;
- 26 `CASEINCOMPLETE`;
- 6 `CMPCONST`;
- 6 `UNOPTFLAT`; and
- 1 `DECLFILENAME`.
The `-Wno-fatal` result is accepted elaboration, not a warning-clean claim.
The six `UNOPTFLAT` reports name RHDL packed feedback envelopes. Passing the
finite simulation does not dispose of them; Vivado synthesis, timing, and
combinational-loop DRC are mandatory before any FPGA claim.
The current gate records the full warning inventory but does not enforce a
code-specific warning allowlist, so a new warning category would be preserved
in evidence rather than rejected automatically.
The timed native build passed in 539.708 seconds. Simulation passed in 83.939
seconds with this exact marker:
```text
WOTS_SHA256_SIGNER_RTL_EQUIVALENCE_PASS jobs=12 beats=420 reset_flush=1 saturation=12 final_hold=5 faults=0
```
The finite trace:
- accepts a sacrificial job and resets it while live;
- requires 80 cycles of post-reset silence before new work;
- fills all twelve signer contexts and rejects a thirteenth offer while full;
- distributes the twelve accepted jobs exactly four per cluster and holds the
rejected offer for eight cycles without accidental acceptance;
- compares twelve distinct fused signature/public-key frames with the
independent software oracle;
- checks exactly 35 beats per result and 420 beats total, including job and
admission-cluster identity and no interleaving within a frame;
- applies deterministic output stalls and requires ready/valid data stability;
- holds the first final beat for five cycles;
- requires exactly twelve finals and releases, with no reported faults; and
- requires exactly four releases per cluster and 160 cycles of final
quiescence.
As an independent cross-check of the embedded Rust-oracle vectors, the audit
reconstructed every signature and public key with Python `hashlib`. All twelve
2,208-byte fused results matched the testbench data.
The trace reported first acceptance at cycle 180, last delivery at cycle 6,665,
an inclusive-work span reported by the testbench as 6,486 cycles, 69 stalled
output cycles, and twelve releases. These are finite-trace observations, not a
steady-state signatures-per-second measurement.
Verilator is a two-state simulator, so this result is not a four-state
unknown-propagation proof.
## Promotion decision and next gate
The production signer is promoted from source-simulation and render-only status
to the generated-Verilog tier for this exact trace and commit. The previous
failed run is retained separately: it stopped on an overstrict structural
assertion that assumed direct top-level cluster instances, before external
lint or simulation. The repaired gate accepts intervening generated wrappers
but still requires exact graph reachability and cardinality.
The next evidence tier is an isolated U280 Vivado synthesis run, followed by
placement/routing at 4.000 ns and 3.333 ns. Those runs must preserve this exact
source/RTL provenance, inspect the six lint feedback paths, and report LUTs,
registers, BRAM/URAM, DSPs, WNS/TNS, route status, and the normalized throughput
calculation. No resource, timing, or 500,000-signatures/second claim is made by
this page.