Develop with pleasure!

福岡でCloudとかBlockchainとか。

BLS12-381の点のシリアライゼーションフォーマット

ペアリングに適した楕円曲線の1つであるBLS12-381の各曲線E, E'上の点のシリアライゼーションフォーマットについて(もともとZcashで定義された仕様)↓

https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#appendix-C

BLS12-381曲線上の点

BLS12-381という名称の由来は埋め込み次数12、曲線上の座標のビット数が381で表現される点から来てる。

BLS曲線は以下の2つの楕円曲線で構成される:

  •  {E: y^{2} = x^{3} + 4}
  •  {E': y^{2} = x^{3} + 4(1 + i)}

BLS12-381の詳細については、以下の記事が詳しい。

qiita.com

E上の点は、圧縮形式で48バイト、非圧縮形式で96バイト。E'上の点は、圧縮形式で96バイト、非圧縮形式で192バイト。

圧縮形式と非圧縮形式の違いは、Bitcoinとかと同様で、圧縮形式は点のx座標+y座標の符号で構成され、非圧縮形式はx座標とy座標を連結したデータになる。

点のメタデータ

点の座標のビット数は381ビットなので、圧縮形式の48バイトと比べると座標をエンコードする際に3ビット余ることになる。この3ビット分のデータが点のメタデータで、以下のように定義されている。

  • 最上位ビット(C_bit)は点が圧縮形式かどうかを示すフラグで、圧縮形式の場合は1、そうでなければ0。
  • 2つめのビット(I_bit)は、無限遠点かどうかを示すフラグで、無限遠点の場合は1、そうでなければ0。
  • 3つめのビット(S_bit)は、点が圧縮形式の場合にy座標の符号を示す値。無限遠点や非圧縮形式の場合は0。

以下、シリアライゼーション/デシリアライゼーション手順。

リアライゼーション手順

  1. ↑のメターデータの仕様に沿って、各メタデータビットを設定する。
  2. 各メタビットからメタバイトm_byte = C_bit * 27 + I_bit * 26 + S_bit * 25を計算する。
  3. xをシリアライゼーションしたx_stringを生成する。
    • E上の点の場合は、48バイト列のデータに変換する。無限遠点の場合48バイトの0。
    • E'上の点の場合は、 {x = (x_0, x_1)}について96バイト列のデータに変換する。無限遠点の場合96バイトの0。 {x_0, x_1}の各要素も381ビットのデータ。
    • 上記すべてのケースにおいて、x_stringの上位3ビットは、0になる。
  4. 圧縮形式の場合はy_stringは空で、非圧縮形式の場合はs_stringと同じ方法で生成する。
  5. x_stringとy_stringを連結してs_stringを構成する。
  6. s_string[0] = s_string[0] OR m_byteをセットする。
  7. s_stringがシリアライゼーションした結果

デシリアライゼーション手順

  1. s_stringからm_byte = s_string[0] & 0xe0を導出し、m_byteの上位3ビットからC_bit、I_bit、S_bitをセットする。
  2. C_bitが1の場合、s_stringが48バイトの場合E上の点、96バイトの場合E'上の点。それ以外の場合無効なデータ。C_bitが0の場合、s_stringが96バイトの場合E上の点、192バイトの場合E'上の点。それ以外の場合無効なデータ。
  3. s_string[0] = s_string[0] & 0x1fをセットし、メタデータのビットをクリアする。
  4. I_bitが1の場合、s_stringはすべて0でなければならない。すべて0であれば無限遠点を出力し、そうでない場合は無効なデータ。
  5. C_bitが0の場合(非圧縮形式)、s_stringの先頭半分をx_string、残り半分がy_stringとする。これら2つのデータを数値に変換し、(x, y)が曲線上の有効な点の場合、その点を出力する。それ以外の場合無効なデータ。
  6. それ以外の場合は圧縮形式なので、x座標からy座標を計算する。
    • 手順2の結果E上の点である場合、 y2 = x3 + 4およびy = sqrt(y2) を計算し、GF(p)のデータかチェックする。
    • E'上の点の場合、y2 = x3 + 4 * (1 + i)および y = sqrt(y2)を計算し、GF(p2)のデータかチェックする。
  7. yの符号を確認し、S_bitと等しければ、点(x, y)を出力する。S_bitと異なる場合は点(x, -y)を出力する。