Simple minds think alike

より多くの可能性を

Go 1.20 crypto/ecdh導入の理由

本記事は以下の記事を参照、一部引用して記載しています。出典の記載がない引用に関しては以下のいずれかからの引用になります。

words.filippo.io

github.com

ECDHとは

楕円曲線ディフィー・ヘルマン鍵共有(だえんきょくせんディフィー・ヘルマンかぎきょうゆう、英: Elliptic curve Diffie–Hellman key exchange, ECDH)は、事前の秘密の共有無しに、盗聴の可能性のある通信路を使って、暗号鍵の共有を可能にする、公開鍵暗号方式の暗号プロトコルである。両者で共有した秘密の値はそのまま、あるいは何かしらの変換をかけて、共通鍵暗号の鍵として用いることができる。 ディフィー・ヘルマン鍵共有を楕円曲線を使うように変更した、楕円曲線暗号の一つである。 出典:Wikipedia(楕円曲線ディフィー・ヘルマン鍵共有)

crypto/ecdh導入の目的

The goal of the package is to replace the major use case for the now-deprecated crypto/elliptic API, which has a hardcoded dependency on the variable-time, large, and complex math/big package.

引用によると、このパッケージの目的は可変時間で大規模かつ複雑なmath/bigパッケージにハードコードされた依存性を持つ crypto/elliptic APIの主なユースケースを置き換えることを目的としているとのことです。crypto/elliptic APIはGo言語標準パッケージの楕円曲線パッケージです。

現在2023年1月時点で crypto/elliptic パッケージはdeprecatedではないため、おそらくnow-deprecatedでは誤記であり、正しくはnon-deprecatedと記載したかったのだと思われます。

GitHub Issueの方で言及されている crypto/elliptic APIのメソッドを見ると、確かに *big.Int に依存してます。

type CurveParams struct {
    P       *big.Int // the order of the underlying field
    N       *big.Int // the order of the base point
    B       *big.Int // the constant of the curve equation
    Gx, Gy  *big.Int // (x,y) of the base point
    BitSize int      // the size of the underlying field
    Name    string   // the canonical name of the curve
}

https://pkg.go.dev/crypto/elliptic#CurveParams

math/big に依存しているとなぜ問題なのか

math/big is a general-purpose big integer library, it's not constant time, and it's full of complex code that while unnecessary for cryptography has repeatedly led to security vulnerabilities in crypto packages.

math/big は汎用のbig integerライブラリで、定数時間ではなく暗号パッケージのセキュリティ脆弱性を繰り返し引き起こすような複雑なコードがたくさんあるからという理由のようです。

この問題に関しては、以前以下のissueでも定数時間サポートに関して提起されており、また今後コードコメントにも注意書きが追加されるようです。 https://github.com/golang/go/issues/20654 https://go-review.googlesource.com/c/go/+/455135/1/src/math/big/int.go

ECDHはどんなところに使われるのか(影響範囲はどの程度なのか)

ECDH is used in TLS, SSH, JOSE, OpenPGP, PIV, and HPKE, as well as a component of other various ECIES schemes.

この定数時間サポートの問題をどのように解決するのか

ざっくりまとめると以下のようにして問題が解決されることが分かります。

  • Go 1.17からGo 1.19の間に標準ライブラリの楕円曲線実装(crypt/eliptic APIの実装のことだと思われます)のほとんどの重要なコードは crypto/internal/nistecrypto/internal/edwards25519 に移動した。
  • math/big の代わりとなる定数時間をサポートするbigmod を実装した。
  • crypto/rsacrypto/ecdsa を移植し math/big依存をなくすことで、bit.Int が暗号パッケージから到達できなくなる。

crypto/ellipticはいつ非推奨になるのか

The full crypto/elliptic deprecation will actually have to wait until Go 1.22, because of the deprecation policy:

Go 1.22

現在使っているcrypto/elipticをより高度に使用する場合はどのようにすれば良いか

Any more advanced uses of crypto/elliptic can switch to filippo.io/nistec which is an exported version of crypto/internal/nistec, or filippo.io/edwards25519 which is an exported version of crypto/internal/edwards25519.

crypto/internal/nistec のエクスポートバージョンである filippo.io/nistec、または crypto/internal/edwards25519 のエクスポートバージョンである filippo.io/edwards25519 へ移行することが可能。

参考・引用資料