本文へスキップ
ecdsa.com
C

wolfSSL (wolfCrypt)

wolfSSL の組み込み向け TLS と 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 を返します。生形式の署名には、r と s を整数として受け取る wc_ecc_verify_hash_ex を使います。検証の出力は 2 つあります。関数の戻り値は処理を実行できたかどうかを示し、int *res 引数には検証結果が入ります。64 バイトの生形式の署名を wc_ecc_verify_hash に渡すと、戻り値は -171(ECC ASN1 bad key data, invalid input)、検証結果は 0 でした。戻り値だけ、または検証結果だけを確認するコードは、2 つのケースのどちらかを誤って処理します。サンプルでは両方を出力しています。

このビルドでは、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 を書き出します。パッケージが WOLFSSL_DER_TO_PEM を設定しているため、PEM への変換(wc_DerToPem)も使えます。Alpine パッケージはライセンスを GPL-3.0-only と宣言しており、商用ライセンスは wolfSSL Inc. が別途販売しています。ほかのスタックとのエンコーディングの違いは、DER ⇄ 生形式の変換ツールで確認してください。

事実とその根拠となるチェック

以下の内容はドキュメントからの転記ではありません。2026年10月20日に、チェック content/libraries/verify/wolfssl/run.sh がコンテナイメージ alpine:3.24.2 内で wolfSSL (wolfCrypt) 5.9.4 を実行しました。このページの内容はその出力と一致していなければならず、各事実には該当する出力行を示しています。

  • 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
  • ECDSA の nonce

    random

    このビルドには WOLFSSL_ECDSA_DETERMINISTIC_K がないため、nonce はランダムです。

    チェックによる記録
    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

    s を n − s に置き換えた DER 署名も検証を通りました。

    チェックによる記録
    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

    生の 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(P-256 では 121 バイト)を書き出し、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

ライブラリ