@noble/curves は、楕円曲線暗号を依存関係のない純粋な TypeScript で実装したライブラリで、これまでに複数回の監査を受けています。ethers v6、viem、多くの Bitcoin・Nostr ツールの内部で使われており、WebCrypto に必要な曲線がないときの定番の選択肢です。P-256、P-384、P-521、secp256k1、Brainpool の r1 曲線、事前ハッシュ版とコンテキスト版を含む Ed25519 と Ed448、BIP-340 の Schnorr 署名に対応しています。
デフォルトはどれも厳格です。署名は 64 バイトのコンパクトな r‖s で、nonce は RFC 6979 に従い(チェックでは RFC の P-256 のテストベクトルを再現できました)、s は常に下半分に正規化されます。検証も同様に厳格で、node:crypto が生成した high-S の署名はすべて拒否され、low-S の署名はすべて受け入れられました。OpenSSL、Java、Go、WebCrypto の署名は約半分の確率で high-S になるため、それらを検証するには lowS: false が必要です。また、DER の入力には format: "der" が必要で、これがないと 70 バイトの DER データは長さのエラーをスローします。
バージョン 2 では最初の引数の意味が変わりました。1.x の sign() と verify() は呼び出し側で計算したハッシュ値を受け取っていましたが、2.x では曲線に対応するハッシュ関数でメッセージを自らハッシュします。チェックでは、1.9.7 がメッセージの SHA-256 を渡したときにだけ RFC のベクトルを再現することを確認しました。そのため、コードを変更せずにアップグレードするとハッシュが二重にかかり、他のどのライブラリとの間でも失敗します。本当にダイジェストを持っている箇所では prehash: false を渡してください。また、バージョン 1 は P-256 の署名を正規化していなかったため、1.x で検証を通った署名が 2.x では失敗することがあります。
鍵は生のバイト列としてのみ扱えます。秘密鍵は 32 バイトの秘密スカラーで、公開鍵は SEC1 の点です(デフォルトは 33 バイトの圧縮形式で、指定すれば非圧縮形式)。SPKI、PKCS#8、JWK は読み込めないため、OpenSSL や JWKS から得た鍵は先に展開する必要があります。それには JWK 変換ツールと楕円曲線プレイグラウンドが役立ちます。このパッケージにポスト量子暗号のコードはなく、同じ作者が別のパッケージとして公開しています。
サンプルでは、noble を OpenSSL 方式の署名者と相互運用させる 2 つのオプション(format と lowS)と、noble 自身の署名による決定的な出力を示しています。エンコーディングの異なる署名を手作業で比較するには DER ⇄ 生形式の変換ツールを使ってください。ウォレットの署名には Ethereum 署名検証ツールを使えます。このツールも同じ曲線のコードで動作しています。