4.9 KiB
OpenSpec Change: crypto-spec-conformance
- Change ID: crypto-spec-conformance
- Package:
@suaveplan/crypto - Status: PROPOSED
- Date: 2026-04-26
Summary
Realign the folded openspec/specs/crypto/spec.md with the actual surface of @suaveplan/crypto (the multi-algorithm façade), add a cross-cutting src/crypto.spec-conformance.test.ts, and annotate every requirement with a **Verified by:** line so bun scripts/openspec-conformance.ts @suaveplan/crypto exits 0. Two prior archived change folders (2026-04-19-crypto-primitive-replaceability, 2026-04-19-enterprise-crypto) carry retroactively ticked markers that the conformance script downgrades to info once a *-spec-conformance rectification exists. No public-API changes.
Current state
@suaveplan/crypto is the engine-pluggable façade composing the per-primitive subpackages (crypto-utils, crypto-hash, crypto-curve, crypto-cipher). Its surface is AEAD (3 algorithms), Ed25519 / ECDSA-P256 sign-verify, X25519 agreement, sealed-box, auth-box, constantTimeEqual, zeroize, randomBytes (single CSPRNG callsite), and a CRYPTO_CODES registry. Per-feature unit tests cover the happy paths, AAD authentication, tampered-ciphertext rejection, key/nonce length validation, fast-check round-trip properties, and engine substitution. The conformance gaps are:
- Spec drift. The folded
openspec/specs/crypto/spec.mdwas the originalenterprise-cryptoproposal — it specssha256,sha384,sha512,hmac,hkdf,pbkdf2,argon2idas exports of this façade. After the per-primitive split those primitives moved to@suaveplan/crypto-hash. ThePurposesection is the literal placeholderTBD - created by archiving change enterprise-crypto. Update Purpose after archive.All 13 requirements lack**Verified by:**lines. - Implicit cross-cutting invariants are unpinned. Engine pluggability across all five operation namespaces, the AEAD nonce-is-caller-supplied invariant (no internal randomness in
src/aead/),verifyreturning a boolean (never throwing) on bad signatures, the single-crypto.getRandomValues-callsite property, and the structured-error-no-leak rule for AEAD failures are all stated by the spec but not directly asserted by any test. - Retroactive ticking debt. Archived change folders
2026-04-19-crypto-primitive-replaceability/tasks.mdand2026-04-19-enterprise-crypto/tasks.mdcontainretroactively ticked, which the conformance script flags aserroruntil a*-spec-conformancerectification folder exists.
What changes
- Rewrite
openspec/specs/crypto/spec.mdto reflect the actual façade surface:- Fill the
## Purposesection. - Replace the drifted hash / KDF / argon2id requirements (which now live in
@suaveplan/crypto-hash's spec) with thirteen requirements that match the façade: engine pluggability, AEAD round-trip across three algorithms, AEAD nonce-caller-supplied invariant, AEAD authentication-failure leak rule, Ed25519 / ECDSA-P256 sign-verify withverifyboolean contract, X25519 stability, sealed-box authenticity, auth-box sender authentication, constant-time-equal, zeroize, single CSPRNG callsite, structured-errors-with-stable-registry, and 100% coverage gate. - Add a
**Verified by:**line to every### Requirement:block pointing at concrete*.test.ts::"name"test cases.
- Fill the
- Add
src/crypto.spec-conformance.test.tscovering:- Default-engine wiring across all five namespaces.
- Custom-engine substitution suppresses the default for sign and agree.
- AEAD façade source contains zero byte-source consumption (
grepoversrc/aead/). - AEAD decryption-failure error context is restricted to
{ algorithm, ciphertextLength }. - Ed25519 / ECDSA-P256
verifyreturnsfalse(never throws) on a wrong message. - X25519 agreement is byte-stable across repeated calls.
constantTimeEqualsource contains noreturn/breakinside its compare loop — only an XOR accumulator.zeroizemutates in place (sameUint8Arrayreference).- Exactly one
crypto.getRandomValues(...)callsite insrc/, located insrc/primitives/random-bytes.ts. - Every
CRYPTO_CODESentry is referenced from at least one non-test source file. CRYPTO_CODESis frozen.- Engine type exports compile.
- Rectify retroactive-ticking debt. Creating this
crypto-spec-conformancechange folder downgrades the priorretroactively tickedmarkers in archived task lists fromerrortoinfoper the conformance-script policy.
Impact
- Public API unchanged.
- One new test file (~330 lines, under the 500-line budget).
openspec/specs/crypto/spec.mdrewritten to reflect the actual façade surface; the prior text described primitives that have since moved to@suaveplan/crypto-hash.- Coverage stays at 100/100/100/100; the new tests exercise existing production code paths plus structural source-text invariants.
- No new runtime dependencies.