Initial Commit
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
# 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.md` was the original `enterprise-crypto` proposal — it specs `sha256`, `sha384`, `sha512`, `hmac`, `hkdf`, `pbkdf2`, `argon2id` as exports of this façade. After the per-primitive split those primitives moved to `@suaveplan/crypto-hash`. The `Purpose` section is the literal placeholder `TBD - 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/`), `verify` returning 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.md` and `2026-04-19-enterprise-crypto/tasks.md` contain `retroactively ticked`, which the conformance script flags as `error` until a `*-spec-conformance` rectification folder exists.
|
||||
|
||||
## What changes
|
||||
|
||||
1. **Rewrite `openspec/specs/crypto/spec.md`** to reflect the actual façade surface:
|
||||
- Fill the `## Purpose` section.
|
||||
- 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 with `verify` boolean 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.
|
||||
2. **Add `src/crypto.spec-conformance.test.ts`** covering:
|
||||
- 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 (`grep` over `src/aead/`).
|
||||
- AEAD decryption-failure error context is restricted to `{ algorithm, ciphertextLength }`.
|
||||
- Ed25519 / ECDSA-P256 `verify` returns `false` (never throws) on a wrong message.
|
||||
- X25519 agreement is byte-stable across repeated calls.
|
||||
- `constantTimeEqual` source contains no `return` / `break` inside its compare loop — only an XOR accumulator.
|
||||
- `zeroize` mutates in place (same `Uint8Array` reference).
|
||||
- Exactly one `crypto.getRandomValues(...)` callsite in `src/`, located in `src/primitives/random-bytes.ts`.
|
||||
- Every `CRYPTO_CODES` entry is referenced from at least one non-test source file.
|
||||
- `CRYPTO_CODES` is frozen.
|
||||
- Engine type exports compile.
|
||||
3. **Rectify retroactive-ticking debt.** Creating this `crypto-spec-conformance` change folder downgrades the prior `retroactively ticked` markers in archived task lists from `error` to `info` per the conformance-script policy.
|
||||
|
||||
## Impact
|
||||
|
||||
- Public API unchanged.
|
||||
- One new test file (~330 lines, under the 500-line budget).
|
||||
- `openspec/specs/crypto/spec.md` rewritten 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.
|
||||
Reference in New Issue
Block a user