ペアリングの構造とBLS署名の検証の高速化
初めに
今回はペアリングの大まかな計算構造と、それを用いたBLS署名の検証の効率化方法を紹介します。実装レベルでは必須の知識です。
用語の復習
まずはいつもの用語の復習から。
ペアリングを
とします。
EthereumタイプのBLS署名は次の形でした。
- 鍵生成 :
をランダムにとり署名鍵とし、検証鍵をs \in 𝔽_r とする。pk:=s P \in G_1 - 署名 Sign
: メッセージ(s,m) に対してm を署名とする。σ:=s H_2(m) \in G_2 - 検証 Verify
: メッセージ(pk, m, σ) , 検証鍵m , 署名pk に対してσ が成り立てば受理する。e(pk, H_2(m)) = e(P, σ)
検証ではペアリングを2回計算してそれを比較しています。ペアリングは重たい計算なので少しでも軽くしたいです。その方法を紹介する前にまずはペアリングの大まかな計算構造を説明します。
ペアリングの構造と署名の高速化第一段階
ペアリングの計算はミラーループML(Miller Loop)と最終べきFE(Final Exponentiation)の部分からなります。
最終べきは、ある定数
それからペアリングの双線型性から
一つ目の同値はペアリングの双線型性、二つ目はペアリングをML+FEに置き換えただけ、三つ目はFEの準同型性によります。
素朴な検証ではペアリング2回、つまりML×2 + FE×2でしたが、※を検証するにはML×2 +FE×1とFEが1個分減ります(
MLとFEの演算コストは1:1.4ぐらいなので、(1+1.4)×2=4.8が1×2+1.4=3.4に減少し、計算時間を約30%削減できました。
ミラーループの構造とマルチミラーループ
ミラーループ
Fp12 ML(G1 P, G2 Q) {
Fp12 f = 1;
for (size_t i = 0; i < 定数; i++) {
f *= f;
// PとQから決まるある値eを計算
f *= e;
}
return f;
}
前節※の部分では2個MLをそれぞれ計算してから掛けています。しかし、このミラーループの構造を見ると、
ということは、
Fp12 ML2(G1 P1, G2 Q1, G1 P2, G2 Q2) {
Fp12 f = 1;
for (size_t i = 0; i < 定数; i++) {
f *= f;
// P1とQ1から決まるある値e1を計算
f *= e1;
// P2とQ2から決まるある値e2を計算
f *= e2;
}
return f;
}
MLを個別に計算する場合に比べて
※からの同値を続けると、
です。mclではmillerLoopVecを提供しています。
2個のペアリングの値が一致することを確認しているコードはisEqualTwoPairingsです。
今回BLS署名のうち、署名が
コード中のprecomputedMillerLoop2mixedですが、細部に入りすぎるので今回は止めておきます。
まとめ
今回はBLS署名の検証アルゴリズムの高速化方法を紹介しました。2個のペアリングの値が一致するということを調べるだけでも様々な知識を使って最適化できます。
複数の検証をまとめて行うことで高速化する方法もあります。またの機会に紹介しましょう。
Discussion