4.0 KiB
@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-backedgetPublicKey,sign,verify,randomPrivateKey. - ADDED:
primitives/p384/impl/p384.native/p384.native.ts—PrimitiveNotImplementedstubs matching the p256 native pattern.
P-521
- ADDED:
primitives/p521/p521.tsand 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:
./p384and./p521subpath exports inpackage.json. - ADDED: corresponding entries in
vite.config.tsexternal list (so consumers can tree-shake to the individual primitive).
COSE wiring in @suaveplan/cbor
- MODIFIED:
verifyCoseSign1switch —ES384andES512branches callp384.verify(sig, sha384(tbs), pk)andp521.verify(sig, sha512(tbs), pk)respectively (replacing theUNEXPECTED_TYPEplaceholder 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.nativestub 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
PrimitiveNotImplementedthrow.
- native impl: sign / verify round-trip, signature length, tampered-sig
rejection, native
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.