Files
suaveplan/openspec/archive/2026-04-19-crypto-primitive-replaceability/specs/crypto-hash/spec.md
2026-05-27 23:29:53 +01:00

71 lines
4.0 KiB
Markdown

## MODIFIED Requirements
### Requirement: Package identity
`@suaveplan/hash` SHALL be renamed to `@suaveplan/crypto-hash` to share the `crypto-*` prefix with the `crypto-curve`, `crypto-cipher`, and `crypto-utils` sibling packages. Every in-tree import of `@suaveplan/hash` SHALL be updated in the same change.
#### Scenario: Package name updated
- **WHEN** `packages/universal/crypto-hash/package.json` is inspected
- **THEN** `name` is `@suaveplan/crypto-hash`
- **AND** no other workspace `package.json` lists `@suaveplan/hash` as a dependency
- **AND** no source file in the repo contains the string `"@suaveplan/hash"` as an import specifier
### Requirement: Per-primitive replaceability layout
Every hash, MAC, and KDF primitive in `@suaveplan/crypto-hash` SHALL live under `src/primitives/<id>/` with both a vendor-forked `noble` implementation and a `native` implementation slot, with the active implementation selected per-primitive at build time via the repo-root `crypto.config.ts`.
#### Scenario: Every primitive has both impl files
- **WHEN** the package is inspected
- **THEN** every primitive id — `sha256`, `sha384`, `sha512`, `hmac`, `hkdf`, `pbkdf2`, `argon2id` — has both `src/primitives/<id>/impl/<id>.noble.ts` and `src/primitives/<id>/impl/<id>.native.ts`
- **AND** the `native.ts` file is either a working implementation or a stub that throws `PrimitiveNotImplemented('<id>')`
#### Scenario: Selection driven by crypto.config.ts
- **WHEN** the root `crypto.config.ts` maps `<id>` to `'noble'` or `'native'`
- **THEN** `src/primitives/<id>/<id>.select.ts` is regenerated to re-export from the chosen impl
- **AND** the build fails if any `*.select.ts` was hand-edited (generated banner check)
### Requirement: Shared test vectors and differential equivalence
Every primitive SHALL have an `<id>.vectors.ts` file containing RFC / NIST / Wycheproof known-answer vectors, executed against every present implementation with cross-impl equivalence asserted.
#### Scenario: KATs pass on every impl
- **WHEN** `bunx turbo test --filter=@suaveplan/crypto-hash` runs
- **THEN** each primitive's vector suite runs against its `noble` and `native` impls
- **AND** native impls that throw `PrimitiveNotImplemented` are reported as `pending`, not failing
#### Scenario: Cross-impl equivalence
- **WHEN** a primitive has both a working `noble` and `native` impl
- **THEN** the test suite executes a differential-equivalence check on the shared vectors
- **AND** any byte-level divergence fails the test
### Requirement: Public API stability
The public API surface of `@suaveplan/crypto-hash` SHALL be identical to the surface that `@suaveplan/hash` exposed at the point of rename. All subpath exports (`./hash`, `./mac`, `./kdf`, `./encoding`, `./errors`) remain available with identical signatures.
#### Scenario: Subpath exports preserved
- **WHEN** a consumer imports from any subpath previously exposed by `@suaveplan/hash`
- **THEN** the exported functions have identical signatures and behaviour as before the rename
## ADDED Requirements
### Requirement: CI gate for flipping default to native
A primitive's default SHALL NOT be changed from `'noble'` to `'native'` in `crypto.config.ts` unless the flip PR demonstrates:
1. Full KAT suite passes on the native impl.
2. Nightly differential fuzz (≥ 1M inputs over 7 days) has zero mismatches.
3. Constant-time lint passes and `dudect` statistical test shows no measurable secret-dependent timing.
4. For `hmac` and any primitive in the **dangerous tier** (defined in `crypto-curve` and `crypto-cipher` specs), a third-party audit sign-off is attached to the PR, referencing the exact commit SHA of the native impl.
#### Scenario: Flip PR blocked without evidence
- **WHEN** a PR modifies `crypto.config.ts` to change a `crypto-hash` entry from `'noble'` to `'native'`
- **THEN** CI requires the flip PR template with links to the KAT run, 7-day fuzz history, timing report, and (for HMAC) audit document
- **AND** the merge is blocked if any evidence link is missing or red