Проект RustCrypto разделяет ECDSA на общий крейт ecdsa и крейты для отдельных кривых: p256, p384, p521, k256 для secp256k1 и крейты Brainpool, и все они реализуют трейты крейта signature (Signer, Verifier, PrehashSigner). Они написаны на чистом Rust без зависимостей на C, поэтому их обычно выбирают для WebAssembly и встраиваемых систем. Для проверки использовались ecdsa 0.17.0 и p256, p384 и k256 версии 0.14.0.
Подписи детерминированы: подпись P-256 тестового сообщения из RFC 6979 побайтово совпала с тестовым вектором из RFC. Тип Signature — это 64-байтовая форма raw r‖s; для DER есть явные to_der() и from_der(), а разбор подписи не в той форме возвращает ошибку ещё до проверки. Трейт Signer хеширует сообщение хеш-функцией кривой по умолчанию (SHA-256 для P-256); PrehashSigner::sign_prehash принимает дайджест и для хеша SHA-256 сообщения выдал идентичную подпись.
Обработка low-S зависит от кривой, и в этом ловушка, когда одна кодовая база работает с обоими семействами кривых. Крейты кривых NIST оставляют s таким, каким оно получилось при вычислении (29 из 64 подписей P-256 оказались high-S), а их код проверки принимает s из обеих половин диапазона. k256 нормализует s при подписании, а его код проверки отклонил зеркальную форму high-S верной подписи, что соответствует правилам Bitcoin. Поэтому подпись secp256k1, созданная OpenSSL, Java или облачным KMS, примерно в половине случаев не проходит проверку в k256; сначала вызовите для неё normalize_s(), как пример показывает для P-256.
Ключи загружаются из SPKI и PKCS#8 (PEM и DER, с feature-флагами pem и pkcs8), из точек SEC1 в любой форме, из закрытых ключей SEC1 и из скаляров в формате raw. Ed25519 находится в отдельном крейте ed25519-dalek, а постквантовых алгоритмов здесь нет; если для Rust нужны примитивы, сертифицированные по FIPS, или постквантовые примитивы, смотрите aws-lc-rs.
Поскольку подписание детерминированное, изменившаяся подпись в тесте здесь действительно указывает на регрессию. Сравнивайте результаты с другими библиотеками с помощью тестовых векторов и конвертера DER ⇄ raw.