HashSigs RHDL privacy-sanitized source narrative Evidence record: production-signer-source-finite Repository-relative source: evidence/rtl/wots-production-signer-source-simulation-2026-07-15.md Cryptographic subject/source commit: 2f21bd47bcbab521e3c2055fed6df2eb3fbfb03d Cryptographic source dirty: yes Pre-sanitization narrative SHA-256: 5a6593a4182a2ad7b149e3843fea40aba293f7ce157b168829100148661d75aa Narrative checkout commit: 3810cf837ea79ca005f4ab227b0b5c2134fe6ad1 Narrative checkout dirty: no Sanitization substitutions: private build-host label: 1 -> [remote-build-host] This public projection is not byte-identical when substitutions are listed. The digest identifies the pre-sanitization narrative bytes read by this documentation build. It does not assert that those bytes existed at the cryptographic subject commit. --- sanitized 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.