crypto/x509,crypto/tls: add ML-DSA support
要約
概要
crypto/x509 および crypto/tls パッケージに、耐量子コンピュータ署名アルゴリズムである ML-DSA(Module-Lattice-Based Digital Signature Algorithm、FIPS 204)のサポートを追加するproposalです。これにより、GoのTLSハンドシェイクおよびX.509証明書チェーンの検証・生成にML-DSAを利用できるようになります。
ステータス変更
likely_accept → accepted
2026年4月29日にaclementsによって「likely accept」と判定され、1週間後の2026年5月6日、コンセンサスに変更がないことを確認した上で正式に承認されました。提案内容が明確であり、関連issue #77626(crypto/mldsaパッケージの新設)がすでに承認済みであったことから、議論は短期間で収束しました。
技術的背景
現状の問題点
量子コンピュータ(CRQC: Cryptographically Relevant Quantum Computer)の実現タイムラインが急速に前倒しになっています。Googleの研究では2029年頃の脅威を示唆しており、既存のECDSA・RSA署名は理論上破られるリスクを持ちます。
WebPKIにおける移行策としてMerkle Tree Certificates(MTC)が2027年頃を目標に検討されていますが、これ自体もML-DSAの公開鍵を必要とする上、プライベートPKI(社内CAや組み込み機器など)への対応には間に合いません。また、GoにはすでにML-KEMによる鍵交換の耐量子化(#78543等)が進んでいましたが、署名アルゴリズムのML-DSA対応が欠落していました。
提案された解決策
本proposalは純粋なML-DSA署名のサポートを追加します(コンポジット署名は対象外)。
crypto/x509への追加:
PublicKeyAlgorithmの新定数:MLDSASignatureAlgorithmの新定数:MLDSA44、MLDSA65、MLDSA87(RFC 9881準拠)*mldsa.PublicKey/*mldsa.PrivateKeyのサポートを以下に追加:Certificate.PublicKey、CertificateRequest.PublicKeyCreateCertificate、CreateCertificateRequest、CreateRevocationListMarshalPKIXPublicKey、ParsePKIXPublicKeyMarshalPKCS8PrivateKey、ParsePKCS8PrivateKey
crypto/tlsへの追加:
- 署名スキーム定数(IANAに登録済みのコードポイント):
MLDSA44 SignatureScheme = 0x0904MLDSA65 SignatureScheme = 0x0905MLDSA87 SignatureScheme = 0x0906
- TLS 1.3ハンドシェイクにおけるML-DSA証明書での署名検証・認証のサポート
TLS仕様はdraft-ietf-tls-mldsa-02に準拠します(IETF WG内の政治的事情でdraft段階が続いていますが、コードポイントはIANA TLS SignatureSchemeレジストリに正式登録済みです)。
これによって何ができるようになるか
- プライベートCAにおける耐量子証明書の発行: 企業内部のCAでML-DSA鍵ペアを使った証明書を発行し、内部サービス間通信のTLSに利用できます。
- TLS 1.3での耐量子認証: サーバー/クライアント証明書としてML-DSA証明書を使ったTLS 1.3接続が可能になり、盗聴→後から復号("Harvest Now, Decrypt Later")攻撃への署名層での対策ができます。
- ML-DSA鍵のPKCS#8・PKIX形式でのシリアライズ: 既存ツールチェーン(OpenSSL等との連携)が容易になります。
コード例
// Before: ML-DSAの証明書を発行できない(ECDSAに限定)
privateKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
template := &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{CommonName: "example.com"},
SignatureAlgorithm: x509.ECDSAWithSHA256,
// ...
}
certDER, _ := x509.CreateCertificate(rand.Reader, template, template, &privateKey.PublicKey, privateKey)
// After: ML-DSA-65でポスト量子証明書を発行
import "crypto/mldsa"
privKey, _ := mldsa.GenerateKey(mldsa.MLDSA65())
template := &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{CommonName: "example.com"},
SignatureAlgorithm: x509.MLDSA65, // 新定数
// ...
}
certDER, _ := x509.CreateCertificate(rand.Reader, template, template, privKey.Public(), privKey)
// TLS設定での使用
tlsCert, _ := tls.X509KeyPair(certPEM, keyPEM)
config := &tls.Config{Certificates: []tls.Certificate{tlsCert}}
// MLDSA65 SignatureScheme (0x0905) が自動的にネゴシエートされる
議論のハイライト
- コンポジット署名は対象外: 提案者(filippo.io)はTLS WGメーリングリストで「純粋なML-DSAをコンポジット署名より優先すべき理由」を説明しており、コンポジット署名への需要がある場合は別proposalとするよう明記しています。
- 既存API #77626への依存:
crypto/mldsaパッケージが土台であり、本proposalは主にその定数を各enumに追加するものに過ぎないと提案者は述べています(「多くのAPIサーフェスに見えるが、実際にはenum値とswitch文の追加に過ぎない」)。 iotaの記述誤り指摘: aclementsが「const MLDSA44 SignatureAlgorithm = iotaを3つ並べると全て0になる」と指摘しました。これは既存のiota列挙に追加する意味であり、文法的な誤りではなく説明上の略記です。- TLS仕様のdraft状態について: TLSの仕様は「IETF WG内の争い(infighting)」によりdraftのままですが、IANAへのコードポイント登録は完了しており、他の実装も存在するため採用に問題なしと判断されました。
- MLSAMu(External μ): 親issueの #77626 で、External μ(プレハッシュ)を
crypto.Hashの新しいiota値として表現する設計が採用されており、本proposalでもその仕組みを利用します。HashML-DSAは過度に多くなるため非サポートです(RFC 9881 §8.1準拠)。