Skip to content

sha256: roll sha256_add_to_hash (-250 B on every profile) (L4) - #290

Merged
JC-000 merged 2 commits into
masterfrom
layout/l4-roll-sha256-add-to-hash
Oct 12, 2026
Merged

JC-000 merged 2 commits into
masterfrom
layout/l4-roll-sha256-add-to-hash

Conversation

@JC-000

@JC-000 JC-000 commented Oct 12, 2026

Copy link
Copy Markdown
Owner

Layout pass L4. sha256_add_to_hash rolled into a word loop: 297 -> 47 B (-250 B on every profile, ip65 included), at +121 cycles per block (+128 on comb-store and the body-to-REU demo, by placement). SHA-256 KATs green on all profiles.

Merge order: independent; merges cleanly with all five sibling PRs.

Commits (messages verbatim; each carries its red-green evidence)

bfd2272 sha256: roll sha256_add_to_hash into a word loop (-250 B, every profile)

sha256_add_to_hash was eight unrolled copies of "clc; 4 x lda/adc/sta"
(297 B). sha256_h0..h7 and sha_a..sha_h are each eight contiguous words in
the same order (src/data.s), so one X indexes both: a word loop, high word
first, LSB-to-MSB carry ripple inside the word, exactly as before. 47 B.
Two lderror asserts pin the contiguity it relies on. Its only caller is
jsr sha256_add_to_hash / rts at the end of compression, so clobbering X
is safe.

Bytes freed, tools/measure_margins.py --build, every profile +250 B in
the region holding sha256.s's code:
ip65 CRYPTO_OVERLAY 45 -> 295, ip65-onchip 11 -> 261 (wiki: same);
uci NET_CODE 176 -> 426, uci-onchip 184 -> 434, uci-comb 176 -> 426,
uci-onchip-store 184 -> 434, uci-comb-store 38 -> 288, comb demo 38 -> 288.

Cycles, per 64 B block, counted from instruction timings (no indexed
access crosses a page on any shipped profile: h0 at $B165 ip65 /
$A965 uci, sha_a 32 B above): 406 -> 527, +121.

Tests: test_sha256 10/10, test_hkdf 12/12, test_keyschedule_steps 9/9,
test_chained_hmac N=1..10 OK on ip65; test_hkdf 12/12 and
test_keyschedule_steps 9/9 on uci-onchip (C64_SKIP_BUILD=1).
Red: ldx #24 (drops h7 += h), PRG 07019d27..., test_hkdf 12/12 FAILED;
sha_c/sha_d swapped in data.s -> lderror "sha_a..sha_h must be
contiguous", no PRG. Restored: 9a05a5a3... (uci-onchip), green.

24ceea2 sha256: correct the rolled loop's cycle cost (+121 or +128 by placement)

The previous commit said +121 cycles per 64 B block "on any shipped
profile". Wrong on two: where the taken bpl @word crosses a page each
taken branch costs one more cycle, 7 per call. Recomputed from where the
routine links on all ten measure_margins profiles (same branch,
bfd2272):

527 cycles (+121): ip65, ip65-onchip, both ip65 wiki targets, uci,
uci-onchip, uci-comb, uci-onchip-store (loop inside one page)
534 cycles (+128): uci-comb-store and the comb demo (routine at $34DC,
loop $34DE..$350A: the bpl at $3508 branches back across $3500)

No indexed lda/adc crosses a page on any of them (sha256_h0 / sha_a sit
32 B apart inside one page). Placement-dependent, so the comment above
the routine now says how the cost arises rather than pinning one number.
Comment only: comb-store PRG unchanged (2f9ad380...).

🤖 Generated with Claude Code

JC-000 and others added 2 commits October 7, 2026 18:54
sha256_add_to_hash was eight unrolled copies of "clc; 4 x lda/adc/sta"
(297 B). sha256_h0..h7 and sha_a..sha_h are each eight contiguous words in
the same order (src/data.s), so one X indexes both: a word loop, high word
first, LSB-to-MSB carry ripple inside the word, exactly as before. 47 B.
Two lderror asserts pin the contiguity it relies on. Its only caller is
`jsr sha256_add_to_hash / rts` at the end of compression, so clobbering X
is safe.

Bytes freed, tools/measure_margins.py --build, every profile +250 B in
the region holding sha256.s's code:
  ip65 CRYPTO_OVERLAY 45 -> 295, ip65-onchip 11 -> 261 (wiki: same);
  uci NET_CODE 176 -> 426, uci-onchip 184 -> 434, uci-comb 176 -> 426,
  uci-onchip-store 184 -> 434, uci-comb-store 38 -> 288, comb demo 38 -> 288.

Cycles, per 64 B block, counted from instruction timings (no indexed
access crosses a page on any shipped profile: h0 at $B165 ip65 /
$A965 uci, sha_a 32 B above): 406 -> 527, +121.

Tests: test_sha256 10/10, test_hkdf 12/12, test_keyschedule_steps 9/9,
test_chained_hmac N=1..10 OK on ip65; test_hkdf 12/12 and
test_keyschedule_steps 9/9 on uci-onchip (C64_SKIP_BUILD=1).
Red: `ldx #24` (drops h7 += h), PRG 07019d27..., test_hkdf 12/12 FAILED;
sha_c/sha_d swapped in data.s -> lderror "sha_a..sha_h must be
contiguous", no PRG. Restored: 9a05a5a3... (uci-onchip), green.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The previous commit said +121 cycles per 64 B block "on any shipped
profile". Wrong on two: where the taken `bpl @word` crosses a page each
taken branch costs one more cycle, 7 per call. Recomputed from where the
routine links on all ten measure_margins profiles (same branch,
bfd2272):

  527 cycles (+121): ip65, ip65-onchip, both ip65 wiki targets, uci,
    uci-onchip, uci-comb, uci-onchip-store (loop inside one page)
  534 cycles (+128): uci-comb-store and the comb demo (routine at $34DC,
    loop $34DE..$350A: the bpl at $3508 branches back across $3500)

No indexed lda/adc crosses a page on any of them (sha256_h0 / sha_a sit
32 B apart inside one page). Placement-dependent, so the comment above
the routine now says how the cost arises rather than pinning one number.
Comment only: comb-store PRG unchanged (2f9ad380...).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@JC-000
JC-000 merged commit 77909e4 into master Oct 12, 2026
JC-000 added a commit that referenced this pull request Oct 12, 2026
The capture predated #292's P256_SCRATCH_UNION and #290's sha256 roll, so
its five PRG hashes and labels were the pre-rebase links. Regenerated with
test_rig_scratch.py --build --write-fixtures; --build re-run: matrix PASS,
17/17, hashes uci ed6871b2, uci-onchip eaa43a6a, uci-comb 8f8a0d05,
uci-comb-trust 936884e9, uci-comb-demo-trust b66eaf0c.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@JC-000
JC-000 deleted the layout/l4-roll-sha256-add-to-hash branch October 14, 2026 15:36
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