本文へスキップ
ecdsa.com

ML-DSA と SLH-DSA の比較|格子署名かハッシュベース署名か

ML-DSA は汎用のポスト量子署名で、署名はキロバイト単位、署名処理は高速です。SLH-DSA は安全性をハッシュ関数だけに依拠しており、その代わりに署名が 8〜50 KB と大きく、署名処理も低速です。

ML-DSA と SLH-DSA のどちらを使うかは、NIST が標準化したポスト量子署名の中での主要な選択肢であり、どちらも 2024年8月13日に公開されました。ML-DSA(FIPS 204、CRYSTALS-Dilithium に由来)は構造化格子に依拠し、SLH-DSA(FIPS 205、SPHINCS+ に由来)はハッシュ関数の安全性だけに依拠します。サイズと速度の特性が大きく異なるため、ほとんどのシステムは ML-DSA を使い、保守的な前提がコストに見合う場面で SLH-DSA を使うことになるでしょう。

比較表

ML-DSA(FIPS 204)SLH-DSA(FIPS 205)
安全性の前提Module-LWE と Module-SIS の格子問題SHA-2 または SHAKE の性質のみ
パラメーターセットML-DSA-44、-65、-8712 セット:SHA2 または SHAKE × 128/192/256 × s(small)または f(fast)
セキュリティカテゴリ2、3、51、3、5
公開鍵1,312 / 1,952 / 2,592 バイト32 / 48 / 64 バイト
署名2,420 / 3,309 / 4,627 バイト7,856 バイト(128s)〜49,856 バイト(256f)
秘密鍵展開形式で 2,560〜4,896 バイト、または 32 バイトのシード64 / 96 / 128 バイト
毎秒の署名回数(OpenSSL 3.6.5)約 3,900(44)、2,400(65)、2,050(87)約 7(SHA2-128s)、144(SHA2-128f)、3.5(SHA2-192s)
毎秒の検証回数約 20,800(44)、13,600(65)、8,500(87)約 7,400(SHA2-128s)、2,400(SHA2-128f)
毎秒の鍵生成回数約 22,000(44)約 55(128s)、3,400(128f)
署名時の乱数デフォルトはヘッジ付き、決定的なバリアントも可デフォルトはヘッジ付き、決定的なバリアントも可
コンテキスト文字列最大 255 バイト最大 255 バイト
事前ハッシュ版HashML-DSA(§5.4)HashSLH-DSA(§10.2.2)
X.509RFC 9881(id-ml-dsa-44 = 2.16.840.1.101.3.4.3.17 …)RFC 9909(id-slh-dsa-sha2-128s = …3.4.3.20 …)

速度は Apple M4 Max の 1 コアで openssl speed を使って計測しました。OpenSSL の ML-DSA はポータブルな C 実装で、最適化された実装では署名が数倍高速になります。

安全性の前提

ML-DSA は、Fiat–Shamir with Aborts に基づく格子ベースの署名方式です。安全性は Module-LWE(加群上の誤差付き学習)問題と Module-SIS(加群上の短整数解)問題に基づいています。これらの問題は 20 年ほど研究され、古典攻撃と量子攻撃のどちらにも耐えてきましたが、格子基底簡約の手法が進歩するにつれて、具体的な安全性の見積もりは今も変動しています。NIST は、それらの見積もりに対して余裕を持たせたパラメーターセットを選びました。

SLH-DSA は、ハイパーツリー状に配置したワンタイム署名とフュータイム署名(いずれもハッシュベース署名)から署名を構成します。SHA-256 や SHAKE256 が原像計算困難性とそれに関連する性質を保っている限り、SLH-DSA は安全です。攻撃の対象となる代数的な構造がないからです。そのため SLH-DSA は NIST が標準化した中で最も保守的な署名であり、格子暗号に対する攻撃に飛躍的な進展があった場合の自然な備えになります。ステートフルなハッシュベース署名方式である LMS や XMSS とは異なり、状態を保持する必要はなく、各鍵で最大 2⁶⁴ 個のメッセージに署名できます。

実際のサイズと速度

次のスクリプトは、OpenSSL 3.6.5 を使い、各アルゴリズムで同じメッセージに署名します。

OpenSSL 3.6:ポスト量子署名と従来の署名のサイズ
#!/bin/sh
dir=$(mktemp -d)
cd "$dir" || exit 1
printf 'firmware-2026.10.bin digest' > msg
for alg in ML-DSA-44 ML-DSA-65 SLH-DSA-SHA2-128s SLH-DSA-SHA2-128f ED25519; do
  openssl genpkey -algorithm "$alg" -out key.pem 2>/dev/null
  openssl pkeyutl -sign -rawin -inkey key.pem -in msg -out sig.bin 2>/dev/null
  openssl pkey -in key.pem -pubout -outform DER -out pub.der 2>/dev/null
  openssl pkey -in key.pem -pubout -out pub.pem 2>/dev/null
  if openssl pkeyutl -verify -rawin -pubin -inkey pub.pem -in msg -sigfile sig.bin >/dev/null 2>&1; then ok=yes; else ok=no; fi
  printf '%-18s public key (SPKI DER) %5s bytes, signature %6s bytes, verifies: %s\n' "$alg" \
    "$(wc -c < pub.der | tr -d ' ')" "$(wc -c < sig.bin | tr -d ' ')" "$ok"
done
cd / && rm -rf "$dir"
出力
ML-DSA-44          public key (SPKI DER)  1334 bytes, signature   2420 bytes, verifies: yes
ML-DSA-65          public key (SPKI DER)  1974 bytes, signature   3309 bytes, verifies: yes
SLH-DSA-SHA2-128s  public key (SPKI DER)    50 bytes, signature   7856 bytes, verifies: yes
SLH-DSA-SHA2-128f  public key (SPKI DER)    50 bytes, signature  17088 bytes, verifies: yes
ED25519            public key (SPKI DER)    44 bytes, signature     64 bytes, verifies: yes

両者の特性は正反対です。ML-DSA は公開鍵と署名がキロバイト単位で、毎秒数千回の署名ができます。SLH-DSA は公開鍵がごく小さい(Ed25519 と同程度)一方で署名は 8〜50 KB あり、小さい s のセットでは、このマシンで署名ごとに約 137 ms かかります(f のセットは、署名サイズが倍になる代わりに署名が約 20 倍速くなります)。検証はどちらも高速です。証明書チェーンや TLS ハンドシェイクでは ML-DSA は実用的ですが、SLH-DSA は実用的ではありません。一方、リリースのたびに一度だけ署名し、起動のたびに検証するファームウェアイメージでは、SLH-DSA のコストは問題にならず、ごく小さな公開鍵はブート ROM に収まります。

運用上の詳細

  • ヘッジ付き署名:どちらの標準も、デフォルトでは新しい乱数と鍵から導出した値を混ぜ合わせ、乱数生成器を持たないプラットフォーム向けに決定的なバリアントも認めています。検証者には両者の違いを区別できません。
  • コンテキスト:どちらも最大 255 バイトのコンテキスト文字列をすべての署名に結び付けます。プロトコルはこれを使って用途を分離すべきです。
  • 通常版(pure)と事前ハッシュ版:HashML-DSA と HashSLH-DSA は、ハッシュ関数の OID を結び付けたうえでダイジェストに署名します。これらは別々の OID を持つ別のアルゴリズムであり、FIPS 204 は鍵をどちらか一方の方式だけに使うことを推奨しています。
  • 秘密鍵の形式:ML-DSA の鍵は 32 バイトのシードとして保存でき、RFC 9881 は seed または both のエンコーディングでこれを認めています。一方が展開済みの鍵を想定していると、相互運用の問題が起こります。
  • ハードウェアと FIPS 認証:ML-DSA と SLH-DSA を搭載した認証済みモジュールは 2024年以降に登場しています。対応する正確なパラメーターセットは、モジュールの証明書で確認してください。

どちらを選ぶべきか

  • プライベート PKI、内部の mTLS、文書署名とコード署名:ML-DSA-65(または 44)を使います。
  • ファームウェア、セキュアブート、ハードウェアの信頼の基点:SLH-DSA-128s または 192s を使います。署名者の状態を管理できるなら、CNSA 2.0 がこの用途に義務付けているステートフルな LMS や XMSS も使えます。
  • 数十年にわたって使う長期アーカイブとルート証明書:SLH-DSA を使います。ML-DSA と併用して二重署名にすることも考えられます。
  • 大量の署名(トークン、トランザクション、ログ):ML-DSA を使います。SLH-DSA では処理が追いつきません。
  • 帯域の限られたプロトコル:どちらも小さくはありません。現時点で標準化済みの選択肢として最も小さいのは ML-DSA-44 で、FN-DSA(FIPS 206 ドラフト)はさらに小さいサイズを目指しています。
  • 公開 WebPKI の TLS:現時点ではどちらもブラウザーに受け入れられていません。移行の全体像は ML-DSA と ECDSA の比較を参照してください。

移行時の注意点

  1. 署名の用途を有効期間と量で棚卸しする:長期間使われ、署名の頻度が低いアーティファクトは SLH-DSA の候補で、それ以外はすべて ML-DSA です。
  2. 最終版の標準を実装したライブラリのバージョンを選ぶ:OpenSSL 3.5 以降(2025年4月)、Java 版 Bouncy Castle 1.79 以降(標準化された秘密鍵のエンコーディングには 1.81 以降)、ML-DSA には Go 1.27 の crypto/mldsa を使います。標準化前の Dilithium や SPHINCS+ の出力とは互換性がありません。
  3. サイズを考慮して計画する:証明書、トークン、署名のフィールドの上限を引き上げます。ML-DSA-65 の証明書は約 5.5 KB(姉妹編の比較記事を参照)で、SLH-DSA の署名は一般的なヘッダーやレコードの上限を超えることがあります。
  4. 移行期間中はハイブリッドを検討する:ML-DSA と ECDSA または EdDSA を組み合わせた複合署名の証明書(IETF のドラフト)や二重署名を使えば、従来の検証者も引き続き動作します。
  5. コンテキスト文字列とバリアント(通常版か事前ハッシュ版か)をプロトコル仕様で固定します。そうすれば、すべての実装で設定が一致します。

参考資料

すべての比較