104 lines
4.0 KiB
Markdown
104 lines
4.0 KiB
Markdown
# `@suaveplan/crypto-curve` — Add P-384 (`secp384r1`) and P-521 (`secp521r1`) primitives
|
|
|
|
**Package**: `@suaveplan/crypto-curve` (extension)
|
|
**Status**: PROPOSED
|
|
**Type**: capability-extension
|
|
**Date**: 2026-05-10
|
|
**Tier**: universal
|
|
|
|
## Why
|
|
|
|
`@suaveplan/cbor` ships RFC 9052 COSE_Sign1 verify but the ES384 / ES512
|
|
algorithm branches throw `CborError(UNEXPECTED_TYPE)` with the message
|
|
*"not implemented in @suaveplan/crypto-curve yet"* because the curve
|
|
primitives were not previously exposed. Downstream consumers (WebAuthn
|
|
attestation, federation tokens, FIDO2 device certificates) need both
|
|
algorithms to interoperate with mainstream issuers — Apple's WebAuthn
|
|
attestation, in particular, signs with ES384 in some configurations.
|
|
|
|
`@noble/curves@1.9.7` (already installed across the workspace) exposes
|
|
`p384` and `p521` with the same surface contract as `p256`. The work is
|
|
purely additive — mirroring the existing `p256` per-primitive layout for
|
|
two more curves and threading them through to the COSE verifier.
|
|
|
|
## What changes
|
|
|
|
### New primitives in `@suaveplan/crypto-curve`
|
|
|
|
#### P-384
|
|
|
|
- ADDED: `primitives/p384/p384.ts` — re-exports the select layer.
|
|
- ADDED: `primitives/p384/p384.select/p384.select.ts` — selector pinned
|
|
to the noble implementation (generated forwarder, mirroring p256).
|
|
- ADDED: `primitives/p384/impl/p384.noble/p384.noble.ts` — noble-backed
|
|
`getPublicKey`, `sign`, `verify`, `randomPrivateKey`.
|
|
- ADDED: `primitives/p384/impl/p384.native/p384.native.ts` —
|
|
`PrimitiveNotImplemented` stubs matching the p256 native pattern.
|
|
|
|
#### P-521
|
|
|
|
- ADDED: `primitives/p521/p521.ts` and full mirror of the p384 layout
|
|
(`p521.select`, `impl/p521.noble`, `impl/p521.native`).
|
|
|
|
#### Barrel + subpath exports
|
|
|
|
- ADDED: `export * as p384 from "./primitives/p384/p384.js"` to root barrel.
|
|
- ADDED: `export * as p521 from "./primitives/p521/p521.js"` to root barrel.
|
|
- ADDED: `./p384` and `./p521` subpath exports in `package.json`.
|
|
- ADDED: corresponding entries in `vite.config.ts` external list (so
|
|
consumers can tree-shake to the individual primitive).
|
|
|
|
### COSE wiring in `@suaveplan/cbor`
|
|
|
|
- MODIFIED: `verifyCoseSign1` switch — `ES384` and `ES512` branches call
|
|
`p384.verify(sig, sha384(tbs), pk)` and `p521.verify(sig, sha512(tbs), pk)`
|
|
respectively (replacing the `UNEXPECTED_TYPE` placeholder throws).
|
|
- MODIFIED: `ec2ToCompressedPoint` — generalised to accept coordinate
|
|
length (32 / 48 / 66) so the same helper compresses P-256 / P-384 / P-521.
|
|
|
|
### Dependencies
|
|
|
|
No new dependencies. `@noble/curves@1.9.7` is the catalog-pinned version
|
|
that ships both `p384` and `p521` subpath exports.
|
|
|
|
## Out of scope
|
|
|
|
- WebCrypto-native impls — the existing `p256.native` stub pattern
|
|
(`PrimitiveNotImplemented`) is preserved for both new curves; an opt-in
|
|
WebCrypto path lands in a separate change when needed.
|
|
- COSE Sign1 / Mac0 / Encrypt0 surfaces beyond the alg switch — already
|
|
wired generically and need no changes.
|
|
|
|
## Source mapping
|
|
|
|
| Requirement | Source | Notes |
|
|
|---|---|---|
|
|
| P-384 ECDSA | FIPS 186-4 §6 + NIST SP 800-186 | `@noble/curves/p384` |
|
|
| P-521 ECDSA | FIPS 186-4 §6 + NIST SP 800-186 | `@noble/curves/p521` |
|
|
| COSE ES384 / ES512 | RFC 9053 §2.1 | Already mapped in `alg-map.ts` |
|
|
| Per-primitive selector layout | Existing crypto-curve convention | mirrors p256 |
|
|
|
|
## Verification approach
|
|
|
|
- `packages/crypto/crypto-curve/src/primitives/p384/p384.test.ts` — noble
|
|
- native impl: sign / verify round-trip, signature length, tampered-sig
|
|
rejection, native `PrimitiveNotImplemented` throw.
|
|
- `packages/crypto/crypto-curve/src/primitives/p521/p521.test.ts` — same.
|
|
- `packages/vault/cbor/src/cose/sign1.test.ts` — extend to cover ES384
|
|
and ES512 round-trip via the new primitives.
|
|
|
|
## Migration impact
|
|
|
|
Additive. No existing consumers break — the deferred branches in cbor
|
|
were already throwing.
|
|
|
|
## Impact
|
|
|
|
### Affected dependents
|
|
|
|
`@suaveplan/cbor` — ES384 / ES512 paths become operational; previously
|
|
threw `UNEXPECTED_TYPE`.
|
|
|
|
For all other packages: no behavioural change. The new primitives are
|
|
opt-in subpath imports.
|