【CTO Tech Blog】楕円曲線の点に対する部分群のメンバーシップチェック
- CTO Tech blog

先日Besuに存在していたBN254曲線上の点の検証ロジックのバグが開示された↓
このバグの内容とは直接関係ないけど*1、解説の中に登場していた楕円曲線上の点が部分群に属しているかどうかのメンバーシップチェックの方法がいろいろあるようだったので調べてみた。
※ Bitcoinが使用しているsecp256k1のように位数が素数で構成される楕円曲線は曲線のサブセットとなる部分群を形成しない(cofactor = 1)ため、このメンバーシップチェックは不要。一方、部分群を構成する楕円曲線を使用している場合に、点の有効性は、その曲線を使用する楕円曲線暗号で使用している有効な部分群に点が属しているかのチェックが必要になる。このチェックが抜けていると脆弱性が生まれる↓
素数位数の乗算
楕円曲線の位数(=楕円曲線上の点の総数)をn
とし、n
が素数でない場合、その楕円曲線は部分群を持つ。楕円曲線暗号の各演算は安全性の観点から、非素数位数n
の楕円曲線ではなく、素数位数(l
とする)を持つ部分群上で行うことが推奨されている。cofactorは、曲線の位数n
と主要な部分群の位数l
の比率で、h = n/l
で計算される。
部分群に属するかチェックする簡単な方法は、点P
に素数位数l
を乗算し、l * P
が無限遠点となるかどうかチェックする。素数位数の群の任意の点に位数を乗算すると必ず無限遠点となるため、l * P
が無限遠点と等しければP
は正しい部分群に属している。↑のMoneroの脆弱性の対応でも、この方法のチェックが追加された。
ただ、素数位数は大きな値になるため、l * P
の計算はコスト高になる。秘密鍵から公開鍵を計算する際のスカラー倍算と同じコストでは?と思ったけど、公開鍵や署名の計算は固定の点G
に対して行なわれるため、G
に対して様々な倍数(2G, 4G, 8G, …)を計算した事前計算テーブルを用意しておくことで、計算処理の最適化が行える(Bitcoinのlibsecp256k1の実装でも採用されている)。
また、特にBN254やBLS12-381のG2G2群での計算は拡大体Fp2Fp2上の計算となるため、secp256k1曲線のような有限体FpFp上の計算に比べて計算コストが約3〜4倍かかる。
自己準同型写像を利用したチェック
Michael ScottやYu Daiらによって提案されたのが、自己準同型写像を使ってメンバーシップチェックを高速化する手法。楕円曲線上の自己準同型写像は、ある楕円曲線E
から同じ楕円曲線E
への写像ϕ:E→Eϕ:E→Eで、以下の性質を持つ。
- ϕ(P+Q)=ϕ(P)+ϕ(Q)ϕ(P+Q)=ϕ(P)+ϕ(Q)
- ϕ(∞)=∞ϕ(∞)=∞
用途は違うけど、GLV法なんかも自己準同型写像を使ってスカラー乗算を高速化している。
最初にScottが提案したBLS12-381の部分群のメンバーシップチェックを高速化する手法では、フロベニウス写像を用いる。有限体FqFq上の楕円曲線のフロベニウス写像は、
ϕ(x,y)=(xq,yq)ϕ(x,y)=(xq,yq)
と定義され、点の座標をq乗した座標になる。そしてこのフロベニウス自己準同型写像は、以下の特性多項式を持つ。
ϕ2−tϕ+q=0ϕ2−tϕ+q=0
ここで、t
はトレースと呼ばれる値で、有限体の位数q + 1から曲線の位数を引いた値↓
t=q+1−♯E(Fq)t=q+1−♯E(Fq)
↑の特性多項式を性質を利用して、点Pに対して、
ϕ2(P)−tϕ(P)+qP=∞ϕ2(P)−tϕ(P)+qP=∞
が成立するかチェックということみたい。qPqPは正確には(qmodl)P(qmodl)PでBLS12曲線の場合qmodl=1qmodl=1となるので、正確には、ϕ2(P)−tϕ(P)+P=∞ϕ2(P)−tϕ(P)+P=∞を計算することになる。
この場合、スカラー乗算が登場するのはtϕ(P)tϕ(P)の部分だけで、残りはフロベニウス写像の計算(スカラー乗算に比べて計算コストはかなり低い)と、点の加算のみ。ここでt
の値が、素数位数l
の値よりも小さいため、上記の検証した方が速度が速くなると。
その後、Daiらによって他の曲線でも使えるように、検証する式が、
cϕ2(P)−bϕ(P)+aP=∞cϕ2(P)−bϕ(P)+aP=∞
という形式に一般化されたらしい。a, b, cは曲線毎に設定される。
Tateペアリングを利用したチェック
Tateペアリングを利用する手法はDmitrii Koshelevによる提案で、↑の自己準同型写像を使用するチェックの方が高速な一方、ペアリングに適していない曲線にも適用できるのが特徴。ペアリングに適していない曲線でペアリングを使って検証というのは不思議に思うけど、完全なペアリング計算の結果(e(P, Q)
の値)が必要な訳ではなく、ペアリングの特性(e(P,Q)≠1e(P,Q)≠1を判定できればいい)を部分的に利用しているということみたい。ペアリングについては、以前の記事参照。
この手法は、e
をTateペアリングとした場合、点Pに対して適切に選択した点Qに対してe(P, Q) = 1
が成立するか検証するというもの。Qの選択方法とか、個人的にこの辺りの背景はまだよく理解していない。
*1:バグの内容は楕円曲線の点について、有効な部分群のメンバーシップチェックはしていたけど、楕円曲線上の点かどうかのチェックをしていなかったというもの。
ブログ元記事へのリンク
Chaintopeでブロックチェーンの未来を共に創りませんか?
Chaintopeは、独自のブロックチェーン「Tapyrus」と、開発プラットフォーム「Tapyrus Platform」を活用し、デジタル社会の信頼基盤を構築しています。
私たちは、ブロックチェーン技術の可能性を最大限に引き出し、社会に新しい価値を提供することを目指しています。
募集職種:
ブロックチェーンエンジニア
アプリケーションエンジニア
インフラ・保守エンジニア
プロジェクトマネージャー
フィールドセールス
Chaintopeで働く魅力:
最先端のブロックチェーン技術に触れる機会
リモートワークやフレックスタイム制による柔軟な働き方
専門性の高いチームとの協働
ブロックチェーン技術に情熱を持つあなたのスキルを、私たちのチームで活かしませんか?
詳細は、採用情報をご覧ください。
https://www.chaintope.com/recruit/