ML-KEM(Kyber)とFIPS 203
NISTが最初に標準化した耐量子鍵カプセル化ML-KEMを、内部まで正確に把握できます。MLWEの土台からK-PKEとFOの二層構造、512/768/1024の使い分け、TLSハイブリッドまで実装目線で押さえられます。
- ML-KEM(FIPS 203、旧Kyber)はModule-LWEに依拠するKEM。IND-CPAのK-PKEを核に、Fujisaki-Okamoto変換でIND-CCA2へ引き上げる二層構造を取る。
- パラメータはn=256・q=3329固定で、格子の段数kだけを2/3/4に変えてML-KEM-512/768/1024を作る。推奨はML-KEM-768。
- デカプセルは常に共有鍵を返し、暗号文が不正なら秘密の値zから偽の鍵を導く暗黙棄却で、失敗の有無を攻撃者に漏らさない。
FIPS 203 が標準化したもの
ML-KEM(Module-Lattice-Based Key-Encapsulation Mechanism)は、NIST が 2024 年 8 月に FIPS 203 として最初に正式標準化した耐量子鍵カプセル化方式です。母体は CRYSTALS プロジェクトの Kyber で、NIST の PQC 標準化コンペを勝ち抜いた後、いくつかの変更を経て ML-KEM になりました。安全性は 格子問題(Module-LWE)の困難性に依拠し、Shor のアルゴリズムを持つ量子計算機でも効率的に解く手段が知られていません。
ここで重要なのは、ML-KEM は汎用の公開鍵「暗号」ではなく KEM(鍵カプセル化機構)だという点です。任意平文を暗号化するのではなく、ランダムな 32 バイトの共有鍵そのものを生成して相手に届けることに特化しています。以降の実データはその共有鍵で AES-256-GCM などの共通鍵暗号(DEM)を使って守る――この KEM-DEM 分業は RSA/DH のハイブリッド暗号とまったく同じ構造で、鍵共有部分だけを格子ベースに置き換えたものと理解すると全体像がつかめます。
二層構造:K-PKE と FO 変換
ML-KEM の内部は 2 段構えです。この分離が設計の勘所なので、先に押さえます。
- K-PKE:Module-LWE に基づく IND-CPA 安全な公開鍵暗号。ランダムな 32 バイトメッセージを 1 個だけ暗号化できる、素朴だが決定論的に扱える部品。
- ML-KEM 本体:K-PKE を Fujisaki-Okamoto(FO)変換で包み、IND-CCA2 安全な KEM に引き上げたもの。
なぜ二層なのか。K-PKE 単体は選択暗号文攻撃(CCA)に弱いからです。攻撃者が細工した暗号文を送り、復号の成否や結果から秘密鍵の情報を少しずつ搾り取る攻撃を、素の格子暗号は防げません。FO 変換はこれを、復号側で暗号文を再生成して一致を検証するという仕組みで封じます。
K-PKE の中身(Module-LWE そのもの)
K-PKE の鍵生成は、LWEの等式をモジュール(多項式行列)版にしたものです。要素はスカラーではなく多項式環 Zq[x]/(x^256 + 1) の元で、模式的には次の形になります。
横にスクロール
A : k×k の多項式行列(32バイトの種ρからSHAKEで擬似ランダム生成)
s, e : 成分が小さい多項式ベクトル(中心二項分布からサンプル)
t = A ∘ s + e (公開鍵は (t, ρ)、秘密鍵は s)
種 ρ から A をその場で展開するため、公開鍵に巨大な A を載せる必要がありません。暗号化は、受信者の (t, A) に対し送信側が別のノイズ r, e1, e2 を混ぜ、u = A^T ∘ r + e1 と v = t^T ∘ r + e2 + Encode(m) を作ります。復号は m ≈ v − s^T ∘ u を計算し、ノイズを丸めて m を復元します。攻撃者は (u, v) を見ても Module-LWE を解かない限りメッセージも秘密 s も取り出せません。
K-PKE は暗号文 (u, v) を送る前に各係数を Compress で少ないビット数に丸めます。パラメータ du(u 側)と dv(v 側)がそのビット幅で、これが暗号文サイズを直接決めます。丸めは追加のノイズを生みますが、LWE は元々ノイズ耐性があるため復号成功率を保てる範囲に収まります。この意図的な情報削減が、格子暗号の暗号文をぎりぎりまで小さくする鍵です。
多項式積 ∘ は素朴には重い演算ですが、q = 3329 と n = 256 は NTT(数論変換)が使えるよう選ばれており、積を成分ごとの掛け算に変えて高速化します。実際、公開鍵の t は NTT 領域で保持・伝送されます。
FO 変換:暗黙棄却で CCA 安全に
ML-KEM 本体はこの K-PKE を次のように包みます。エンカプセルは乱数 m(32 バイト)を引き、それをハッシュして暗号化に使う乱数 r と共有鍵 K を同時に導出する点が肝です。
Encaps(pk):
m ← ランダム32バイト
(K, r) = G( m || H(pk) ) # 乱数を鍵と暗号化乱数に分岐
c = K-PKE.Encrypt(pk, m; r) # r を明示指定した決定論的暗号化
return (c, K)
Decaps(sk, c):
m' = K-PKE.Decrypt(sk, c)
(K', r')= G( m' || H(pk) )
c' = K-PKE.Encrypt(pk, m'; r') # 同じ乱数で再暗号化
if c' == c: return K' # 一致 → 正規の鍵
else: return J( z || c ) # 不一致 → 秘密zから偽鍵
デカプセル側は復号で得た m' から暗号文を作り直し、送られてきた c とバイト単位で完全一致するかを確かめます。これが FO 変換の核心です。正規に生成された暗号文なら必ず一致し、細工された暗号文はまず一致しません。
不一致のとき、ML-KEM はエラーを返しません。秘密鍵に含まれる 32 バイトの値 z と暗号文 c から J(z || c) で決定論的な偽の共有鍵を導いて返します。これが暗黙棄却(implicit rejection)です。もし失敗時にエラーや特別な値を返すと、その反応差が選択暗号文攻撃やサイドチャネルの手掛かりになります。攻撃者から見れば成功時も失敗時も「32 バイトの区別できない鍵」が返るだけなので、失敗の有無自体が隠蔽されます。復号成否で情報を漏らさない設計は、定数時間実装と並ぶ CCA 防御の要です。
Kyber との差分もここに関係します。ML-KEM では鍵導出の入力から暗号文ハッシュを外す簡素化(K を c に依存させない)や、公開鍵の妥当性検査(modulus チェック)の追加など、FIPS 化にあたり細部が調整されました。相互運用では Kyber の実装と ML-KEM の実装は非互換である点に注意します。
パラメータセット:段数 k だけを変える
ML-KEM の 3 つの水準は、n = 256・q = 3329 を固定したまま格子の段数 k を変えるという明快な設計です。k を上げると行列・ベクトルが大きくなり、鍵と暗号文が線形に増えます。
| パラメータ | k | 公開鍵 | 秘密鍵 | 暗号文 | 強度目安 |
|---|---|---|---|---|---|
| ML-KEM-512 | 2 | 800 B | 1632 B | 768 B | AES-128 級 (Lv.1) |
| ML-KEM-768 | 3 | 1184 B | 2400 B | 1088 B | AES-192 級 (Lv.3) |
| ML-KEM-1024 | 4 | 1568 B | 3168 B | 1568 B | AES-256 級 (Lv.5) |
実務の既定は ML-KEM-768 です。NIST の分析で 512 の安全余裕が想定より薄いと判断され、多くのプロトコル(後述の TLS ハイブリッドを含む)が 768 を標準採用しました。512 は帯域が厳しい組込み用途、1024 は最高強度が要る長期秘匿用途、という位置づけになります。なお η1/η2(ノイズ分布の幅)や du/dv(圧縮ビット幅)は水準ごとにわずかに違いますが、選択を左右するのは基本的に k と考えて差し支えありません。
TLS 1.3 への統合とハイブリッド
ML-KEM は既に TLS 1.3 の鍵共有に組み込まれています。ただし単独ではなく、既存の X25519 と束ねたハイブリッドが主流です。TLS の key_share 拡張に、両者を連結した鍵共有グループ X25519MLKEM768 を載せ、両方の共有秘密を結合してハンドシェイクの鍵導出に流します。
combined = X25519_shared || ML-KEM-768_shared
# 以降は TLS 1.3 の HKDF 鍵スケジュールへ(両方を破らない限り鍵は漏れない)
ハイブリッドにする理由は明快です。格子暗号は歴史が浅く実装バグや未知の解読法の残余リスクがあるため、古典(X25519)と PQC(ML-KEM)の両方を破らないと鍵が漏れない構成にして保険をかけます。量子計算機が来れば X25519 側が破れますが ML-KEM 側が守り、逆に ML-KEM に欠陥が出ても X25519 側が守ります。
ML-KEM-768 の公開鍵は約 1184 バイト、暗号文は約 1088 バイト。X25519 の 32 バイトと比べ桁違いで、鍵共有を最初の 1 パケットに載せる ClientHello が肥大化します。1 往復に収めようとすると 初期パケットが複数に分割され、ミドルボックスの相性問題や initcwnd 起因の追加往復が現実の論点になります。移行では「壊れないか」だけでなく「ハンドシェイク遅延がどう変わるか」を計測すべきで、優先度の考え方は PQC 移行戦略に整理があります。
まとめ
ML-KEM(FIPS 203)は、IND-CPA な K-PKE を Fujisaki-Okamoto 変換で IND-CCA2 に引き上げた二層 KEM です。K-PKE は Module-LWE の等式そのもので、種からの A 展開・意図的な係数圧縮・NTT 高速化で実用サイズと速度を成立させています。
CCA 安全の要は、デカプセル時に暗号文を再暗号化して一致検証し、不一致でも秘密 z から偽鍵を返す暗黙棄却にあります。失敗を失敗として見せないことが選択暗号文攻撃を封じます。
パラメータは n=256・q=3329 固定で段数 k だけを 2/3/4 に変える設計で、既定は ML-KEM-768。TLS では X25519MLKEM768 のハイブリッドが事実上の標準で、ClientHello の肥大化という新しい実務課題を伴います。土台の数学は 格子暗号と LWE、KEM-DEM の枠組みは ハイブリッド暗号、量子脅威の全体像は ポスト量子暗号と合わせて押さえてください。
セキュリティの記事ガイド
ML-KEM(Kyber)とFIPS 203を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
ML-KEM
比較で見る軸
難易度: advanced / カテゴリ: セキュリティ / タグ数: 6
導入後に効く点
パラメータはn=256・q=3329固定で、格子の段数kだけを2/3/4に変えてML-KEM-512/768/1024を作る。推奨はML-KEM-768。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- セキュリティ
- タグ数
- 6
判断チェックリスト
- 自社の用途が「ML-KEM / Kyber」に近いか確認する。
- 強みである「ML-KEM(FIPS 203、旧Kyber)はModule-LWEに依拠するKEM。IND-CPAのK-PKEを核に、Fujisaki-Okamoto変換でIND-CCA2へ引き上げる二層構造を取る。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。