Skip to content

Retire all archive member surgery — SPEC §6.1 satisfied (closes #119) - #122

Merged
JC-000 merged 3 commits into
masterfrom
feat/spec-6.1-app-owned-v2
Aug 16, 2026
Merged

Retire all archive member surgery — SPEC §6.1 satisfied (closes #119)#122
JC-000 merged 3 commits into
masterfrom
feat/spec-6.1-app-owned-v2

Conversation

@JC-000

@JC-000JC-000 commented Aug 16, 2026

Copy link
Copy Markdown
Owner

Closes#119. c64-https no longer edits any archive member set — SPEC §6.1 is satisfied.

Pins move to libs/nistcurvesv0.11.2 and libs/x25519v0.11.2.

What changed

The §8.0 APP_OWNED shape is now requested through CONTRACT_DEFINES (SPEC §6.2) rather than achieved by deleting members:

-D SHARED_SQTAB_INIT -D SHARED_REU_MUL_INIT -D SHARED_REU_MUL_FETCH
-D SHARED_CT_MUL_8X8 -D LIB_NO_BARE_EXPORTS=1 -D LIB_SHARED_SQTAB_BASE=0xBC00

Gone: the three member drops (mul_8x8.o, data_shared.o, reu_mul_init.o) and the generated glue TU that .included pristine library source for mul_8x8_onchip.o.

The payoff

The manifest now attests the deferral instead of us resolving it by deletion. That makes the §8.0 disjointness and coverage asserts live, having been recorded in lib_contract_asserts.s as "not writable today" since the clause landed.

Measured on the staged archives — note that only PRIMITIVES is profile-independent:

archivePRIMITIVESCONSUMES
lib-p256-verify (REU)$0000$0007
lib-p256-verify-onchip$0000$0005
lib-p256-comb-onchip$0000$0005

Under FP_ONCHIP_MUL the manifest zeroes the reu_mul bit in both masks, because that build genuinely does not read the primitive — a deferral switch drops a bit from ownership only, a profile gate drops it from ownership and consumption. All three asserts pass either way ($0005 & ~$0007 = 0).

The coverage assert is a tautology today and is documented as such: APP_OWNED = $0007 covers every allocated bit, so it cannot fire. It is kept as the clause's canonical form, and it arms itself when a fourth primitive is allocated. It does not guard the poly_prod rendezvous — only the comb/onchip KAT does.

Ownership moves

All three go the direction §8.0 always implied — the provider of a primitive owns its state:

symbolnow owned bywas
poly_prod_lo/hic64-https (we provide the §8.3 ct_mul_8x8 body)imported under onchip
sqtab_lo/hic64-https (we provide sqtab_init)yielded to the sibling under onchip; sqtab_reserved placeholder retired
ABI equateprefixed LIB_NISTCURVES_ABI_VERSIONbare name, now suppressed by the export gate

Both buffer moves are silent-failure surfaces: a second definition of either links clean and produces wrong arithmetic with no diagnostic anywhere. The KATs are the evidence, not the link. sqtab additionally has a hard address constraint — the sibling reads through its own equates derived from LIB_SHARED_SQTAB_BASE, deriving sqtab_hi = base+$0200, so the labels must land at $BC00/$BE00. The Makefile's post-link check now asserts sqtab_lo rather than the retired placeholder.

Two upstream fixes made this possible

  • v0.11.1 made SHARED_CT_MUL_8X8 assemble against the on-chip TU (c64-nist-curves#123, filed from this work). Before it, the glue TU was the only route.
  • v0.11.2 added the knob-staleness guard. A changed CONTRACT_DEFINES used to reuse stale objects and exit 0 with a different archive than requested. An earlier attempt at this change, before that guard, produced a comb image that would not boot — and the cause looked like these ownership moves when it was actually mixed objects. Worth knowing: anything inexplicable after a define change, check the pin is ≥ v0.11.2 before debugging anything else.

Verification

  • ECDSA KAT oracle 6/6 on REU, on-chip and comb (3 valid accepted, 3 invalid rejected each). Comb is the one that matters most — it exercises the poly_prod rendezvous through og_common during its boot precompute, which is exactly the silent-failure path.
  • REU-profile PRGs byte-identical to the previous release (7a02e213d014, b574b344cdca); on-chip and comb changed as expected.
  • make package-verify: 31/31 gate logic tests, 11/11 artifact checks, RELEASE ARTIFACTS VERIFIED, no skips, clean provenance.

Also in this PR (from contract-side review)

The zp_config rebuild was the surviving tail of #119: it re-archived one member built withoutCONTRACT_DEFINES, so that member re-exported the bare zp_* names every other member suppressed — one archive, two configurations (§6.2), and the resurrected names are the #83 ZP collision family. Routing the overrides through CONTRACT_ZP_DEFINES retired the rebuild, the member-name discovery block, the staging directory and the re-archive step together. The archive we link is now byte-for-byte upstream's. PRG-neutral: all five hashes unchanged.

Still open

§13 net ABI (#70) — deferred, unchanged by this.

🤖 Generated with Claude Code

Pins: libs/nistcurves v0.11.0 -> v0.11.2, libs/x25519 v0.11.1 -> v0.11.2.
c64-https no longer edits any archive member set. The §8.0 APP_OWNED shape
is requested through CONTRACT_DEFINES (SPEC §6.2) instead:
-D SHARED_SQTAB_INIT -D SHARED_REU_MUL_INIT -D SHARED_REU_MUL_FETCH
-D SHARED_CT_MUL_8X8 -D LIB_NO_BARE_EXPORTS=1
-D LIB_SHARED_SQTAB_BASE=0xBC00
Three drops (mul_8x8.o, data_shared.o, reu_mul_init.o) and the generated
glue TU for mul_8x8_onchip.o are all gone.
WHAT THAT BUYS
The manifest now ATTESTS the deferral rather than us resolving it by
deletion: SHARED_PRIMITIVES=$0000, SHARED_CONSUMES=$0007. So the §8.0
disjointness and coverage asserts — recorded in lib_contract_asserts.s as
"not writable today" since the clause landed — are live, and
profile-independently, since the old REU-vs-onchip mask split was a
property of which bodies each archive shipped and neither ships any now.
OWNERSHIP MOVES, ALL TOWARD WHAT §8.0 ALWAYS IMPLIED
poly_prod_lo/hi we provide the §8.3 ct_mul_8x8 body, so we own its
product scratch. poly1305.s exports in every profile;
it used to import under onchip.
sqtab_lo/hi we provide sqtab_init, so we own the table. data.s
defines it in every profile and sqtab_reserved is gone.
The sibling still reads via its own equates derived from
LIB_SHARED_SQTAB_BASE (sqtab_hi = base+$0200), so the
labels MUST land at $BC00/$BE00 — the Makefile check now
asserts sqtab_lo rather than the retired placeholder.
ABI import prefixed LIB_NISTCURVES_ABI_VERSION; the bare name is
suppressed by the export gate.
Both are silent-failure surfaces: a second definition of either links
clean and yields wrong arithmetic with no diagnostic. The KATs are the
evidence, not the link.
TWO UPSTREAM FIXES MADE THIS POSSIBLE
v0.11.1 made SHARED_CT_MUL_8X8 assemble against the on-chip TU
(c64-nist-curves#123, filed from here) — before it, the glue TU was the
only route. v0.11.2 added the knob-staleness guard: a changed
CONTRACT_DEFINES used to reuse stale objects and exit 0 with a different
archive than requested. An earlier attempt at this change, before that
guard, produced a comb image that would not boot; the cause looked like
these ownership moves and was actually mixed objects. Anything
inexplicable after a define change: check the pin is >= v0.11.2 first.
VERIFICATION
ECDSA KAT oracle 6/6 on REU, onchip AND comb builds (3 valid accepted,
3 invalid rejected each) — comb is the one that exercises the poly_prod
rendezvous through og_common at boot.
REU-profile PRGs byte-identical to the previous release (7a02e213d014,
b574b344cdca); onchip/comb changed as expected.
make package-verify: 11/11 artifact checks, RELEASE ARTIFACTS VERIFIED.
Closes#119. §13 (#70) remains open and deferred.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@JC-000

Copy link
Copy Markdown
OwnerAuthor

Evaluated against SPEC v0.10.6, with the v0.11.2 upstream source and both release notes in hand. The migration itself is right: this is exactly the §6.1→§6.4→§6.6 repair the clause chain was written for, and the evidence bar (KATs on all three profiles including comb's og_common rendezvous path, REU byte-identity, package-verify with no skips) is the correct one for a change whose failure mode is silent wrong arithmetic. Three findings — one worth fixing before merge, one comment-level note, one follow-up that keeps #119 from closing entirely clean.

Verified

  • Pins are exact tag commits.libs/nistcurves 58f4cf5 = v0.11.2^{}, libs/x25519 5b344bf = v0.11.2^{} (checked against git ls-remote --tags).
  • The define set matches §6.2's table: the four SHARED_* switches, LIB_NO_BARE_EXPORTS, and LIB_SHARED_SQTAB_BASE are all named CONTRACT_DEFINES cargo; 0xBC00 honors the $-free rule. §8.2's both-or-neither rule for SHARED_REU_MUL_INIT/_FETCH is honored.
  • The §8.3 story matches v0.10.6 exactly. The five-symbol provider surface (ct_mul_8x8, smc_sum_a_imm, smc_diff_a_imm, poly_prod_lo/hi) is what the v0.11.1 release notes say the deferring TU now imports, and poly1305.s exports all five with the profile split removed. The glue-TU retirement comment correctly credits nist#123.
  • The new §8.0 asserts are the SPEC's canonical forms, and the PRIMITIVES = 0 tripwire with its "do not restore the member drops" warning is the right primary defense.
  • The sqtab_lo post-link check is sound as written: sqtab_hi needs no separate grep since the two labels are contiguous in the same segment, so lo at $BC00 forces hi to $BE00 — matching the sibling's own .assert sqtab_hi = sqtab_lo + $0200.

Fix before merge: SHARED_CONSUMES is not $0007 profile-independently

The PR body and the new comment block in src/lib_contract_asserts.s ("LIB_NISTCURVES_SHARED_CONSUMES $0007 — it still READS all three … PROFILE-INDEPENDENT, unlike the old tripwire") overstate it. Upstream's manifest at the v0.11.2 pin zeroes the reu_mul consumes bit under FP_ONCHIP_MUL (src/lib_manifest.s_USE_REU_MUL = 0 in the profile gate) and hard-asserts it:

.ifdef FP_ONCHIP_MUL .assert (LIB_NISTCURVES_SHARED_CONSUMES & LIB_SHARED_PRIMITIVES_REU_MUL) = 0, error,"FP_ONCHIP_MUL manifest must not claim SPEC 8.2 reu_mul consumption".endif

That's §8.0's three-state table working as designed: the onchip build is a non-consumer of reu_mul (profile gate drops the bit from both masks — deferral switches drop it from ownership only). So the onchip and comb archives report SHARED_CONSUMES = $0005, and the REU archive $0007. What actually became profile-independent is SHARED_PRIMITIVES = $0000 — and all three asserts passing, since $0005 & ~$0007 = 0. No assert changes needed; the comment (and ideally the PR description) should say $0007 (REU) / $0005 (onchip, comb), or the next person to od65 an onchip archive will "discover" a discrepancy this comment says can't exist.

Note: the coverage assert cannot fire today

With APP_OWNED = $0007 covering every allocated §8.0 bit and CONSUMES drawn from those same three bits, CONSUMES & ~(APP_OWNED | PRIMITIVES) is identically zero — the coverage assert is a tautology until a future §8.x clause allocates bit $0008 and nistcurves consumes it. The comment sells it as catching "a deferral requested but not honoured," but that case is actually covered elsewhere: defines missing from the manifest TU → the PRIMITIVES = 0 assert; defines missing from the code TUs → duplicate-external link failure against your exports. Worth one sentence in the comment so nobody reads the coverage assert as guarding the poly_prod rendezvous — it can't. Keeping the assert is still right (it's the canonical form, and it arms itself the day a fourth primitive lands).

Follow-up: the zp_config rebuild + re-archive is the surviving tail of #119

"No archive member set is edited" is now literally true, but steps 3/5 of build_nistcurves_p256.sh still rebuild the zp_config*.o member out-of-band and re-archive — and that rebuild passes only the ZP overrides, not the CONTRACT_DEFINES string. Concretely: zp_config.s gates its bare ZP exports on .ifndef LIB_NO_BARE_EXPORTS (v0.11.2, src/zp_config.s:152–171), so the one member you rebuild re-exports the bare zp_* names that every other member of the same archive was built to suppress. That's a §6.2 "one configuration per artifact" violation in the shipped archive, and the resurrected names are exactly the #83 ZP collision family the suppression gate exists for — dormant today, live the day a second contract library enters the link built the same way.

The sanctioned route exists at this pin: upstream has carried CONTRACT_ZP_DEFINES with an explicit rule reaching the ZP TU since nist#104, and the v0.11.2 staleness stamp covers it (same CURRENT_KNOBS string as CONTRACT_DEFINES). Passing the three overrides there (-D nistcurves_zp_ptr2=0x3d -D fp_mul_i=0x39 -D fp_mul_j=0x3a, already 0x-hex) should retire the rebuild, the member-name discovery case block, and the re-archive step wholesale — the archive you link becomes byte-for-byte the one upstream's make produced, which is what makes §6.1's "no copying intermediates around" true by construction. The script's header comment ("we cannot pass -D overrides via make CA65=…… we build upstream with its defaults") predates both knobs and now contradicts the build invocation a few lines below it. Fine as its own PR with its own od65 post-check run — but #119 shouldn't be remembered as fully discharged until it lands, so worth either folding in or filing the successor issue at merge time.

None of the three findings touches the KAT/byte-identity evidence, which stands as reported. Once this merges I'll refresh the c64-https row in the contract repo's consumers.md — it currently carries the §6.1/§6.6/§8.0 gap trio this PR closes (§13/#70 stays open, as noted).

… the zp_config rebuild
Three findings from the contract-side review of #122. All three verified
against the v0.11.2 source before acting.
1. SHARED_CONSUMES IS NOT PROFILE-INDEPENDENT (comment was wrong)
The §8.0 block claimed CONSUMES = $0007 "PROFILE-INDEPENDENT". Measured
with od65 on the staged archives:
archive PRIMITIVES CONSUMES
lib-p256-verify (REU) $0000 $0007
lib-p256-verify-onchip $0000 $0005
lib-p256-comb-onchip $0000 $0005
Only PRIMITIVES is profile-independent. Under FP_ONCHIP_MUL the manifest
zeroes the reu_mul bit in BOTH masks because that build genuinely does not
read the primitive, and upstream hard-asserts it. That is §8.0's
three-state table working: a deferral switch drops a bit from ownership
only; a profile gate drops it from ownership AND consumption. No assert
change needed — all three pass either way, since $0005 & ~$0007 = 0. The
comment now carries the table so the next person to od65 an onchip archive
does not "discover" a contradiction.
2. THE COVERAGE ASSERT CANNOT FIRE TODAY (scope was oversold)
APP_OWNED is $0007, covering every §8.0 bit allocated so far, and CONSUMES
is drawn from those same bits — so CONSUMES & ~(APP_OWNED | PRIMITIVES) is
identically zero. The comment sold it as catching "a deferral requested but
not honoured"; it cannot. That case is covered by the PRIMITIVES = 0 assert
(defines missing from the manifest TU) or by a duplicate-external link error
(defines missing from the code TUs), and the poly_prod rendezvous is caught
by neither — only by the comb/onchip KAT. Kept, because it is the clause's
canonical form and arms itself when a fourth primitive is allocated.
3. THE ZP_CONFIG REBUILD WAS THE SURVIVING TAIL OF #119
"No member set is edited" was true, but the wrapper still rebuilt
zp_config*.o out-of-band and re-archived — passing only the ZP overrides and
NOT CONTRACT_DEFINES. Since zp_config.s gates its bare exports on
`.ifndef LIB_NO_BARE_EXPORTS`, that one member re-exported the bare `zp_*`
names every other member was built to suppress. One archive, two
configurations (SPEC §6.2) — and the resurrected names are exactly the #83
ZP collision family the gate exists to prevent. Dormant with one contract
library in the link; live the day a second joins.
Fixed by the sanctioned route: the three overrides move to
CONTRACT_ZP_DEFINES (upstream since nist#104, covered by v0.11.2's staleness
stamp). That retires the rebuild, the member-name discovery case block, the
staging directory AND the re-archive step. The archive we link is now
byte-for-byte the one upstream's make produced, which is what makes §6.1's
"no copying intermediates around" true by construction.
The od65 post-check is kept and strengthened: it verifies the three slots
from the emitted object (canonical spellings only — the bare aliases vanish
under the gate, and a guard that can go vacuous is worse than none) and adds
a new check that the bare zp_ptr2 is NOT re-exported. It reads od65's hex
field directly rather than the parenthesised decimal.
EVIDENCE
All five PRGs byte-identical to the pre-fix build (7a02e213d014,
b574b344cdca, 6acfa0ef9cfd, d59254702819, dcde8eb8f150) — the bare export
was unreferenced, so removing it changes no shipped byte. The comb and
onchip KATs already run at exactly those hashes (6/6 each), so their
evidence carries; re-running identical bytes would prove nothing new.
make package-verify: 31/31 logic, 11/11 artifact, RELEASE ARTIFACTS VERIFIED.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@JC-000

Copy link
Copy Markdown
OwnerAuthor

Thank you — all three findings were correct. Verified each against the v0.11.2 source before acting rather than taking them on trust, and pushed 8e2194c.

1. SHARED_CONSUMES — fixed, you were right

Measured with od65 on the staged archives:

archivePRIMITIVESCONSUMES
lib-p256-verify (REU)$0000$0007
lib-p256-verify-onchip$0000$0005
lib-p256-comb-onchip$0000$0005

The comment now carries that table plus the reason — a deferral switch drops a bit from ownership only, a profile gate drops it from ownership and consumption — and says outright not to "correct" $0005 to $0007 on an onchip archive. No assert changed; all three pass either way since $0005 & ~$0007 = 0. The PR description above is corrected too.

2. Coverage assert — scope note added

You're right that it's a tautology today, and the comment oversold it. It now states plainly that it cannot fire while APP_OWNED = $0007 covers every allocated bit, that the failure it sounds like it catches is actually covered by the PRIMITIVES = 0 assert or by a duplicate-external link error, and — the part that mattered most to get on the page — that the poly_prod rendezvous is caught by neither, only by the comb/onchip KAT. Kept the assert for the reason you give: canonical form, and it arms itself when a fourth primitive lands.

3. zp_config tail — folded in rather than deferred

Confirmed the defect before fixing: the rebuilt zp_config_p256verify.o did export the bare zp_ptr2 while every other member in the same archive suppressed it.

Routing the three overrides through CONTRACT_ZP_DEFINES works exactly as you said, and retired more than the rebuild — the member-name discovery case block, the staging directory and the re-archive step all went with it. The archive we link is now byte-for-byte the one upstream's make produced, which is the version of §6.1 that needs no inspection to believe.

The od65 post-check is kept and strengthened: canonical spellings only (the bare aliases vanish under the gate, and a guard that can go vacuous under a build-tightening flag is worse than none), plus a new check that the bare zp_ptr2 is not re-exported — the exact regression you found, now guarded. It also reads od65's hex field rather than the parenthesised decimal; the first version of that check compared a hex string against a decimal one and failed loudly on a correct build, which is at least the right direction to fail in.

I also fixed the stale header comment you flagged — it claimed we "cannot pass -D overrides" and "build upstream with its defaults", both untrue since the knobs landed.

Evidence for the follow-up

All five PRGs are byte-identical to the pre-fix build (7a02e213d014, b574b344cdca, 6acfa0ef9cfd, d59254702819, dcde8eb8f150) — the bare export was unreferenced, so removing it changes no shipped byte. The comb and onchip KATs already ran at exactly those hashes, so that evidence carries; re-running identical bytes would prove nothing new. make package-verify: 31/31 logic, 11/11 artifact, RELEASE ARTIFACTS VERIFIED, no skips.

So #119 closes without a successor issue. §13/#70 remains open and untouched.

@JC-000

Copy link
Copy Markdown
OwnerAuthor

Re-verified 8e2194c against the reply rather than taking it on trust — all three findings are properly closed.

  • Masks: the new table matches upstream's lib_manifest.s gates exactly (deferral switch → ownership only; profile gate → both masks), and the "do not 'correct' $0005 to $0007" warning is the right guard against the failure mode I was worried about.
  • Coverage assert: the HONEST SCOPE comment is accurate on all three points, and stating that the poly_prod rendezvous is caught only by the comb/onchip KAT is the sentence that will save someone a wrong sense of safety later.
  • zp_config: the linked archive being upstream's artifact byte-for-byte closes the §6.2 one-configuration defect by construction, and the post-check now guards both directions — canonical values landed, bare zp_ptr2 suppressed. Reading od65's hex field rather than the parenthesized decimal is also the right call.

One non-blocking nit on the new member discovery: ls "$LIB_BUILD"/zp_config_*.o | head -1 picks the alphabetically-first ZP object in the build directory, which — when several variants' objects coexist there (REU, onchip and comb are all built from the same libs/nistcurves tree) — may not be the member actually shipped in this profile's archive. The v0.11.2 staleness stamp guarantees every object in the directory carries the same knob string, so the value check can't silently pass on a wrong-config object; the residual gap is only that a variant-gated slot could someday differ between variants' ZP TUs. ar65 t "$UPSTREAM_ARCHIVE" | grep '^zp_config' names the exact member in the archive being linked, and od65 can then read that object from $LIB_BUILD directly — listing is not extraction, so §6.1 stays clean. Take or leave; the current shape is defensible.

Nothing further from my side — #119 closes clean with no successor, and I'll refresh the contract repo's consumers.md row once this merges.

Follow-up nit from the contract-side review of #122, and it was my
regression: the pre-existing code discovered the ZP member with
`ar65 t` on the archive, and when I removed the staging step I replaced
that with `ls "$LIB_BUILD"/zp_config_*.o | head -1`.
All three profiles build from the same libs/nistcurves tree, so several
variants' ZP objects coexist there. Reproduced: after a comb build followed
by a REU build,
ls zp_config_*.o | head -1 -> zp_config_p256comb.o
REU archive actually ships -> zp_config_p256verify.o
so the post-check was reading an object the archive being linked does not
contain. It passed anyway — v0.11.2's staleness stamp guarantees every
object in the directory carries the same knob string, so the values were
right — but a guard that inspects a different artifact than the one shipped
is the wrong shape whatever it happens to return, and a variant-gated slot
could someday differ between variants' ZP TUs.
Now derived from the archive being linked:
ZP_MEMBER="$( ar65 t "$UPSTREAM_ARCHIVE" | grep '^zp_config' )"
with explicit zero-match and multi-match failures rather than a silent
head -1, plus a check that the named member exists in the build dir.
Listing an archive is not extracting it, so §6.1 stays clean.
PRG-neutral, as build tooling should be: all five images byte-identical
(7a02e213d014, b574b344cdca, 6acfa0ef9cfd, d59254702819, dcde8eb8f150),
so the comb and onchip KAT evidence carries unchanged.
make package-verify: 31/31 logic, 11/11 artifact, RELEASE ARTIFACTS VERIFIED.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@JC-000

Copy link
Copy Markdown
OwnerAuthor

Taken, in 6bc6965 — and it was my regression rather than a pre-existing shape. The original code discovered the member with ar65 t on the staged archive; when I removed staging I replaced that with the glob.

Reproduced before fixing, since "may not be the member shipped" deserved confirming rather than assuming. After a comb build followed by a REU build in the same tree:

ls zp_config_*.o | head -1 -> zp_config_p256comb.o
REU archive actually ships -> zp_config_p256verify.o

So the check was reading an object the linked archive does not contain. It passed anyway, exactly for the reason you gave — the staleness stamp means every object in the directory carries the same knob string — but you're right that it's the wrong shape regardless of what it returns.

Now derived from the archive being linked:

ZP_MEMBER="$("$AR65" t "$UPSTREAM_ARCHIVE"| grep '^zp_config')"

with explicit zero-match and multi-match failures instead of a silent head -1, plus a check that the named member is actually present in the build dir. Verified it now selects zp_config_p256verify.o in the precise scenario that previously mis-selected. And as you note, listing an archive is not extracting it, so §6.1 stays clean.

PRG-neutral, as build tooling should be — all five images byte-identical, so the comb and on-chip KAT evidence carries unchanged. make package-verify: 31/31 logic, 11/11 artifact, RELEASE ARTIFACTS VERIFIED.

Thanks for all three rounds — the SHARED_CONSUMES correction in particular was a claim I'd have shipped as fact, and the coverage-assert scope note is the kind of thing that reads as safety when it isn't.

Sign up for freeto 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.

Retire ar65 member surgery in the nistcurves wrappers (SPEC §6.1)

1 participant

@JC-000