ペアリングに適した楕円曲線の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つの楕円曲線で構成される:
BLS12-381の詳細については、以下の記事が詳しい。
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。
シリアライゼーション手順
- ↑のメターデータの仕様に沿って、各メタデータビットを設定する。
- 各メタビットからメタバイトm_byte = C_bit * 27 + I_bit * 26 + S_bit * 25を計算する。
- xをシリアライゼーションしたx_stringを生成する。
- 圧縮形式の場合はy_stringは空で、非圧縮形式の場合はs_stringと同じ方法で生成する。
- x_stringとy_stringを連結してs_stringを構成する。
- s_string[0] = s_string[0] OR m_byteをセットする。
- s_stringがシリアライゼーションした結果
デシリアライゼーション手順
- s_stringからm_byte = s_string[0] & 0xe0を導出し、m_byteの上位3ビットからC_bit、I_bit、S_bitをセットする。
- C_bitが1の場合、s_stringが48バイトの場合E上の点、96バイトの場合E'上の点。それ以外の場合無効なデータ。C_bitが0の場合、s_stringが96バイトの場合E上の点、192バイトの場合E'上の点。それ以外の場合無効なデータ。
- s_string[0] = s_string[0] & 0x1fをセットし、メタデータのビットをクリアする。
- I_bitが1の場合、s_stringはすべて0でなければならない。すべて0であれば無限遠点を出力し、そうでない場合は無効なデータ。
- C_bitが0の場合(非圧縮形式)、s_stringの先頭半分をx_string、残り半分がy_stringとする。これら2つのデータを数値に変換し、(x, y)が曲線上の有効な点の場合、その点を出力する。それ以外の場合無効なデータ。
- それ以外の場合は圧縮形式なので、x座標からy座標を計算する。
- 手順2の結果E上の点である場合、 y2 = x3 + 4およびy = sqrt(y2) を計算し、GF(p)のデータかチェックする。
- E'上の点の場合、y2 = x3 + 4 * (1 + i)および y = sqrt(y2)を計算し、GF(p2)のデータかチェックする。
- yの符号を確認し、S_bitと等しければ、点(x, y)を出力する。S_bitと異なる場合は点(x, -y)を出力する。