did-btcr2-js

ADR 015: Keypair Security Hardening and Noble / Scure Migration

Status: Accepted

Date: 2026-03-20

Commit: 5a9fbe5

Context

@did-btcr2/keypair holds the project’s most security-sensitive primitives: secp256k1 secret keys, the schnorr signing path used by DID-update proofs, and the PSBT signing path used by Bitcoin outputs. Prior to v0.11.0 the package had two distinct classes of problem.

Library-stack concerns:

Security and API concerns (not all visible at the type level, but all live):

The keypair package is too close to the crypto boundary to leave any of these alone.

Options considered

  1. Incremental security fixes, keep tiny-secp256k1. Address the security issues in-place; skip the library migration. Leaves the WASM / bundle-size concerns, and we miss the opportunity to consolidate on audited pure-JS primitives.
  2. Full rewrite: migrate to @noble/curves v2 + @scure/base, apply all security fixes together, break circular dependencies, remove dead code. Everything in one breaking release. Higher risk of introducing new bugs during the rewrite; mitigated by the test expansion (50 to 80 tests, 77% to 90% statement coverage).

Decision

Option 2. The v0.11.0 release ships all of the following as one coordinated change, versioned as a breaking release:

Library stack:

Secret-key hardening (Secp256k1SecretKey):

Keypair hardening (SchnorrKeyPair):

Test expansion:

Consequences

Positive

Negative

Explicitly accepted trade-offs

References