La bibliothèque @noble/curves implémente la cryptographie sur courbes elliptiques en TypeScript pur, sans aucune dépendance, et a été auditée à plusieurs reprises. C’est le moteur d’ethers v6, de viem et de nombreux outils Bitcoin et Nostr, et la réponse habituelle quand WebCrypto ne propose pas une courbe : elle couvre P-256, P-384, P-521, secp256k1 et les courbes Brainpool r1, Ed25519 et Ed448 avec leurs variantes de pré-hachage et de contexte, ainsi que les signatures Schnorr BIP-340.
Ses valeurs par défaut sont strictes. Une signature fait 64 octets de r‖s compact, le nonce suit la RFC 6979 (les essais ont reproduit le vecteur de test P-256 de la RFC) et s est toujours normalisé dans la moitié inférieure. La vérification est tout aussi stricte : chaque signature high-S produite par node:crypto a été rejetée, chaque signature low-S acceptée. Les signatures issues d’OpenSSL, de Java, de Go ou de WebCrypto sont high-S environ une fois sur deux : leur vérification nécessite donc lowS: false, et une entrée DER nécessite format: "der", sans quoi un bloc DER de 70 octets lève une erreur de longueur.
La version 2 a changé le sens du premier argument. En 1.x, sign() et verify() prenaient un condensat que vous aviez calculé ; en 2.x, elles hachent elles-mêmes le message avec la fonction de hachage de la courbe, et les essais ont confirmé que la 1.9.7 ne reproduit le vecteur de la RFC que si on lui fournit le SHA-256 du message. Le code mis à jour sans modification hache donc deux fois et échoue face à toutes les autres bibliothèques ; passez prehash: false là où vous détenez réellement un condensat. De plus, la version 1 ne normalisait pas les signatures P-256, si bien que des signatures qui passaient la vérification en 1.x peuvent échouer en 2.x.
Les clés sont uniquement des octets bruts : un scalaire secret de 32 octets, et des clés publiques sous forme de points SEC1, compressés (33 octets) par défaut, non compressés sur demande. SPKI, PKCS#8 et JWK ne sont pas lus, si bien que les clés provenant d’OpenSSL ou d’un JWKS doivent d’abord être extraites ; le convertisseur JWK et le bac à sable des courbes elliptiques y aident. Ce paquet ne contient aucun code post-quantique : le même auteur le publie séparément.
L’exemple montre les deux options (format et lowS) qui rendent noble interopérable avec un signataire de type OpenSSL, ainsi que la sortie déterministe de son propre signataire. Pour comparer manuellement une signature dans ses différents encodages, utilisez le convertisseur DER ⇄ brut ; pour les signatures de portefeuille, le vérificateur de signatures Ethereum s’appuie sur le même code de courbes.