メインコンテンツへスキップ

Go Proposal Weekly Digest

Go言語のproposal更新を毎週お届け

新機能

crypto/x509とcrypto/tlsに耐量子署名アルゴリズムML-DSAのサポートが追加される。

crypto/tls

この項目の注釈は AI により生成されており、誤りを含む場合があります。
使用例のコンパイル検証: 検証済み

概要

crypto/x509crypto/tls に、耐量子計算機署名アルゴリズムML-DSA(Module-Lattice-Based Digital Signature Algorithm、FIPS 204)のサポートが追加される。土台となるcrypto/mldsaパッケージの鍵型を、証明書の発行・検証(x509.CreateCertificatex509.ParseCertificateなど)およびTLS 1.3ハンドシェイクの署名(crypto/tls)で扱えるようになる。対象は複合(コンポジット)署名ではなく、純粋なML-DSA署名のみである。

crypto/x509側の追加:

  • PublicKeyAlgorithmの新定数MLDSA
  • SignatureAlgorithmの新定数MLDSA44/MLDSA65/MLDSA87RFC 9881準拠、NISTセキュリティレベル2/3/5にそれぞれ対応)
  • *mldsa.PublicKey*mldsa.PrivateKey(を返すcrypto.Signer)の、証明書の発行・パース・PKIX/PKCS#8シリアライズ関連APIへの対応

crypto/tls側の追加:

  • SignatureSchemeの新定数MLDSA440x0904)/MLDSA650x0905)/MLDSA870x0906)。TLS仕様はdraft-ietf-tls-mldsa-02に基づくが、コードポイント自体はIANAのTLS SignatureSchemeレジストリに登録済み
  • ML-DSA証明書によるTLS 1.3ハンドシェイク署名の検証、および*mldsa.PublicKeyを返すcrypto.SignerCertificate.PrivateKeyとして使う署名のサポート

秘密鍵の形式は、RFC 9881が推奨する32バイトのseed形式のみをサポートする(展開形式の鍵は非対応)。

導入経緯

提案者(Filippo Valsorda)は、量子コンピュータ(CRQC: Cryptographically Relevant Quantum Computer)の実用化タイムラインが前倒しになっていることを理由に挙げている。WebPKIの移行先として検討されているMerkle Tree CertificatesもML-DSAの葉公開鍵を必要とする上、2027年頃までは実用化されず、多くのプライベートPKI(社内CAなど)には間に合わないため、crypto/tlscrypto/x509への直接のML-DSA対応が必要と判断された。本提案は#77626で追加されたcrypto/mldsaパッケージのAPIを前提としており、既存の列挙型(PublicKeyAlgorithmSignatureAlgorithmSignatureScheme)に値を追加する形の、比較的小さな拡張として設計されている。コンポジット署名(従来方式とのハイブリッド)は意図的に対象外とされ、需要があれば別提案とするよう明記されている。

議論タイムライン

  • 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/MLDSA870x09040x0906)が定義されている。ハンドシェイク署名の検証はverifyHandshakeSignature内のsignatureMLDSAケースで行われ、*mldsa.PublicKeyへのアサーション後にmldsa.Verifyを呼び出す。ECDSA/RSA系がハッシュ値に対して署名するのに対し、ML-DSA(Ed25519と同様)はdirectSigning(プリハッシュなし)として扱われ、メッセージそのものに対して署名・検証される。

crypto/x509では、SignatureAlgorithmMLDSA44/MLDSA65/MLDSA87定数PublicKeyAlgorithmMLDSA定数が追加されている。signatureAlgorithmDetailsテーブルでもML-DSAの3方式はcrypto.Hash(0)(プリハッシュなし)として登録されており、TLS側と同じくメッセージ全体に対して直接署名する設計になっている。CreateCertificateが呼ぶsigningParamsForKeyは、鍵のParameters()(MLDSA44/65/87のどれか)から対応するSignatureAlgorithmを自動的に選ぶため、テンプレートのSignatureAlgorithmは省略しても動作する。

関連リンク