Библиотека @noble/curves реализует криптографию на эллиптических кривых на чистом TypeScript без зависимостей и несколько раз проходила аудит. Она служит движком для ethers v6, viem и многих инструментов для Bitcoin и Nostr и обычно выручает, когда в WebCrypto нет нужной кривой: в ней есть P-256, P-384, P-521, secp256k1 и кривые Brainpool r1, Ed25519 и Ed448 с вариантами с предварительным хешированием и с контекстом, а также подписи Schnorr по BIP-340.
Настройки по умолчанию у неё строгие. Подпись — 64 байта в компактном формате r‖s, nonce вычисляется по RFC 6979 (проверка воспроизвела тестовый вектор из RFC для P-256), а s всегда нормализуется в нижнюю половину. Проверка столь же строгая: все подписи high-S, созданные node:crypto, были отклонены, все подписи 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 воспроизводит вектор из RFC, только если передать ей SHA-256 сообщения. Поэтому код, обновлённый без изменений, хеширует дважды и расходится со всеми остальными библиотеками; передавайте prehash: false там, где у вас действительно дайджест. Кроме того, версия 1 не нормализовала подписи на P-256, так что подписи, прошедшие проверку в 1.x, в 2.x могут её не пройти.
Ключи принимаются только в виде сырых байтов: 32-байтовый секретный скаляр и открытые ключи в виде точек SEC1, по умолчанию сжатых (33 байта), а по запросу несжатых. SPKI, PKCS#8 и JWK библиотека не читает, поэтому ключи из OpenSSL или JWKS сначала нужно распаковать; с этим помогут конвертер JWK и песочница эллиптических кривых. Постквантового кода в этом пакете нет: тот же автор публикует его отдельно.
Пример показывает два параметра, format и lowS, с которыми noble совместима с библиотеками подписи в стиле OpenSSL, и детерминированный результат её собственной функции подписи. Чтобы вручную сравнить подпись в разных кодировках, воспользуйтесь конвертером DER ⇄ raw; для подписей кошельков есть проверка подписей Ethereum, которая работает на том же коде кривых.