chore(libs): bump x25519 pin to v0.13.0, and keep the wrapper linkable - #189
Merged
Conversation
Issue #166 is an advisory that the vendored libs/x25519 v0.11.2 predates the c64-lib-contract §8.2 REU post-execute settle. It is correct about the tree and wrong about the blast radius: USE_X25519_SIBLING defaults to 0 (Makefile:44), does not link under either backend, and no shipped product passes it, so libs/x25519 contributes zero bytes to every PRG we release. This bump is hygiene, not a fix. Proof of PRG-neutrality, per the repo rule that only the PRG sha256 counts: `make clean && make BACKEND=uci USE_NISTCURVES_ONCHIP_COMB=1` before and after the bump both produce c423476011e1928f5955e4773c3cf28c4876dcf76e70be9de40c2f4522f8bf72. The sibling archive is never even staged (build/lib/ holds only nistcurves-p256-onchip-comb.a). The bump is not free for the dead sibling lane. v0.12.0 added three bytes to the sibling's src/data.s (x25519_reu_fault plus the REU_SETTLE slow path's two internal bytes), and this wrapper replaces that file wholesale, so at the new pin `make BACKEND=uci USE_X25519_SIBLING=1` gained three unresolved externals on top of the pre-existing structural overflow. Restating the three bytes in the staged BSS restores parity: the link now fails on exactly the one failure it failed on at v0.11.2, `X25519_BSS overflows CRYPTO_OVERLAY by 1536 bytes`, and nothing else. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #166.
Bumps
libs/x25519from v0.11.2 to v0.13.0(
3ea64210ce4c7c4fcebdded49c3ca663ce0fd8d3, tag dereferenced via the GitHubAPI, not read off
git submodule status), and restates three BSS bytes in theintegration wrapper so the sibling lane keeps failing on the one failure it
already had.
This is a rebase onto
dc06095of a commit prepared in an earlier session thatwas code-reviewed but never built, never tested and never pushed. Everything
below was measured here.
Read this first: the sibling is dormant, so this is hygiene, not a fix
#166 is an advisory, and it is careful to bound itself. Bounding it further:
libs/x25519contributes zero bytes to every PRG we ship.USE_X25519_SIBLING ?= 0(Makefile:44); noPACKAGE_VARIANTSrow intools/package/_common.shsets it.still true at the new pin (verified below).
uci-comb"drives x25519's REU multiplypath". It does not.
reu_fetch_mul_rowis APP_OWNED here (ourSHARED_REU_MUL_FETCHdefine suppresses the library's copy), and in allthree shipped maps the symbol does not exist at all:
boot.s:52-54gatesthe
.exportoff underUSE_NISTCURVES_ONCHIP, leaving the body atboot.s:945as unreferenced code. Its single callersrc/crypto/fe25519.s:439sits in the.elseof the same guard and iscompiled out —
fe25519.sdeliberately does not even.importthe symbol onthat profile. All three shipped variants set the flag (comb promotes it at
Makefile:221-222).So the §8.2 REU settle this bump brings in is not reachable from anything we
release. Do not read this PR as closing a live defect. It gets the vendored
tree onto a maintained tag so the dormant lane is not the thing that surprises
us later.
The exposure that is real is in
libs/nistcurves, which is in every shippedPRG and still pinned below its own §8.2 release — filed separately, see below.
Both backends link
Standing rule for any pin bump. Submodules initialised in a fresh worktree,
make ip65-libsrun once, blob rebuilt in-worktree.The blob matches the documented
cf1a5ff7…/ 6,951 B, so the worktree builtits own and did not reach into the parent checkout.
All three PRGs are byte-identical to
dc06095. I built the same three atorigin/masterin the same worktree and compared — same hashes, both sides.That is the measurement that supports the "zero bytes in the shipped PRG"
claim above; it is not a mixed-build artefact, it is the point.
KATs
Both in VICE via
tools/_vice_helpers.py::default_vice_config()(
-reu -reusize 512applied, per the harness gotcha).tools/test_x25519.pytools/test_ecdsa_kat_oracle.pytools/test_ecdsa_kat_oracle.pyip65-onchip,C64_SKIP_BUILD=1The onchip run is the
poly_prod_lo/hirendezvous guard CLAUDE.md asks for —this PR does not touch that ownership, but the run is cheap evidence that it is
still intact. No hardware was used.
Red-green
Most of this diff is a submodule gitlink, for which no behavioural test is
possible: the changed bytes are not in any PRG we build, so there is
nothing to assert about runtime behaviour and I am not claiming coverage I do
not have.
The one hunk with an effect is the wrapper change, and that one does
red-green cleanly. The sibling gained three bytes in its
src/data.s(
x25519_reu_faultplus theREU_SETTLEslow path's two internal bytes;the sibling annotates them §8.2 at v0.13.0 —
x25519.inc:414,fe25519.s:40— the commit message's "v0.12.0" is off by a release).build_x25519.shreplaces that file wholesale, so the staged BSS has torestate them.
Red — new pin, wrapper hunk reverted to
dc06095,make BACKEND=uci USE_X25519_SIBLING=1:Green — with the hunk, same command:
The three unresolved externals are gone and only the pre-existing structural
overflow remains — the lane still does not link, which is unchanged and out of
scope here.
One note for the record: CLAUDE.md states this overflow as 1,280 B, not
1,536 B. The measurement above is what ld65 reports today at both pins; the
CLAUDE.md figure is stale. Added to #193 (CLAUDE.md margin staleness) rather
than fixed here — other lanes are in that file.
Reviewer notes
uci-comb(c423476…) thatI measured at
dc06095, even though it was written against0b55c30. I didnot take that on trust; both sides were rebuilt and compared here.
repo, because nothing links it.
Related, not in this PR
libs/nistcurvespin has the same §8.2 gap, upstreamfixed it in v0.12.0 (2026-08-30), and unlike x25519 that code is in every
shipped PRG, with
uci-combthe exposed variant. Bumping it is blocked, andnot by bytes: at v0.12.0 all three products fail the link with
Duplicate external identifier: 'nistcurves_mul_dma_hi', a §8.0/§8.3APP_OWNED ownership collision. Reproduced and traced in that issue.
src/has 12 unfencedsta reu_commandsites, which noupstream bump can fix for us. Only two of them (the
reu_mul_initstashes)are reachable in a shipped product.
🤖 Generated with Claude Code