Privacy-sanitized source narrative
Production signer source simulation
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 private build-host label occurrence(s) replaced with
[remote-build-host].
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
# Production WOTS signer RHDL source simulation — 2026-07-15
## Evidence tier and boundary
This record is a behavioral Rust/RHDL **source-simulation** gate for the actual
production specialization:
```text
Sha256SignerTop = SignerTop<64, 6>
```
It exercises all three complete 64-round SHA-256 lanes, all twelve signer
contexts, the lane-local framers, and the global three-cluster admission/data/
error merges. The cryptographic profile is `HASHSIGS_SHA256_GENERIC_V1`; it is
separate from and incompatible with `LEGACY_KECCAK`.
This command does not call `descriptor`, emit Verilog, run a Verilog simulator,
synthesize, place, route, inspect a U280, or execute on a card. Therefore it
provides no generated-RTL, resource, DSP, LUT, register, BRAM, timing, clock,
power, side-channel, sustained-throughput, [remote-build-host], or hardware evidence.
## Source identity
- Baseline commit: `2f21bd47bcbab521e3c2055fed6df2eb3fbfb03d`
- Baseline tree: `0428d51f7abcf821221881468d150c6a4d439822`
- Working tree during the measured run: dirty only for the two Rust files
listed below; this evidence file was added after the run
- Pinned RHDL revision:
`c99d5cc53269a247bbc675d0fbd766991d409f56`
- `crates/wots-rhdl/src/top.rs` SHA-256:
`9cbff18e31c13676c723c30eedfa745f9db35401defc6ffb4ecc0680d40a74ab`
- `crates/wots-rhdl/tests/top_full.rs` SHA-256:
`a81b498baec07e82c61fbd1d937e75f6e8d870a38ba42c29c5fcffc72f5ecb57`
- `crates/wots-rhdl/Cargo.toml` SHA-256 (unchanged):
`44a5350cddfd51375c9fb40b652fdca08ddd0a3db87e7dc34f2c2c48ff1a32aa`
- `Cargo.lock` SHA-256 (unchanged):
`fe58afb75398780025983d191771ddbd3e08618ff38e33dffd63180fb0dba547`
- Rust: `rustc 1.96.0 (ac68faa20 2026-05-25)`, LLVM 22.1.2
- Cargo: `cargo 1.96.0 (30a34c682 2026-05-25)`
- Host kernel: Linux `7.0.1-1-cachyos`, `x86_64`
The only production-source addition is a hidden host method that reads the
existing per-context `request_accepted` outputs from typed RHDL simulation
state. It does not add a field to `SignerTopInput` or `SignerTopOutput`, is not
called by a kernel, and does not widen or otherwise change the generated
hardware interface. Its purpose is to count actual scheduler/lane handshakes
without maintaining a duplicate test scheduler.
## Measured command
The resource-intensive integration test is ignored by default and was invoked
explicitly with one Cargo build job and one test thread:
```console
time cargo test -j1 -p wots-rhdl --test top_full -- \
--ignored --nocapture --test-threads=1
```
Result:
```text
production source finite trace: admissions 178..=189 (12 cycles),
SHA issues 180..=6119 (5940 cycles, 15096 accepted),
deliveries 6224..=6674 (451 cycles), first final held 9 cycles,
total modeled cycles 6836
test result: ok. 1 passed; 0 failed
test-reported time: 138.66s
shell real: 2m18.832s
shell user: 2m16.816s
shell sys: 0m0.155s
```
GNU `time -v` was not installed. Three manual `ps` samples of the test process
at approximately 49, 90, and 133 seconds reported 9,920, 10,056, and 10,088 KiB
RSS. These sparse samples are **not** a peak-RSS measurement. The process VSZ
included the explicitly reserved 768 MiB test-thread stack; that reservation is
host test scaffolding, not resident use and not an FPGA memory claim.
## Properties exercised
The gate uses an independent `Sha256GenericWots` oracle and the canonical
`pack_fused_output` software packer. It proves all of the following within the
finite trace:
- one sacrificial job is admitted, places real requests into a full SHA lane,
and is reset while still in flight;
- the one shared top-level reset flushes all cluster/lane work, active contexts,
frame ownership, output state, errors, releases, and request pulses;
- 80 idle cycles after that reset exceed the 64-cycle SHA response latency and
contain no stale request, output beat, final, release, fault, or error;
- twelve unique deterministic private-seed/message jobs are admitted in twelve
consecutive cycles, exactly four to each cluster;
- while all twelve context credits are held, a valid thirteenth job sees no
`start_ready`, no `start_accepted`, and no ready cluster for eight cycles;
- exactly 15,096 SHA requests are accepted (`12 * 1,258`), counted from the
real per-context acceptance pulses;
- each accepted output beat matches its job's independently packed 35-beat
`signature || public_key` frame, including every data byte, `keep`, `last`,
final padding byte, and job ID;
- cluster and job identity remain fixed through each frame, all twelve jobs
appear exactly once, and frames never interleave;
- deterministic backpressure holds the complete registered output stable;
- the first registered final is deliberately held for exactly nine cycles;
- exactly twelve final deliveries and twelve local credit releases occur,
with exactly four releases per cluster;
- no top/cluster fault, error notification, or error delivery appears; and
- 160 final idle cycles exceed two SHA response latencies and remain fully
quiescent after every context and output owner is released.
## Interpretation of the finite spans
The 5,940-cycle issue span is evidence that this finite saturated twelve-job
batch completes the exact production source scheduler workload with three real
64-round lanes. It is not a measured steady-state initiation interval: the
batch begins from empty state and stops offering jobs once all twelve credits
are occupied. The separate scheduler/policy model owns steady-state throughput
claims until a sustained generated-RTL or hardware gate exists.
The 451-cycle delivery span is the intentionally serialized 512-bit global
output stream under deterministic stalls, including the held first final. It
must not be divided into clock frequency to claim signing throughput; SHA work
completed before this drain interval and local final capture can release credit
before external final delivery.
## Regression and static gates
The same final Rust source passed:
```console
cargo test -j1 -p wots-rhdl --lib top::tests -- --test-threads=1
# 3 passed, 0 failed
cargo test -j1 -p wots-rhdl --test top -- --test-threads=1
# 12 passed, 0 failed, 2 descriptor-generation tests ignored; 120.66s
cargo clippy -j1 -p wots-rhdl --all-targets -- -D warnings
RUSTDOCFLAGS='-D warnings' cargo doc -j1 -p wots-rhdl --no-deps
```
The existing `SignerTop<4, 2>` tests are fast control/composition regressions;
their four-round hash payloads are not SHA-256 or cryptographic evidence. The
production descriptor test remains ignored and its prior bounded lowering
attempt remains a retained negative result in
`wots-global-signer-top-2026-07-15.md`.
## Next evidence gates
1. Compose/lower the production hierarchy with the accepted lower-memory RHDL
strategy and record exact generated-source identity.
2. Parse/lint that hierarchy with the accepted full-stage external tool and run
self-checking generated-RTL frame equivalence.
3. Only after those local gates pass, proceed separately to U280 synthesis,
implementation, timing, resources, and sustained hardware measurements.