Skip to main content

wots_rhdl/verify/
mod.rs

1//! SHA-256 WOTS verification framing, exact work accounting, and RHDL tops.
2//!
3//! Verification consumes only public data. Its chain workload is therefore
4//! message dependent, while the final comparison always examines all 256 bits.
5//!
6//! # Implemented scope and profile boundary
7//!
8//! This module implements hardware verification only for
9//! `HASHSIGS_SHA256_GENERIC_V1`. [`top::Sha256VerifierTop`] is the inline-lane
10//! source-simulation top, and [`top::ModularSha256VerifierTop`] is the typed
11//! unresolved-lane skeleton for a separately generated RHDL SHA-256 lane. There
12//! is no legacy Keccak verifier top in this crate. `LEGACY_KECCAK` signatures
13//! can be checked by the `hashsigs-reference` software oracle, but they must not
14//! be presented to this hardware interface.
15//!
16//! Serialized frames have no profile tag. A host protocol must authenticate
17//! the selected profile/build target separately. Verification does not repair
18//! the one-time-key requirement: accepting one signature says nothing about
19//! whether its private key was safely used only once.
20//!
21//! # Input and result contract
22//!
23//! [`framing::VerifyStreamBeat`] carries the canonical byte sequence
24//! `signature`, then `public_seed`, then `public_key_hash`, then the
25//! already-hashed 32-byte message. All 2,240 bytes occupy exactly 35 transfers:
26//!
27//! | Beats | Contents | Sideband |
28//! |---:|---|---|
29//! | 0 through 32 | Signature segments 0 through 65 | Every byte valid; not last |
30//! | 33 | Signature segment 66 followed by the public seed | Every byte valid; not last |
31//! | 34 | Public-key endpoint hash followed by the message digest | Every byte valid; last |
32//!
33//! [`framing::pack_verify_input`] and [`framing::unpack_verify_input`] are the
34//! independent host framing oracles. The hardware locks one physical context
35//! from accepted beat zero through exactly 35 accepted beats. Fixed beat count,
36//! not untrusted `last`, releases frame ownership. A stalled ready/valid offer
37//! does not advance either the top or child frame counter.
38//!
39//! [`top::VerifierTopOutput`] returns one registered
40//! [`cluster::VerifyResult`]. Its job ID is the opaque identity captured from
41//! beat zero. `verified` is meaningful only with [`sha::VERIFY_ERROR_NONE`]; a
42//! framing, transport, or audit error forces it false. The result remains stable
43//! while `result_valid` is true and the consumer withholds `result_ready`, except
44//! that the first fatal transport edge may convert a retained clean completion
45//! into an identified transport error before suppressing its transfer.
46//!
47//! # Work graph and production topology
48//!
49//! Let `S` be the sum of `15 - digit` over the 64 message digits and let `h(S)`
50//! be the sum of the three hexadecimal checksum digits. The verifier performs
51//! exactly `S + 45 - h(S)` real chain hashes, ranging from 45 to 990. Including
52//! 16 mask PRFs and 34 serialized endpoint-hash blocks, a SHA job emits between
53//! [`tasks::VERIFY_MIN_SHA_TASKS`] and [`tasks::VERIFY_MAX_SHA_TASKS`] (95 and
54//! 1,040) compression tasks. A bypassed chain position emits no compression
55//! request.
56//!
57//! One [`sha::VerifySingleContextSha`] owns the frame, dependency state,
58//! parity-banked chain storage, exact issued/retired counts, and retained result.
59//! Four contexts share one lane through [`transport::VerifyTransport`] inside
60//! [`cluster::VerifierCluster`]. The transport delays each launched tag for the
61//! lane's exact 64-cycle latency and compares it before routing. The production
62//! [`top::VerifierTop`] replicates three complete clusters, giving twelve
63//! physical contexts and three lanes:
64//!
65//! ```text
66//! top::Sha256VerifierTop
67//!   +-- cluster 0: 4 verifier contexts + expected-tag transport + 1 lane
68//!   +-- cluster 1: 4 verifier contexts + expected-tag transport + 1 lane
69//!   +-- cluster 2: 4 verifier contexts + expected-tag transport + 1 lane
70//!   +-- registered input-frame ownership and fair result merge
71//! ```
72//!
73//! # Fail-closed transport and reset
74//!
75//! Outbound rejection and every missing, extra, mistimed, swapped, malformed,
76//! stale, duplicate, or unowned return are fatal transport events. The failing
77//! cluster registers reset-only poison. The top records the first cause,
78//! broadcasts a registered abort to peers, blocks new frame admission and lane
79//! launch, and drains already-accepted identities as nonzero errors. One input
80//! beat may complete on the original containment edge because already-advertised
81//! ready cannot depend combinationally on the newly observed response fault;
82//! registered poison removes credit on the next cycle.
83//!
84//! Shared reset flushes every lane, expected-tag slot, valid bit, frame owner,
85//! generation, result, and poison state and suppresses transfers on the reset
86//! edge. Resetless data is ignored while resettable ownership is clear. Systems
87//! that cannot reset the contexts, transport, and lanes together do not satisfy
88//! this verifier's stale-token contract.
89//!
90//! # Reading order
91//!
92//! 1. [`framing`] defines the exact untrusted byte stream and host oracle.
93//! 2. [`tasks`] derives message-dependent work and the canonical verifier tag
94//!    subset without hardware state.
95//! 3. [`sha`] implements one frame-owning context and its local audit/fault
96//!    rules.
97//! 4. [`transport`] arbitrates four contexts and enforces the exact lane-return
98//!    schedule before routing.
99//! 5. [`cluster`] composes four contexts, one transport, one injectable lane,
100//!    result buffering, and local poison.
101//! 6. [`top`] composes three clusters, locks the global frame, merges results,
102//!    and contains a fault across peers.
103//!
104//! # Evidence boundary
105//!
106//! The complete inline-lane three-cluster top has Rust/RHDL source-simulation
107//! evidence for twelve simultaneous worst-case jobs. The trace accepts and
108//! routes exactly `12 * 1,040 = 12,480` SHA tasks, checks all decisions and job
109//! identities under deterministic result stalls, and reaches quiescence. The
110//! modular top also passes a bounded source-descriptor structure check with the
111//! expected unresolved lane leaf.
112//!
113//! Those are source-tier results. This verifier has no linked generated-Verilog
114//! arithmetic/equivalence simulation, U280 synthesis, mapped-resource, timing,
115//! placement, route, or card-execution evidence. Signer throughput evidence
116//! elsewhere in the crate cannot be attributed to the verifier.
117
118pub mod cluster;
119pub mod framing;
120pub mod sha;
121pub mod tasks;
122pub mod top;
123pub mod transport;
124
125pub use cluster::{
126    ModularSha256VerifierCluster, Sha256VerifierCluster, VERIFY_DIAGNOSTIC_CHILD_FAULT,
127    VERIFY_DIAGNOSTIC_CHILD_RESPONSE_REJECT, VERIFY_DIAGNOSTIC_EXTERNAL_ABORT,
128    VERIFY_DIAGNOSTIC_OWNERSHIP, VerifierCluster, VerifyClusterControl, VerifyClusterCore,
129    VerifyClusterCoreInput, VerifyClusterInput, VerifyClusterOutput, VerifyClusterSelection,
130    VerifyClusterTransportGateInput, VerifyClusterTransportGateOutput, VerifyResult,
131    select_verify_cluster_context_kernel, sha256_verifier_cluster_kernel,
132    verifier_cluster_with_lane_kernel, verify_cluster_core_kernel,
133    verify_cluster_transport_gate_kernel,
134};
135
136pub use framing::{
137    VERIFY_BEAT_BYTES, VERIFY_FULL_KEEP, VERIFY_INPUT_BEATS, VERIFY_INPUT_BYTES, VerifyBeatHalves,
138    VerifyFrame, VerifyFrameBeat, VerifyFrameError, VerifyStreamBeat, pack_verify_input,
139    unpack_verify_input, verify_beat_halves_kernel, verify_hash_equal_kernel,
140};
141pub use sha::{
142    VERIFY_CONTEXT_LOGICAL_RAM_BITS, VERIFY_ERROR_AUDIT, VERIFY_ERROR_FRAME, VERIFY_ERROR_NONE,
143    VERIFY_ERROR_TRANSPORT, VERIFY_LANE_LATENCY, VerifyContextControl, VerifyContextInput,
144    VerifyContextOutput, VerifyPrepareRequestInput, VerifySingleContextSha,
145    prepare_verify_request_kernel, verify_single_context_sha_kernel,
146};
147pub use tasks::{
148    VERIFY_MASK_TASKS, VERIFY_MAX_CHAIN_TASKS, VERIFY_MAX_SHA_TASKS, VERIFY_MIN_CHAIN_TASKS,
149    VERIFY_MIN_SHA_TASKS, VERIFY_PUBLIC_KEY_TASKS, canonical_verification_tasks,
150    verification_chain_count, verification_chain_count_kernel, verification_chain_fields_kernel,
151    verification_fields_are_canonical_kernel, verification_message_task_count_kernel,
152    verification_sha_task_count, verification_sha_task_count_kernel,
153    verification_tag_is_well_formed_kernel,
154};
155pub use transport::{
156    VERIFY_CLUSTER_CONTEXTS, VERIFY_DIAGNOSTIC_ISSUE_REJECT, VERIFY_DIAGNOSTIC_RETURN_FORMAT,
157    VERIFY_DIAGNOSTIC_RETURN_OWNER, VERIFY_DIAGNOSTIC_RETURN_TAG, VERIFY_DIAGNOSTIC_RETURN_TIMING,
158    VERIFY_EXPECTED_TAG_ADDRESS_BITS, VerifyTransport, VerifyTransportControl,
159    VerifyTransportInput, VerifyTransportOutput, VerifyTransportSelection,
160    compression_input_equal_kernel, select_verify_transport_request_kernel,
161    verify_transport_kernel, verify_transport_request_is_canonical_kernel,
162};
163
164pub use top::{
165    ModularSha256VerifierTop, Sha256VerifierTop, VERIFY_TOP_CLUSTERS, VERIFY_TOP_CONTEXTS,
166    VERIFY_TOP_DIAGNOSTIC_ADMISSION_CURSOR, VERIFY_TOP_DIAGNOSTIC_CLUSTER_0,
167    VERIFY_TOP_DIAGNOSTIC_CLUSTER_1, VERIFY_TOP_DIAGNOSTIC_CLUSTER_2,
168    VERIFY_TOP_DIAGNOSTIC_OWNERSHIP, VERIFY_TOP_DIAGNOSTIC_RESULT_CURSOR, VerifierTop,
169    VerifierTopControl, VerifierTopInput, VerifierTopOutput, VerifierTopSelection,
170    select_verifier_top_cluster_kernel, sha256_verifier_top_kernel, verifier_top_with_lane_kernel,
171};