Skip to content

test(tri_sha256): assert two-block chaining in-spec (closes an out-of-CI proof) - #371

Merged
gHashTag merged 1 commit into
mainfrom
test/sha256-two-block-kat
Aug 9, 2026
Merged

test(tri_sha256): assert two-block chaining in-spec (closes an out-of-CI proof)#371
gHashTag merged 1 commit into
mainfrom
test/sha256-two-block-kat

Conversation

@gHashTag

@gHashTag gHashTag commented Aug 9, 2026

Copy link
Copy Markdown
Owner

The pad2 comment admitted the gap outright: "full two-block bit-exactness vs hashlib is proven by the trinet_ledger_head binary" — i.e. the multi-block property was proven outside the gates, so no PR ever re-checked it. The specs only ever asserted single-block vectors.

Added sha256_two_block_64a: sha256(64 × 'a'), digest ffe054fe…154668eb from the OS SHA-256. That 64-byte message fills block 1 exactly, so all padding lands in block 2 (0x80 marker in w0, the 512-bit length in w15) — exactly the sha256_pad2_word layout. Block 1 compresses from the standard IV via sha256_word; block 2 compresses from that intermediate state via sha256_compress, asserting all 8 final words. This is the first test that exercises state chaining at all.

Written as one test block (8 intermediates reused across 8 assertions = 16 compress calls) rather than 8 separate tests (which would have cost 72), so the icarus run stays sub-second.

Verified: 19/19 under icarus and zig. gen/rust is unchanged (gen-rust doesn't emit test blocks, so the dedicated sha256-gen-check stays green); tri_sha256 has no C gen. The stale pad2 comment now points at the in-spec proof.

Continues the semantic-anchor series (#370 added the empty-string NIST vector).

gen/zig regeneration via the no-gen-edits escape (LEFTHOOK=0).

🤖 Generated with Claude Code

…-CI proof)

The pad2 comment admitted the gap outright: 'full two-block bit-exactness
vs hashlib is proven by the trinet_ledger_head binary' -- i.e. the
multi-block property was proven OUTSIDE the gates, so no PR ever
re-checked it. The specs only ever asserted single-block vectors.

Add sha256_two_block_64a: sha256(64 x 'a'), digest
ffe054fe...154668eb from the OS SHA-256. That 64-byte message fills
block 1 exactly, so all padding lands in block 2 (0x80 marker in w0, the
512-bit length in w15) -- exactly the sha256_pad2_word layout. Block 1
compresses from the standard IV via sha256_word; block 2 compresses from
THAT intermediate state via sha256_compress, asserting all 8 final
words. This is the first test that exercises state chaining at all.

Written as ONE test block (8 intermediates reused across 8 assertions =
16 compress calls) rather than 8 separate tests (which would have cost
72), so the icarus run stays sub-second.

Verified: 19/19 under icarus and zig. gen/rust is unchanged (gen-rust
does not emit test blocks, so the dedicated sha256-gen-check stays
green); tri_sha256 has no C gen. The stale pad2 comment now points at
the in-spec proof.

gen/zig regeneration via the no-gen-edits escape (LEFTHOOK=0).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@gHashTag
gHashTag merged commit 533b56b into main Aug 9, 2026
5 checks passed
@gHashTag
gHashTag deleted the test/sha256-two-block-kat branch August 9, 2026 03:41
gHashTag pushed a commit that referenced this pull request Aug 9, 2026
…stop the bleed

Same trap as the dead test target (#376), one directory over. Cargo.toml
sets 'autobins = false', so a file in src/bin/ is compiled ONLY with an
explicit [[bin]] block. There is exactly ONE such block for 29 files:
28 binaries are never built, never type-checked, free to rot silently.

Among the dead: trinet_compute_lifecycle.rs -- the end-to-end proof that
tests/compute_ring_invariants.rs cites as living outside cargo -- and
trinet_ledger_head.rs, the binary the tri_sha256 spec credited with
proving two-block bit-exactness before #371 moved that proof in-spec.

Triaged all 28 with cargo check, one target at a time:

  24 compile once the gen/rust modules they include by #[path] exist.
     Ten of those gens were simply never committed even though every
     spec is present (the same omission #376 hit). NOT revived here:
     those #[path] mods lack #[allow(clippy::all, unused)], so
     'clippy --all-targets -D warnings' reports 349 errors from the
     GENERATED code and would redden the required build+test gate.
     Reviving them is attribute surgery across 24 files -- its own change.

   3 are genuinely rotted, and this records why:
     tri_rti          unresolved import trios_mesh::rti
     trinet_a2a_node  needs gen/rust/router_ttl.rs -- no such spec exists
     trios_meshd      method 'send' is not a member of trait 'Transport'

The guard makes the debt visible and bounded: every src/bin/*.rs must be
declared or named in KNOWN_DEAD, so a NEW binary can never join them
silently. Shrink the list; never grow it.

Verified: clean tree exits 0 and prints '29 files, 1 declared, 28
known-dead'; a new undeclared bin is caught; the test-side guard still
catches an undeclared test file.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
gHashTag added a commit that referenced this pull request Aug 9, 2026
…stop the bleed (#377)

Same trap as the dead test target (#376), one directory over. Cargo.toml
sets 'autobins = false', so a file in src/bin/ is compiled ONLY with an
explicit [[bin]] block. There is exactly ONE such block for 29 files:
28 binaries are never built, never type-checked, free to rot silently.

Among the dead: trinet_compute_lifecycle.rs -- the end-to-end proof that
tests/compute_ring_invariants.rs cites as living outside cargo -- and
trinet_ledger_head.rs, the binary the tri_sha256 spec credited with
proving two-block bit-exactness before #371 moved that proof in-spec.

Triaged all 28 with cargo check, one target at a time:

  24 compile once the gen/rust modules they include by #[path] exist.
     Ten of those gens were simply never committed even though every
     spec is present (the same omission #376 hit). NOT revived here:
     those #[path] mods lack #[allow(clippy::all, unused)], so
     'clippy --all-targets -D warnings' reports 349 errors from the
     GENERATED code and would redden the required build+test gate.
     Reviving them is attribute surgery across 24 files -- its own change.

   3 are genuinely rotted, and this records why:
     tri_rti          unresolved import trios_mesh::rti
     trinet_a2a_node  needs gen/rust/router_ttl.rs -- no such spec exists
     trios_meshd      method 'send' is not a member of trait 'Transport'

The guard makes the debt visible and bounded: every src/bin/*.rs must be
declared or named in KNOWN_DEAD, so a NEW binary can never join them
silently. Shrink the list; never grow it.

Verified: clean tree exits 0 and prints '29 files, 1 declared, 28
known-dead'; a new undeclared bin is caught; the test-side guard still
catches an undeclared test file.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: SSD DDD <ssdm4@MacBook-Pro.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant