📑

Mastering Ethereum追加解説1(BLS Digital Signatures)

に公開

Mastering Ethereum 第2版 第4章 Cryptography で躓いた BLS 署名を“素人向け”に解きほぐす

日付: 2025年12月15日
学習内容: Mastering Ethereum(第2版)第4章 Cryptography の学習中に詰まった BLS Digital Signatures(BLS12-381 / ペアリング / 集約署名 / q と r)を、できるだけ丁寧に整理して理解する

1. 学習の背景と目的

1.1 背景:なぜ BLS で詰まったのか

Ethereum を学んでいると「署名」と言えば ECDSA がまず出てきますが、PoS(Beacon Chain)では BLS 署名が登場します。Mastering Ethereum 第4章でも暗号の流れの中で BLS が出てくるのですが、ここで自分は次の点で理解が止まりました。

  • 見慣れない数学が一気に増える
    • 楕円曲線の式 y^2=x^3+4
    • 0x1a0111ea... のような 115 桁級の巨大な法(modulus)
    • 0x73eda753... のような別の巨大な数(位数 r)
    • ペアリング e(\cdot,\cdot) という新しい道具
  • “何がどこで mod されているのか” が混乱する
    • 座標の mod と、秘密鍵(スカラー)の mod が別物
  • 検証式・集約式が一見すると魔法
    • なぜ e(g_1,\sigma)=e(pk,H(m)) が検証になるのか
    • なぜ \sigma を足すだけで集約できるのか

この混乱を解くために、理解した内容を 背景付きで“読める文章”に再構成したものです。

1.2 この記事のゴール

読み終わった時に、次が腹落ちしている状態を目指します。

  1. 0x1a0111ea...(q)と 0x73eda753...(r)の役割の違い
  2. BLS の鍵・署名・検証が、何の性質(双線形性)で成立するか
  3. 集約署名が“足し算だけ”で成り立つ理由
  4. Ethereum PoS で BLS を使う実務上の意味(大量署名の圧縮)

2. まず超入門:mod(剰余)とは何か

**mod(モジュロ)**は「余りだけを気にして、同じ余りの数を同一視する」という約束です。

例:mod 7 の世界では、

  • 15 \equiv 1 \pmod 7
  • -1 \equiv 6 \pmod 7

のように、7で割った余りが同じなら同じ数として扱います。直感的には「7時間制の時計」です。


3. 一番大事:BLS12-381 には “2つの巨大な数” が出てくる

3.1 q(115桁級)は「座標の世界の法」

楕円曲線の式 y^2=x^3+4 は、普通の整数の世界で解くのではなく、有限体 \mathbb{F}_q 上で考えます。つまり “本当は” 次の意味です:

y^2 \equiv x^3 + 4 \pmod q

ここでの q が、Ethereum の資料でよく見るこの値です(16進表記):

  • q(基礎体の法):
    0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab

この数字が表しているのは、難しいことではなく、

  • 「点の座標 x,y を計算するときに、結果は全部 mod q で丸める」

というルールそのものです。

3.2 r(77桁級)は「秘密鍵(スカラー)の世界の法」

一方で、秘密鍵 sk は座標ではなく「点を何回足すか」という **回数(スカラー)**です。これは別の有限体 \mathbb{F}_r の要素として扱います。

Ethereum の資料でよく見る r は次です(16進表記):

  • r(スカラー体の法):
    0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001

ここが重要で、

  • q: 座標 x,y を計算する “盤面” の大きさ
  • r: 暗号で使う “ループの長さ(部分群の位数)”

という 役割分担があります。

3.4 なぜ q と r は “別の素数” なのか

ここもつまずきポイントなので、結論から書きます:

  • q と r は、そもそも “割り算で閉じた世界” の対象が違う(役割が違う)ため、別の素数になるのが自然です。

もう少し丁寧に分けると、理由は大きく3つあります。

理由1:q は「座標を計算する世界」、r は「点を何回足すか(スカラー)の世界」

  • q は \mathbb{F}_q の法で、曲線点の座標 x,y の足し算・掛け算・逆数などは mod q で行います。
  • r は \mathbb{F}_r の法で、秘密鍵 sk や「何倍するか」の係数は mod r で扱います。

つまり、同じ“mod”でも対象が違い、同じ素数を使う必然性がありません。

理由2:安全に使うために「素数位数 r の部分群」を切り出す必要がある

楕円曲線上の点の集合 E(\mathbb{F}_q) の点の個数(位数)は、一般に

\#E(\mathbb{F}_q) = h \cdot r

のように「大きな素数 r」に「小さな係数 h(コファクタ)」が掛かった形になります。

暗号で使う G_1, G_2 は、点全部ではなく 素数位数 r の部分群(ループ長が r の世界)を使います。
こうしておかないと、小さい位数の部分に落とし込む攻撃(いわゆる小さい部分群関連の問題)が起きやすくなります。

この構造上、r は「点の個数(位数)の大きな素数因子」として現れ、座標の法 q と一致するとは限りません(むしろ一致しないのが普通です)。

理由3:ペアリングが必要な “ペアリングフレンドリー曲線” の設計上、q と r は別に選ばれる

BLS 署名はペアリング e: G_1 \times G_2 \to G_T を使います。
このペアリングが高速に計算でき、かつ安全になるように、曲線は「特別な数論条件」を満たすように設計されています。

代表的には(詳細は覚えなくてOKですが)、

  • r が q^k - 1 を割る(埋め込み次数 k という概念が出てくる)

のような条件があり、BLS12-381 では名前の通り k=12 が関係します。
こうした条件を満たすために、q(座標の法)と r(部分群の位数)は 別の巨大素数として選ぶのが普通です。


3.3 なぜ秘密鍵は 1〜r-1 から選ぶの?

秘密鍵 sk はスカラーなので、数学的には

sk \in \{0,1,2,\dots,r-1\}

から選べますが、0だけは避けます。なぜなら

  • pk = sk \cdot g_1 で sk=0 だと pk が “ゼロ点”(無限遠点)になり、鍵として意味がない
  • \sigma = sk \cdot H(m) も 0 になってしまい、署名として意味がない

からです。なので実装ではふつう

1 \le sk \le r-1

の一様ランダムが使われます。


4. このメモの流儀(重要):pk は G1、署名 σ は G2

ここから先は、次の配置に統一して説明します(この記事で扱う流儀)。

  • 生成元 g_1 \in G_1
  • 公開鍵 pk = sk \cdot g_1 \in G_1
  • ハッシュ H: \{0,1\}^* \to G_2(メッセージを G_2 の点にする)
  • 署名 \sigma = sk \cdot H(m) \in G_2
  • ペアリング e: G_1 \times G_2 \to G_T

「なんで署名が G_2?」という疑問は自然ですが、ここは 実装設計(高速化・表現)上の都合でこう置く流儀もある、くらいにまずは割り切って OK です。大事なのは「両辺が同じ値になる」ことです。

4.1 公開鍵 pk は「点」であり、座標 (x,y) はその表現の1つ

公開鍵 pk は 楕円曲線上の点です。数学的には「点そのもの」が公開鍵で、座標で書けば

  • pk = (x,y)(ただし x,y \in \mathbb{F}_q)

のように表せます。

ただし 実装でネットワークに載せたりファイルに保存したりするとき、毎回 (x,y) をそのまま “単純に連結” して表現するとは限りません。

  • 概念(数学): 公開鍵 = 点 pk(必要なら (x,y) で書ける)
  • 実装(バイト列): 公開鍵 = 点をルールに従ってエンコードしたバイト列
    • 典型的には 圧縮形式(例:x と y の符号ビット等)で表現し、サイズを小さくします

このため、「x と y を連結したものが公開鍵か?」という問いへの答えは、

  • 数学的には「公開鍵は点(座標はその表示方法)」
  • 実装的には「仕様で定められたシリアライズ(エンコード)形式が公開鍵」

になります。

4.2 生成元 g_1 とは何か(sk=1 のときの公開鍵と同じ?)

g_1 は G_1 の **生成元(generator)**として、仕様や実装で固定されている「基準点」です。

公開鍵は pk = sk \cdot g_1 なので、

  • たしかに sk=1 なら pk = 1 \cdot g_1 = g_1

となります。したがって「g_1 は “秘密鍵が1のときの公開鍵の点”」という理解は 結果としては正しいです。

ただし本質は、

  • g_1 は「秘密鍵から導くもの」ではなく、最初から固定で与えられる点
  • その点を sk 回足したもの(スカラー倍)が公開鍵になる

という関係です。


5. BLS 検証式が成立する理由(式変形を省略しない)

検証でチェックしたいのは、「この \sigma は本当に sk を知る人が作ったか?」です。

5.0 署名・検証で “実際に何をやり取りするか”

ここが一番イメージしづらい所なので、先に入出力を書きます。

  • 署名者(秘密鍵所有者)が持っているもの

    • 秘密鍵 sk
    • 生成元 g_1(固定)
    • ハッシュ関数(hash-to-curve)H(\cdot)
  • 署名者が受け取るもの

    • メッセージ m(署名したい内容)
  • 署名者が計算するもの(署名の生成)

    1. H(m) \in G_2 を計算(メッセージを曲線上の点に写す)
    2. \sigma = sk \cdot H(m) \in G_2 を計算
  • 署名者が外部へ渡すもの(最低限)

    • メッセージ m
    • 署名 \sigma(点をエンコードしたバイト列)
    • 公開鍵 pk(相手が既に知っている/登録済みなら省略できる)
  • 検証者が計算するもの(検証)

    1. 公開鍵が必要なら pk を受け取る(または事前に取得)
    2. 自分でも H(m) \in G_2 を計算
    3. ペアリングを2回計算して比較する:
      • 左辺:e(g_1,\sigma)
      • 右辺:e(pk,H(m))
      • 一致すれば「sk を知る人が作った署名」と判断

ここで重要なのは、検証者は 秘密鍵 sk を一切受け取らないことです。
代わりに「ペアリングを使うと、sk を使った関係式が両辺で一致するかどうかを見られる」ので検証できます。

5.0.1 おもちゃの数で「本当に計算してみる」例(手計算できるサイズ)

本物のBLS12-381は桁が大きすぎて手計算が不可能なので、仕組みだけ同じになるように **小さい数で作った“おもちゃ例”**を使います(※安全性はありません)。

おもちゃ設定

  • スカラーの世界(秘密鍵など)は位数 r=7 の世界(0..6)で考える
  • ペアリングの出力側は mod p=29 の乗法群の中の「位数7の部分」を使う
    • 位数7の元として g=7 を採用(7^7 \equiv 1 \pmod{29})

おもちゃのペアリングを次で定義します:

e(P,Q) := g^{P\cdot Q} \bmod p

ここで P,Q は「0..6 の数(加法群の元)」だと思ってください(本物では P,Q は曲線上の点ですが、手計算のために“数で代用”しています)。

署名者がやること(入力:m、出力:\sigma)

  1. 固定の生成元を g_1=1 とします(おもちゃなので G_1 の生成元を “1” と見なす)。
  2. 秘密鍵を sk=3(本当は 1..r-1 からランダム)とします。
  3. メッセージ m をハッシュして H(m)=2 にする(おもちゃなので「m \mapsto 2」と決め打ち)。

公開鍵:

pk = sk\cdot g_1 = 3\cdot 1 \equiv 3 \pmod 7

署名:

\sigma = sk\cdot H(m) = 3\cdot 2 \equiv 6 \pmod 7

署名者が検証者に渡す情報は(最低限):

  • メッセージ m
  • 署名 \sigma=6
  • 公開鍵 pk=3(検証者が事前に知っていれば不要)

検証者がやること(受け取った m,\sigma,pk で検証)

検証者も同じハッシュを使って H(m)=2 を計算し、次をチェックします:

e(g_1,\sigma) \stackrel{?}{=} e(pk,H(m))

左辺:

e(g_1,\sigma)=e(1,6)=g^{1\cdot 6}\bmod 29 = 7^6 \bmod 29

7^6 \equiv 25 \pmod{29} なので、左辺は 25。

右辺:

e(pk,H(m))=e(3,2)=g^{3\cdot 2}\bmod 29 = 7^6 \bmod 29 = 25

左右が一致(25=25)したので「この署名は sk を知る人が作った」と判断できます。
重要なのは、検証者は sk=3 を知らない/受け取らないのに、成立チェックができている点です。

まとめると、署名者は「sk を使って \sigma を作る」だけ、検証者は「m から同じ H(m) を作り、ペアリングの等式が成立するか見る」だけです。

5.1 鍵と署名の定義(もう一度)

pk = sk \cdot g_1
\sigma = sk \cdot H(m)

5.2 使うのは“双線形性”だけ

ペアリングには次が成り立ちます:

e(aP, Q) = e(P, Q)^a,\quad e(P, bQ) = e(P, Q)^b

特に重要なのがこの形です:

e(aP, Q) = e(P, aQ)

(両辺とも e(P,Q)^a だから)

5.2.0 直感:「足し算が積に分かれる」ってどういうこと?

記事の後半で使う

  • e(P_1+P_2, Q) = e(P_1, Q)\cdot e(P_2, Q)
  • e(P, Q_1+Q_2) = e(P, Q_1)\cdot e(P, Q_2)

という性質は、言葉だけだと不思議に見えます。直感のコアはこれです:

ペアリングは「点(足し算の世界)」を「指数(掛け算の世界)」へ写しているので、
“足し算” が “掛け算” に変わって見える。

まず、おもちゃ例で一発で見る

おもちゃ例では

e(P,Q) := g^{P\cdot Q}\bmod p

でした。ここで P_1,P_2 を足すとどうなるか:

e(P_1+P_2, Q) = g^{(P_1+P_2)\cdot Q}

指数の分配で

g^{(P_1+P_2)\cdot Q} = g^{P_1Q + P_2Q}

そして指数の基本法則 g^{a+b}=g^a\cdot g^b から

g^{P_1Q + P_2Q} = g^{P_1Q}\cdot g^{P_2Q}

つまり

e(P_1+P_2, Q) = e(P_1,Q)\cdot e(P_2,Q)

になります。これが「足し算が積に分かれる」の正体です。

本物のペアリングでも“やっていることの型”は同じ

本物のBLS12-381では式はもっと複雑ですが、性質として

  • P \mapsto e(P,Q)(Q を固定したとき)
  • Q \mapsto e(P,Q)(P を固定したとき)

がそれぞれ **群の準同型(homomorphism)**になっています。

超ざっくり言うと、

  • 点の世界(G_1,G_2)では演算は「足し算」
  • 出力の世界(G_T)では演算は「掛け算」

なので、準同型として “足し算が掛け算に写る” 形になり、

e(P_1+P_2,Q)=e(P_1,Q)e(P_2,Q)

が成り立ちます(BLSの集約署名は、まさにこの性質に依存します)。

5.2.1 本物のペアリング e(P,Q) はどう定義されるのか(BLS12-381の概観)

おもちゃ例では e(P,Q)=g^{P\cdot Q}\bmod p のように “掛け算” で作りましたが、本物のBLS12-381では、e は次のような流れで定義・計算される 暗号用ペアリングです。

まず前提:どこからどこへの写像か

BLS12-381 では

e: G_1 \times G_2 \to G_T

で、

  • G_1 は楕円曲線 E/\mathbb{F}_q 上の 素数位数 r の部分群
  • G_2 は同じ曲線の **ねじれ(twist)**を使って \mathbb{F}_{q^2} 上に持ち上げた点の素数位数 r の部分群
  • G_T は拡大体 \mathbb{F}_{q^{12}} の乗法群の中の位数 r の部分(概念的には「位数 r の循環群」)

という関係にあります(BLS12-381 の “12” はこの q^{12} に関係します)。

直感:G_T は「ペアリングの結果が入る“別の箱”」だと思えばOK

素人目線で一番大事なのは、G_T を“具体的な式”で理解するより、

  • e(P,Q) の結果が属する先(出力の箱)
  • その箱の中で 掛け算とべき乗ができる
  • しかも e(aP,Q)=e(P,Q)^a のような 双線形性が成り立つ

という役割です。

おもちゃ例に対応させると、

  • おもちゃ例の G_T は「mod p の乗法群(1..p-1 の掛け算世界)」の一部でした
  • 本物のBLS12-381の G_T は「拡大体 \mathbb{F}_{q^{12}} の乗法群」の一部です

つまり G_T は、「点(G_1,G_2)をそのまま比べる代わりに、比較しやすい“数の世界”へ写した結果を比べるための場所」だと思うと理解が進みます。

もう一つの言い方をすると、G_T は

  • G_1,G_2(点の世界)での “足し算・スカラー倍” の関係を
  • G_T(数の世界)での “掛け算・べき乗” の関係として保存する

ための中継地点です。BLSの検証式は、まさにこの対応関係(双線形性)だけを使っています。

定義の中身(概念):Miller関数 → 最終べき乗

本物のペアリングは、ざっくり言うと

  1. Miller loop で「ある有理関数の値」を計算して f \in \mathbb{F}_{q^{12}}^* を得る
  2. **final exponentiation(最終べき乗)**で f^{(q^{12}-1)/r} を計算して、値を位数 r の世界 G_T に“正規化”する

という2段階で定義されます。

数式としては(詳細を隠して書くと)次の形だと思ってよいです:

e(P,Q) := f(P,Q)^{(q^{12}-1)/r}

ここで f(P,Q) は Miller のアルゴリズムで計算される値(「点 P,Q から作る関数値」)で、e(P,Q) が G_T の元(位数 r の元)になるように最後に指数を掛けています。

実装でよく聞く言い方:optimal ate pairing

実装の説明では、BLS12-381 のペアリングは多くの場合

  • optimal ate pairing(最適Ateペアリング)

と呼ばれ、実際の計算は

  • Miller loop(曲線パラメータに由来する回数だけ反復)
  • final exponentiation(q^{12}-1 を利用して効率化)

で行われます。

この記事では「どう計算するか(アルゴリズム詳細)」よりも、「こう定義された e が双線形性を満たすので BLS の検証・集約が動く」ことが重要、という位置づけです。

5.3 検証式

BLS の検証は次です:

e(g_1,\sigma) \stackrel{?}{=} e(pk,H(m))

左辺に署名を代入:

e(g_1,\sigma) = e(g_1, sk \cdot H(m))

双線形性で指数(sk)を外に出すと:

e(g_1, sk \cdot H(m)) = e(g_1, H(m))^{sk}

右辺に公開鍵を代入:

e(pk,H(m)) = e(sk \cdot g_1, H(m))

同じく双線形性で:

e(sk \cdot g_1, H(m)) = e(g_1, H(m))^{sk}

左辺も右辺も 同じ e(g_1,H(m))^{sk} になるので、等式が成り立ちます。

つまり検証は「秘密鍵 sk を知らなくても、両辺が一致するかで正当性を確認できる」という仕組みです。


6. 集約署名が“足し算だけ”で成り立つ理由

Ethereum PoS で BLS が重要な理由はここです。attestation などで「同じ内容に多人数が署名」するので、署名をまとめられると強いです。

6.1 まず定義:集約する

同じメッセージ m に対して、参加者 i=1..n が署名したとします。

pk_i = sk_i \cdot g_1,\quad \sigma_i = sk_i \cdot H(m)

集約公開鍵と集約署名を “足し算” で作ります:

pk_{\mathrm{agg}} = \sum_{i=1}^n pk_i,\quad \sigma_{\mathrm{agg}} = \sum_{i=1}^n \sigma_i

6.2 検証式(集約版)

検証したい式はこれです:

e(g_1,\sigma_{\mathrm{agg}}) \stackrel{?}{=} e(pk_{\mathrm{agg}},H(m))

右辺・左辺が同じになることを示します。

左辺:

e(g_1,\sigma_{\mathrm{agg}}) = e\left(g_1,\sum_{i=1}^n \sigma_i\right)

ペアリングは “足し算が積に分かれる” 性質があるので:

e\left(g_1,\sum_{i=1}^n \sigma_i\right) = \prod_{i=1}^n e(g_1,\sigma_i)

各 \sigma_i = sk_i H(m) を代入:

\prod_{i=1}^n e(g_1, sk_i H(m)) = \prod_{i=1}^n e(g_1, H(m))^{sk_i} = e(g_1, H(m))^{\sum_{i=1}^n sk_i}

右辺も同様に:

e(pk_{\mathrm{agg}},H(m)) = e\left(\sum_{i=1}^n pk_i, H(m)\right) = \prod_{i=1}^n e(pk_i, H(m))

各 pk_i = sk_i g_1 を代入:

\prod_{i=1}^n e(sk_i g_1, H(m)) = \prod_{i=1}^n e(g_1, H(m))^{sk_i} = e(g_1, H(m))^{\sum_{i=1}^n sk_i}

左右とも同じ値になり、検証できます。

6.3 直感(数式の意味)

集約が効くのは、BLS が「署名が点で、点の足し算が自然に定義されている」からです。

  • 署名は \sigma_i = sk_i H(m)
  • それを足すと \sigma_{\mathrm{agg}} = (\sum sk_i)H(m) と同じ形になる

この「足すだけで、秘密鍵を足したのと同じ効果になる」性質が、PoS の大量署名にハマります。


7. PoS での “意味” に戻る(なぜ BLS なのか)

PoS(Beacon Chain)では、ブロック提案・attestation・sync committee などで 大量の署名が発生します。

  • もし署名が 1 人 1 本のままだと、ブロックが署名だらけになって帯域・検証コストが増える
  • BLS なら、多数の署名を 集約して 1 本として扱える

つまり BLS は「数学がオシャレだから」ではなく、プロトコルが要求する“スケール”に直結する道具です。


8. つまずきポイントチェックリスト(自分用メモ)

  • 0x1a0111ea... は 座標の法 q(\mathbb{F}_q)
  • 0x73eda753... は スカラーの法 r(\mathbb{F}_r)
  • 秘密鍵は 1..r-1(0はダメ)
  • この流儀では pk\in G_1、\sigma\in G_2、H(m)\in G_2
  • 検証は 双線形性で両辺が同じ e(g_1,H(m))^{sk} に揃う
  • 集約は「点の足し算」と「ペアリングが積に分かれる」性質で成立する

Discussion