crypto/x509とcrypto/tlsに耐量子署名アルゴリズムML-DSAのサポートが追加される。
crypto/tls
概要
crypto/x509 と crypto/tls に、耐量子計算機署名アルゴリズムML-DSA(Module-Lattice-Based Digital Signature Algorithm、FIPS 204)のサポートが追加される。土台となるcrypto/mldsaパッケージの鍵型を、証明書の発行・検証(x509.CreateCertificate、x509.ParseCertificateなど)およびTLS 1.3ハンドシェイクの署名(crypto/tls)で扱えるようになる。対象は複合(コンポジット)署名ではなく、純粋なML-DSA署名のみである。
crypto/x509側の追加:
PublicKeyAlgorithmの新定数MLDSASignatureAlgorithmの新定数MLDSA44/MLDSA65/MLDSA87(RFC 9881準拠、NISTセキュリティレベル2/3/5にそれぞれ対応)*mldsa.PublicKey・*mldsa.PrivateKey(を返すcrypto.Signer)の、証明書の発行・パース・PKIX/PKCS#8シリアライズ関連APIへの対応
crypto/tls側の追加:
SignatureSchemeの新定数MLDSA44(0x0904)/MLDSA65(0x0905)/MLDSA87(0x0906)。TLS仕様はdraft-ietf-tls-mldsa-02に基づくが、コードポイント自体はIANAのTLS SignatureSchemeレジストリに登録済み- ML-DSA証明書によるTLS 1.3ハンドシェイク署名の検証、および
*mldsa.PublicKeyを返すcrypto.SignerをCertificate.PrivateKeyとして使う署名のサポート
秘密鍵の形式は、RFC 9881が推奨する32バイトのseed形式のみをサポートする(展開形式の鍵は非対応)。
導入経緯
提案者(Filippo Valsorda)は、量子コンピュータ(CRQC: Cryptographically Relevant Quantum Computer)の実用化タイムラインが前倒しになっていることを理由に挙げている。WebPKIの移行先として検討されているMerkle Tree CertificatesもML-DSAの葉公開鍵を必要とする上、2027年頃までは実用化されず、多くのプライベートPKI(社内CAなど)には間に合わないため、crypto/tls・crypto/x509への直接のML-DSA対応が必要と判断された。本提案は#77626で追加されたcrypto/mldsaパッケージのAPIを前提としており、既存の列挙型(PublicKeyAlgorithm・SignatureAlgorithm・SignatureScheme)に値を追加する形の、比較的小さな拡張として設計されている。コンポジット署名(従来方式とのハイブリッド)は意図的に対象外とされ、需要があれば別提案とするよう明記されている。
議論タイムライン
- 2026-04-22: proposal reviewの
activeカラムに追加され、週次レビュー会議での審議が始まる。 - 2026-04-29: レビュー会議で
likely acceptと判定される。 - 2026-05-06: 前週からコンセンサスに変更がないことが確認され、正式に
acceptedとなる。
議論のハイライト
- コンポジット署名は明確にスコープ外とされ、需要がある場合は別のproposalを立てるよう案内されている。
- 提案者自身が「APIサーフェスは広く見えるが、実質は既存のenumへの値追加とswitch文の拡張に過ぎない」と述べており、実装コストは小さいと見積もられている。
- レビュアーのaclementsから、提案文中の
const MLDSA44 SignatureAlgorithm = iotaという記述だけを見ると3つとも0になってしまう、という指摘が入った。これは説明上の略記であり、実際には既存のiota列挙への追加を意図したものである旨が確認されている。 - TLS仕様の
draft-ietf-tls-mldsa-02はIETF WG内の事情により正式なRFCになっていないが、IANAへのコードポイント登録は完了しており、他の実装も存在することから採用の障壁にはならないと判断された。
使用例
Before
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"fmt"
"math/big"
"time"
)
func main() {
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
panic(err)
}
template := &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{CommonName: "example.com"},
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour),
}
der, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv)
if err != nil {
panic(err)
}
fmt.Printf("issued %d-byte ECDSA certificate\n", len(der))
}
After
package main
import (
"crypto/mldsa"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"fmt"
"math/big"
"time"
)
func main() {
priv, err := mldsa.GenerateKey(mldsa.MLDSA65())
if err != nil {
panic(err)
}
template := &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{CommonName: "example.com"},
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour),
SignatureAlgorithm: x509.MLDSA65,
}
der, err := x509.CreateCertificate(rand.Reader, template, template, priv.Public(), priv)
if err != nil {
panic(err)
}
fmt.Printf("issued %d-byte ML-DSA-65 certificate\n", len(der))
}
移行時の注意
- ML-DSAの鍵・署名はECDSAやEd25519に比べてかなり大きい(公開鍵はML-DSA-44/65/87でそれぞれ1312/1952/2592バイト、署名は2420/3309/4627バイト)。証明書チェーンやTLSハンドシェイクのサイズが増えるため、MTUやハンドシェイク遅延に敏感な環境では影響を見積もる必要がある。
- サポートされるのは純粋なML-DSA署名のみで、コンポジット署名(従来アルゴリズムとのハイブリッド)は対象外である。
crypto/mldsaはFIPS 140-3 Go Cryptographic Moduleのv1.0.0では利用できず、v1.26.0以降が必要になる。FIPSモード運用の環境では事前にモジュールのバージョンを確認する必要がある。- 秘密鍵はRFC 9881推奨の32バイトseed形式のみサポートされる。展開形式(semi-expanded key)の鍵は非対応。
実装解説
crypto/tlsでは、TLS 1.3のSignatureSchemeとしてMLDSA44/MLDSA65/MLDSA87(0x0904〜0x0906)が定義されている。ハンドシェイク署名の検証はverifyHandshakeSignature内のsignatureMLDSAケースで行われ、*mldsa.PublicKeyへのアサーション後にmldsa.Verifyを呼び出す。ECDSA/RSA系がハッシュ値に対して署名するのに対し、ML-DSA(Ed25519と同様)はdirectSigning(プリハッシュなし)として扱われ、メッセージそのものに対して署名・検証される。
crypto/x509では、SignatureAlgorithmのMLDSA44/MLDSA65/MLDSA87定数とPublicKeyAlgorithmのMLDSA定数が追加されている。signatureAlgorithmDetailsテーブルでもML-DSAの3方式はcrypto.Hash(0)(プリハッシュなし)として登録されており、TLS側と同じくメッセージ全体に対して直接署名する設計になっている。CreateCertificateが呼ぶsigningParamsForKeyは、鍵のParameters()(MLDSA44/65/87のどれか)から対応するSignatureAlgorithmを自動的に選ぶため、テンプレートのSignatureAlgorithmは省略しても動作する。