本記事は以下の記事を参照、一部引用して記載しています。出典の記載がない引用に関しては以下のいずれかからの引用になります。
- ECDHとは
- crypto/ecdh導入の目的
- math/big に依存しているとなぜ問題なのか
- ECDHはどんなところに使われるのか(影響範囲はどの程度なのか)
- この定数時間サポートの問題をどのように解決するのか
- crypto/ellipticはいつ非推奨になるのか
- 現在使っているcrypto/elipticをより高度に使用する場合はどのようにすれば良いか
- 参考・引用資料
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/niste
とcrypto/internal/edwards25519
に移動した。 math/big
の代わりとなる定数時間をサポートするbigmod
を実装した。crypto/rsa
とcrypto/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
へ移行することが可能。