Перейти к содержимому
ecdsa.com
C

wolfSSL (wolfCrypt)

Встраиваемая TLS-библиотека wolfSSL с криптобиблиотекой wolfCrypt: ECDSA в DER по дайджесту, который вы передаёте сами, функция проверки, у которой код возврата и вердикт разделены, и набор возможностей, полностью зависящий от параметров сборки.
Лицензия
GPL-3.0-only
Проверенная версия
5.9.4 ·
Исходный код
github.com/wolfSSL/wolfssl
Документация
www.wolfssl.com/documentation/manuals/wolfssl/

Совместимость вкратце

ECDSAEdDSAПостквантовая криптография

Кривые ECDSA
P-224P-256P-384P-521
EdDSA
Ed25519

wolfSSL рассчитана на встраиваемые системы и развёртывания с сертификацией FIPS, и почти всё в ней задаётся параметрами компиляции: кривые, варианты EdDSA, детерминированные nonce, постквантовые алгоритмы и поддержка PEM появляются и исчезают вместе с флагами ./configure. Факты на этой странице относятся к пакету wolfSSL 5.9.4 из Alpine 3.24.2, собранному с HAVE_ECC, HAVE_ED25519, HAVE_CURVE25519 и WOLFSSL_HAVE_MLKEM, но без HAVE_ED448, HAVE_DILITHIUM, кривых Koblitz и Brainpool и без WOLFSSL_ECDSA_DETERMINISTIC_K. В собственной сборке любой из этих пунктов может отличаться.

wc_ecc_sign_hash подписывает вычисленный вами дайджест и возвращает DER; wc_ecc_verify_hash_ex принимает r и s как целые числа для подписей в формате raw. У проверки два результата: код возврата функции сообщает, смогла ли она выполниться, а аргумент int *res содержит вердикт. Вызов wc_ecc_verify_hash с подписью raw длиной 64 байта вернул -171 (ECC ASN1 bad key data, invalid input) с вердиктом 0; код, который проверяет только код возврата или только вердикт, неправильно обработает один из двух случаев. Пример выводит оба значения.

В этой сборке nonce случайные (для детерминированной подписи по RFC 6979 нужен WOLFSSL_ECDSA_DETERMINISTIC_K), s не нормализуется, а подписи с high-S проходят проверку. Поддерживаются кривые от P-224 до P-521; secp256k1 и Brainpool отсутствуют, если их не включить. Ed25519 работает, инкапсуляция и декапсуляция ML-KEM-768 через wc_MlKemKey_* прошли успешно; ML-DSA (Dilithium) в эту сборку не входит.

Ключи передаются в DER: wc_EccPublicKeyToDer записывает SPKI, а wc_EccKeyToDer — SEC1 ECPrivateKey; преобразование в PEM (wc_DerToPem) доступно, потому что пакет задаёт WOLFSSL_DER_TO_PEM. В пакете Alpine указана лицензия GPL-3.0-only; wolfSSL Inc. отдельно продаёт коммерческие лицензии. Сверяйте кодировки с другими стеками с помощью конвертера DER ⇄ raw.

Факты и проверки, на которых они основаны

Ничего из приведённого ниже не скопировано из документации. 20 октября 2026 г. проверка content/libraries/verify/wolfssl/run.sh запустила wolfSSL (wolfCrypt) 5.9.4 в образе контейнера alpine:3.24.2; содержимое страницы должно совпадать с выводом проверки, а у каждого факта приведены соответствующие строки вывода.

  • Кодировка подписи ECDSA

    der

    wc_ecc_sign_hash возвращает DER; wc_ecc_verify_hash_ex проверяет r и s, переданные как целые числа.

    Что записала проверка
    fact ecdsa-signature-encoding = der
    evidence ecdsa-signature-encoding: wc_ecc_verify_hash_ex with r and s as integers verifies: 1
  • Nonce в ECDSA

    random

    Случайный nonce: в этой сборке нет WOLFSSL_ECDSA_DETERMINISTIC_K.

    Что записала проверка
    fact ecdsa-nonce = random
    evidence ecdsa-nonce: this build lacks WOLFSSL_ECDSA_DETERMINISTIC_K, so RFC 6979 signing is not available
  • Low-S при подписи

    either

    s не нормализуется: среди 64 подписей встретились значения high-S.

    Что записала проверка
    fact ecdsa-low-s-sign = either
  • High-S при проверке

    accepts-high-s

    Подпись в DER, в которой s заменили на n − s, прошла проверку.

    Что записала проверка
    fact ecdsa-low-s-verify = accepts-high-s
  • Что хеширует вызов подписи

    takes-digest

    wc_ecc_sign_hash и wc_ecc_verify_hash работают с дайджестом, который вычислила вызывающая сторона.

    Что записала проверка
    fact ecdsa-prehash = takes-digest
    evidence ecdsa-prehash: wc_ecc_sign_hash and wc_ecc_verify_hash take a digest the caller computed
  • Некорректная подпись ECDSA

    returns-error

    С подписью в формате raw r‖s функция wc_ecc_verify_hash вернула -171 (ECC ASN1 bad key data, invalid input) и вердикт 0.

    Что записала проверка
    fact ecdsa-malformed-signature = returns-error
    evidence ecdsa-malformed-signature: wc_ecc_verify_hash on raw r||s: return code -171 (ECC ASN1 bad key data, invalid input), result 0
  • Кривые ECDSA

    P-224P-256P-384P-521

    В этой сборке P-224, P-256, P-384 и P-521; генерация ключей secp256k1 и brainpoolP256r1 завершилась ошибкой.

    Что записала проверка
    fact ecdsa-curves = P-224, P-256, P-384, P-521
  • EdDSA

    Ed25519

    Ed25519; HAVE_ED448 в этой сборке не задан.

    Что записала проверка
    fact eddsa = Ed25519
    evidence eddsa: HAVE_ED448 is not set in this build
  • Постквантовые алгоритмы

    ML-KEM

    ML-KEM-768 прошёл полный цикл инкапсуляции и декапсуляции через wc_MlKemKey_*; HAVE_DILITHIUM (ML-DSA) в этой сборке не задан.

    Что записала проверка
    fact pqc = ML-KEM
    evidence pqc: HAVE_DILITHIUM (ML-DSA) is not set in this build
  • Форматы открытых ключей

    spki-der

    wc_EccPublicKeyToDer и wc_EccPublicKeyDecode работают с SPKI DER, и декодированный ключ успешно проверил подпись.

    Что записала проверка
    fact public-key-formats = spki-der
  • Форматы закрытых ключей

    sec1-der

    wc_EccKeyToDer записывает SEC1 ECPrivateKey (121 байт для P-256), который wc_EccPrivateKeyDecode читает обратно.

    Что записала проверка
    fact private-key-formats = sec1-der
    evidence private-key-formats: wc_EccKeyToDer writes a SEC1 ECPrivateKey of 121 bytes
    evidence private-key-formats: WOLFSSL_DER_TO_PEM is set in this build

Использование

Вычислите хеш, подпишите на P-256 и проверьте подпись, выводя и код возврата, и вердикт проверки.
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/sha256.h>
#include <stdio.h>

int main(void) {
    WC_RNG rng;
    ecc_key key;
    unsigned char digest[32], sig[ECC_MAX_SIG_SIZE];
    word32 sig_len = sizeof sig;
    int verified = 0;
    const unsigned char msg[] = "order #1042 approved";

    wc_InitRng(&rng);
    wc_ecc_init(&key);
    wc_ecc_make_key_ex(&rng, 32, &key, ECC_SECP256R1);

    /* wolfCrypt signs a digest you computed and returns DER. */
    wc_Sha256Hash(msg, sizeof msg - 1, digest);
    wc_ecc_sign_hash(digest, sizeof digest, sig, &sig_len, &rng, &key);
    /* The return code says whether verification ran; "verified" holds the verdict. */
    int rc = wc_ecc_verify_hash(sig, sig_len, digest, sizeof digest, &verified, &key);
    printf("rc: %d, verified: %d, DER starts with 0x%02x\n", rc, verified, sig[0]);

    wc_ecc_free(&key);
    wc_FreeRng(&rng);
    return 0;
}

Тестовый стенд для фрагментов кода запускает каждый пример без изменений в образе контейнера alpine:3.24.2, и запуск завершается ошибкой, если вывод не совпадает.

Подготовка
apk add --no-cache -q build-base wolfssl-dev=5.9.4-r0 >/dev/null
Команда
cc -o usage usage.c -lwolfssl && ./usage
Вывод должен совпадать (регулярное выражение)
rc: 0, verified: 1, DER starts with 0x30

Библиотеки