crypto/x509,crypto/tls: add ML-DSA support
要約
概要
crypto/x509 および crypto/tls パッケージに対して、耐量子計算機署名アルゴリズムである ML-DSA(Module-Lattice-Based Digital Signature Algorithm、FIPS 204)のサポートを追加するproposalです。量子コンピュータの実用化タイムラインが前倒しになってきたことを受け、既存の公開鍵暗号(RSA・ECC)からの移行を促進するため、証明書の署名検証からTLSハンドシェイクまでの一貫したサポートを提供します。
ステータス変更
active → likely_accept
2026年4月29日のProposal Review Meetingで、ACM Fellowのaclements(@aclements)がレビューグループを代表して「likely accept」に移行することを決定しました。提案内容は #77626 の crypto/mldsa パッケージAPIを基盤とし、既存の列挙型に値を追加するだけの限定的かつ明確なAPI拡張であること、IANA署名スキームレジストリへのコードポイント登録も完了済みであることが承認の決め手となったと考えられます。
技術的背景
現状の問題点
量子コンピュータ(CRQC: Cryptographically Relevant Quantum Computer)の実用化タイムラインが大幅に前倒しになっており、2029年頃には256ビット楕円曲線暗号が破られる可能性があるとGoogleのセキュリティ研究者が警告しています。現在のGo標準ライブラリでは、crypto/tls でのTLSハンドシェイクや crypto/x509 での証明書署名に ML-DSA を利用できません。
Merkle Tree Certificates(WebPKIの移行先として2027年ごろに普及見込み)もML-DSAの葉公開鍵を必要とし、プライベートPKI向けの移行はそれより早急に必要です。
提案された解決策
#77626 で承認済みの crypto/mldsa パッケージ(Go 1.27向け)を基盤として、RFC 9881(X.509向け)および draft-ietf-tls-mldsa-02(TLS向け)に準拠した以下のAPI拡張を行います。
crypto/x509 への追加:
// 公開鍵アルゴリズム定数
const MLDSA PublicKeyAlgorithm = iota
// 署名アルゴリズム定数(セキュリティレベル別)
const MLDSA44 SignatureAlgorithm = iota // NIST セキュリティレベル2
const MLDSA65 SignatureAlgorithm = iota // NIST セキュリティレベル3
const MLDSA87 SignatureAlgorithm = iota // NIST セキュリティレベル5
*mldsa.PublicKeyをCertificate.PublicKey、CertificateRequest.PublicKey、CreateCertificate、MarshalPKIXPublicKey、ParsePKIXPublicKeyでサポート*mldsa.PrivateKeyをCreateCertificate、CreateCertificateRequest、CreateRevocationList、MarshalPKCS8PrivateKey、ParsePKCS8PrivateKeyでサポート
crypto/tls への追加:
// TLS SignatureScheme 定数(IANAコードポイント登録済み)
const MLDSA44 SignatureScheme = 0x0904
const MLDSA65 SignatureScheme = 0x0905
const MLDSA87 SignatureScheme = 0x0906
*mldsa.PublicKeyを返すcrypto.SignerをCertificate.PrivateKeyでサポート
これによって何ができるようになるか
このproposalによって、GoアプリケーションはML-DSA証明書を使ったTLS通信を標準パッケージだけで実現できるようになります。
コード例
// Before: ML-DSA証明書はパース・検証できず、TLS接続にも使用不可
cert, err := x509.ParseCertificate(certDER)
// エラー: Unknown public key type
// After: ML-DSA証明書を透過的に扱える
import "crypto/mldsa"
import "crypto/x509"
import "crypto/tls"
// ML-DSA秘密鍵の生成
privKey, err := mldsa.GenerateKey(mldsa.MLDSA65())
// ML-DSA証明書の発行
template := &x509.Certificate{
SerialNumber: big.NewInt(1),
SignatureAlgorithm: x509.MLDSA65,
// ...
}
certDER, err := x509.CreateCertificate(rand.Reader, template, parent, privKey.Public(), privKey)
// TLS設定でML-DSA証明書を使用
tlsCert := tls.Certificate{
Certificate: [][]byte{certDER},
PrivateKey: privKey,
}
config := &tls.Config{Certificates: []tls.Certificate{tlsCert}}
議論のハイライト
- 複合署名(Composite Signatures)は対象外: ハイブリッド方式ではなく純粋なML-DSAのみを対象とする方針が明確化されました。複合署名を望む場合は別proposalを立てるよう促されています。これはwait-and-see期間の結論として、純粋ML-DSAの方が運用コストが低くセキュリティ上も十分という判断によるものです。
- TLS仕様がまだドラフト: draft-ietf-tls-mldsa-02はIETF内部の無関係な対立により正式RFCになっていませんが、IANAコードポイントは既に登録済みであり、他の実装も存在するため、ドラフトであることが承認の障壁にはなりませんでした。
- API表面の広さは見かけだけ: 提案者自身が「表面上は広く見えるが、実質は既存の列挙型への値の追加とswitch文の拡張に過ぎない」と指摘しており、実装コストは低い見通しです。
iota記法の明確化: aclements が指摘したように、提案中のconst MLDSA44 SignatureAlgorithm = iotaは独立した宣言として解釈すると全て0になりますが、実際は既存のiotaリストへの追加を意図したものです。- 秘密鍵はseedのみサポート: #77626と同様、拡張形式(semi-expanded keys)はサイズが大きく読み込みも遅い上により危険なため、32バイトのseedのみをサポートします。