以太坊共識層 BLS 簽名數學推導:從橢圓曲線到門限簽名的完整密碼學解析
BLS 簽名是以太坊 PoS 共識層的核心密碼學基礎,支援高效的簽名聚合,讓成千上萬驗證者的簽名可以壓縮成區區 48 bytes。本文從群論基礎開始,詳細推導橢圓曲線點運算、雙線性配對、BLS 簽名生成與驗證、以及門限簽名的數學原理。涵蓋完整的代碼實現、性能分析、以及對常見誤解的澄清。
以太坊共識層 BLS 簽名數學推導:從橢圓曲線到門限簽名的完整密碼學解析
我跟很多以太坊開發者聊過,發現一個有趣的現象:大家都在用 BLS 簽名,但真正搞懂它背後數學原理的人卻不多。這不怪你們,網上大部分資料要么太浅、要么太數學、要么乾脆就是錯的。
這篇文章我決定用一種不一樣的方式來寫——不是堆砌公式,而是帶你一步步理解這些公式從哪裡來、為什麼長這樣、以及在以太坊裡到底是怎麼用的。咱們會從最基礎的群論開始,一路推到 BLS 簽名和聚合簽名的原理,最後講清楚以太坊共識層的簽名機制到底是怎麼回事。
一、密碼學基礎:群論視角
1.1 為什麼要從群論開始?
很多人學密碼學的順序搞反了——上來就記公式、背流程,結果換個場景就懵了。其實密碼學的精髓就三個字:離散對數。所有的非對稱密碼學——RSA、橢圓曲線、BLS——歸根結底都是在玩這個問題。
讓我解釋一下什麼是群:
群的定義:
一個集合 G 和一個二元運算 • 構成群 (G, •),當且僅當:
1. 封閉性:對所有 a, b ∈ G,a • b ∈ G
2. 結合律:(a • b) • c = a • (b • c)
3. 單位元:存在 e ∈ G,使得 a • e = e • a = a
4. 逆元:對每個 a ∈ G,存在 a⁻¹ ∈ G,使得 a • a⁻¹ = e
如果還滿足交換律 a • b = b • a,則稱為阿貝爾群。
例子:
- 整數加法 (Z, +) 是一個群
- 模 n 整數乘法 (Z_n*, ×) 是一個群
- 橢圓曲線上的點是一個群
1.2 橢圓曲線群
以太坊用的橢圓曲線叫做 BLS12-381。讓我直接說重點:
橢圓曲線密碼學的優點:
相比 RSA:
✓ 密鑰長度短:256 位 ≈ RSA 3072 位的安全性
✓ 運算速度快:點加法比大整數乘法快
✓ 存儲空間小:簽名只有 96 bytes
BLS12-381 的參數:
- 基域:Fp = 模 p 整數,p =
0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
- 曲線方程:y² = x³ + 4(在 Fp 上)
- 基點 G₁:G₁ = (0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14ef3aabe9
9158b, 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18c
b2f19e6e, 0x0)
- 階 n:n = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000
1.3 橢圓曲線點運算的推導
這裡是很多人暈掉的地方。橢圓曲線上的點加法到底怎麼算?讓我一步步推給你看。
曲線方程:y² = x³ + ax + b
以橢圓曲線 E: y² = x³ + 4 為例
定義:P = (x₁, y₁), Q = (x₂, y₂) 是曲線上的點
Case 1:P ≠ Q(不同點相加)
斜率 λ = (y₂ - y₁) / (x₂ - x₁)
然後:
x₃ = λ² - x₁ - x₂
y₃ = λ(x₁ - x₃) - y₁
為什麼是這個公式?
幾何意義:P + Q + R = O(無窮遠點)
代數推導:把直線方程代入曲線方程,解三次方程
實際上這段代數推導挺複雜的,但記住幾個要點就行:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 橢圓曲線點加法的直觀理解: │
│ │
│ 1. 兩點連線:P 和 Q 連成直線 │
│ 2. 求交點:直線第三次與曲線相交的點就是 R │
│ 3. 取反射:R 對 x 軸反射得到 P + Q │
│ │
│ 特殊情況: │
│ - P + O = P(O 是單位元,相當於「無窮遠點」) │
│ - P + (-P) = O(互為逆元,關於 x 軸對稱) │
│ - P + P = 2P(倍點,用切線公式) │
│ │
│ 密碼學意義: │
│ - 「已知 P 和 k,求 kP」是容易的(多倍點算法) │
│ - 「已知 P 和 Q = kP,求 k」是困難的(橢圓曲線離散對數) │
│ │
└─────────────────────────────────────────────────────────────┘
二、從離散對數到雙線性配對
2.1 離散對數問題
這是整個密碼學的核心:
離散對數問題 (DLP):
給定:
- 群 G,階為 n
- 生成元 g
- h = gˣ(h 在群中)
求解:
- 找到 x = log_g(h)
難度:
- 在大素數階的群中,目前沒有已知的多項式時間算法
- 計算複雜度 O(√n)(Birthday attack 需要 O(√n))
2.2 雙線性配對:讓乘法變成驗證
BLS 簽名厲害的地方在於它用到了雙線性配對。讓我解釋這是什麼。
雙線性配對的定義:
給定三個群 G₁, G₂, G_T,它們的階都是 n(質數)。
一個映射 e: G₁ × G₂ → G_T 是雙線性配對,如果:
1. 雙線性:
e(a·P, b·Q) = e(P, Q)^(ab)
對所有 P ∈ G₁, Q ∈ G₂, a,b ∈ Z
2. 非退化:
不存在 P ∈ G₁, Q ∈ G₂ 使得 e(P, Q) 是 G_T 的單位元
3. 可計算:
存在高效算法計算 e(P, Q)
簡單理解:
配對讓我們可以把「兩個群元素的乘積」映射到「第三個群」,
而且這個映射是雙線性的!
2.3 Tate 配對在 BLS12-381 上的實現
BLS12-381 的配對不是凭空来的,它用的是 Tate 配對的優化版本。具體數學推導太複雜了,但讓我說清楚概念:
配對計算的幾個關鍵步驟:
1. Miller 算法:
- 計算埋入多項式(Embedding Polynomial)
- 複雜度 O(log n)
2. 最終指數:
- 將結果規範化到 G_T
- 需要計算 n 次根
BLS12-381 的配對特點:
- G₁: 橢圓曲線點(定義在 Fp)
- G₂: 橢圓曲線點(定義在 Fp²,即二次擴域)
- G_T: 乘法群(定義在 Fp¹²)
為什麼 G₂ 在擴域上?
- 為了實現嵌入度(Embedding Degree)= 12
- 使得配對計算可行但足夠難
三、BLS 簽名的數學原理
3.1 從 ECDSA 到 BLS:為什麼要換?
以太坊最初的共識層用的是 ECDSA 簽名(跟比特幣一樣)。後來要轉 PoS 的時候,Vitalik 果斷選擇了 BLS。為什麼?
┌─────────────────────────────────────────────────────────────┐
│ │
│ ECDSA 的問題: │
│ │
│ - 簽名不能聚合:每個簽名獨立驗證 │
│ - 驗證複雜度:O(n) │
│ - 以太坊 1000 萬驗證者 × 2 個 簽名/區塊 = 悲劇 │
│ │
│ BLS 的優點: │
│ │
│ - 簽名可以聚合:任意數量的簽名聚合成一個 │
│ - 驗證複雜度:O(1) │
│ - 密鑰簡單:只需要一個私鑰 │
│ │
│ 代價: │
│ - 需要雙線性配對 │
│ - 配對計算比 ECDSA 驗證慢(但可接受) │
│ │
└─────────────────────────────────────────────────────────────┘
3.2 BLS 簽名方案:完整的數學推導
現在讓我正式介紹 BLS 簽名。假設我們有:
符號約定:
- G₁, G₂: 橢圓曲線群,階為 n
- g₁: G₁ 的生成元
- g₂: G₂ 的生成元
- e: G₁ × G₂ → G_T 的雙線性配對
- H: 密碼學哈希函數,輸出 G₁ 的元素
密鑰生成:
步驟:
1. 選擇隨機數 x ∈ Z_n 作為私鑰
2. 計算公鑰 P = x · g₂ ∈ G₂
這就是簡單的標量乘法,在橢圓曲線上很容易計算。
驗證「已知 g₂ 和 P,求 x」是離散對數問題,目前無高效算法。
簽名:
輸入:消息 m,私鑰 x
輸出:簽名 σ ∈ G₁
步驟:
1. 計算消息哈希:Q = H(m) ∈ G₁
2. 計算簽名:σ = x · Q
幾何直觀:
- Q = H(m) 是消息在曲線上的「代表點」
- σ = x·Q 把私鑰「乘」到這個點上
- 只有知道 x 才能計算 σ
驗證:
輸入:消息 m,公鑰 P = x·g₂,簽名 σ
輸出:接受或拒絕
步驟:
1. 計算 Q = H(m) ∈ G₁
2. 驗證配對等式:e(Q, P) = e(σ, g₂)
為什麼這個等式成立?
e(Q, P)
= e(Q, x·g₂) [P = x·g₂]
= e(x·Q, g₂) [配對的雙線性]
= e(σ, g₂) [σ = x·Q]
如果等式成立,說明 σ 確實是用 x 計算的。
如果等式不成立,說明 σ 不是合法的簽名。
3.3 為什麼 BLS 簽名安全?
BLS 簽名安全性基於:
1. 離散對數假設(DL):
已知 g₂ 和 P = x·g₂,計算 x 是困難的
2. 哈希到曲線的安全性:
H(m) 在 G₁ 上均勻分佈,不知道 H 的輸出無法構造假的 Q
3. 配對的安全性:
給定 Q 和 P,無法構造 σ 使得 e(Q, P) = e(σ, g₂)
(除非知道 x)
形式化證明:
假設存在攻擊者 A 能偽造簽名,
則可以構造算法解決離散對數問題。
四、簽名聚合的數學魔法
4.1 為什麼聚合是可能的?
BLS 最神奇的地方是簽名可以像數字一樣相加。讓我解釋這個魔法是怎麼發生的。
簽名聚合的原理:
假設有三個簽名者:
- 私鑰 x₁, x₂, x₃
- 公鑰 P₁ = x₁·g₂, P₂ = x₂·g₂, P₃ = x₃·g₂
- 消息 m₁, m₂, m₃
- 簽名 σ₁ = x₁·H(m₁), σ₂ = x₂·H(m₂), σ₃ = x₃·H(m₃)
聚合簽名:
σ_agg = σ₁ + σ₂ + σ₃
= x₁·H(m₁) + x₂·H(m₂) + x₃·H(m₃)
驗證(聚合驗證):
e(σ_agg, g₂) = e(σ₁ + σ₂ + σ₃, g₂)
= e(σ₁, g₂) · e(σ₂, g₂) · e(σ₃, g₂)
= e(x₁·H(m₁), g₂) · e(x₂·H(m₂), g₂) · e(x₃·H(m₃), g₂)
= e(H(m₁), x₁·g₂) · e(H(m₂), x₂·g₂) · e(H(m₃), x₃·g₂)
= e(H(m₁), P₁) · e(H(m₂), P₂) · e(H(m₃), P₃)
所以只需要驗證:
e(σ_agg, g₂) = e(H(m₁), P₁) · e(H(m₂), P₂) · e(H(m₃), P₃)
4.2 以太坊的具體應用
在以太坊共識層,每個 slot(12 秒)需要大量簽名:
以太坊共識層簽名需求:
- 每個 slot:約 400,000 驗證者參與投票
- 每個區塊:2 個 attestation(每個約 100,000 簽名聚合)
- 目標:1 個簽名驗證完成整個區塊
實現方式:
1. 每個 epoch(32 slots)的簽名聚合到單一聚合簽名
2. 聚合簽名大小固定:48 bytes(與單個 BLS 簽名相同)
3. 驗證時間固定:O(1)
計算:
- 不用聚合:400,000 × 96 bytes = 38.4 MB/區塊(不可能)
- 使用聚合:48 bytes/區塊(完全可以接受)
4.3 聚合器與同步委員會
以太坊的簽名聚合架構:
┌─────────────────────────────────────────────────────────────┐
│ │
│ Validator 節點: │
│ └── 計算自己的簽名 │
│ └── 發送到自己所屬的聚合器 │
│ │
│ 聚合器 (Aggregator): │
│ └── 每個 slot 有多個聚合器 │
│ └── 收集同一消息的所有簽名 │
│ └── 執行簽名聚合 │
│ └── 發布聚合簽名到網路 │
│ │
│ 同步委員會 (Sync Committee): │
│ └── 每 256 個 epoch(~27 小時)輪換 │
│ └── 512 個驗證者 │
│ └── 負責提供區塊頭.light_client_aggregate │
│ │
└─────────────────────────────────────────────────────────────┘
五、門限簽名與MPC
5.1 為什麼需要門限簽名?
想象一下:如果以太坊的驗證者私鑰被盜,會發生什麼?簡直是災難。所以以太坊用了一種叫做 三方門限 ECDSA(也叫 TSS,Threshold Signature Scheme)的方案來保護質押資金。
門限簽名的概念:
(n, t)-門限方案:
- n 個參與者
- 任何 ≥ t 個參與者聯合可以簽名
- 任何 < t 個參與者無法簽名
例子:
(3, 2)-門限:需要任意 2 個人才能簽名
應用場景:
- 以太坊驗證者:分散式密鑰管理
- 交易所熱錢包:降低單點故障風險
- 多簽錢包:提高安全性
5.2 秘密分享的數學原理
門限簽名的基礎是秘密分享。讓我從頭推導 Shamir 秘密分享:
Shamir 秘密分享:
目標:將秘密 s 分成 n 份,任何 ≥ t 份可以恢復
步驟 1:選擇隨機多項式
f(x) = s + a₁x + a₂x² + ... + a_{t-1}x^{t-1}
其中 a₁, ..., a_{t-1} 是隨機係數(在有限域 F_p 上)
步驟 2:計算分享
第 i 個參與者獲得 (i, f(i)),i = 1, 2, ..., n
為什麼任意 ≥ t 份可以恢復?
假設有 t 份:(x₁, y₁), (x₂, y₂), ..., (x_t, y_t)
構造拉格朗日插值:
f(x) = Σ_{j=1}^{t} y_j · L_j(x)
其中 L_j(x) = Π_{k≠j} (x - x_k)/(x_j - x_k)
特別地,s = f(0) = Σ_{j=1}^{t} y_j · L_j(0)
這個公式叫做拉格朗日插值公式。
5.3 門限 BLS 簽名的實現
現在把秘密分享應用到 BLS 簽名:
門限 BLS 簽名方案:
設定:(n, t)-門限,秘密 s 的公鑰 P = s·g₂
步驟 1:分發秘密份額
- 每個驗證者 i 獲得秘密份額 s_i
- s_i = f(i),其中 f(x) = s + a₁x + ... + a_{t-1}x^{t-1}
步驟 2:計算部分簽名
- 對消息 m,驗證者 i 計算 σ_i = s_i · H(m)
- 這叫做「部分簽名」
步驟 3:聚合部分簽名
- 收集 ≥ t 個部分簽名
- 使用拉格朗日插值恢復完整簽名:
σ = Σ_{i} σ_i · L_i(0)
= Σ_{i} s_i · H(m) · L_i(0)
= (Σ_{i} s_i · L_i(0)) · H(m)
= s · H(m)
驗證:
- e(σ, g₂) = e(H(m), P) 仍然成立
- 攻擊者需要 ≥ t 個份額才能構造 σ
5.4 以太坊的實際實現
以太坊共識層用的是 三方門限 BLS(並不是 ECDSA)。讓我說明:
以太坊質押的密鑰結構:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 提款憑證 (Withdrawal Credentials): │
│ - 定義資金的控制權 │
│ - 兩種類型: │
│ 1. BLS12-381 提款(0x00) │
│ 2. 執行層提款(0x01)- ETH2 升級後支持 │
│ │
│ 驗證者密鑰: │
│ - 用於簽署共識層消息 │
│ - 可以是三方密鑰(推薦)或單密鑰 │
│ - 通過助記詞衍生 │
│ │
│ 實際流程: │
│ 1. 用戶創建質押存款 │
│ 2. 指定提款地址(執行層) │
│ 3. 指定驗證者公鑰(共識層 BLS) │
│ 4. 質押合約鎖定 ETH │
│ 5. 驗證者開始參與共識 │
│ │
└─────────────────────────────────────────────────────────────┘
六、代碼實現
6.1 BLS 簽名驗證的 Python 實現
"""
BLS 簽名的概念實現
注意:這是教學用途,實際應用請使用成熟庫如 py_ecc 或 mcl
"""
class BLS12_381:
"""BLS12-381 曲線參數"""
# 質數
p = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
# 群的階
n = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000
# 基點
G1 = (0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14ef3aabe9158b,
0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2f19e6e)
G2 = (
# x coordinates
(0x30d3a0fc5195b5ece8225a5286db1df35d45c31a0db1c7eedda2e340b7ab8f0,
0x91eff53f5f2a8aa2e7a7e4c7f4c88e6b4c5f9e6a5e8e8e7e5e4e3e2e1e0),
# y coordinates
(0x0519533c15e7e1e2c7d3d3e4e5e6e7e8e9eaeafb0b1b2b3b4b5b6b7b8b9bab,
0x0bc3b6b6b5b4b3b2b1b0b9b8b7b6b5b4b3b2b1b0af9e8d7c6b5a4a3a2a1a0)
)
@staticmethod
def point_add(P, Q):
"""橢圓曲線點加法"""
# 這裡省略完整實現,需要用到射影坐標
# 實際使用中推薦用 mcl 或 relic 庫
pass
@staticmethod
def scalar_mul(P, k):
"""標量乘法(使用double-and-add)"""
result = (0, 0) # O 點(單位元)
base = P
while k:
if k & 1:
result = BLS12_381.point_add(result, base)
base = BLS12_381.point_add(base, base)
k >>= 1
return result
class BLSSignature:
"""BLS 簽名方案"""
def __init__(self, curve):
self.curve = curve
def keygen(self):
"""生成密鑰對"""
import secrets
# 選擇隨機私鑰
private_key = secrets.randbelow(self.curve.n)
# 計算公鑰
public_key = self.curve.scalar_mul(self.curve.G2, private_key)
return private_key, public_key
def hash_to_curve(self, message):
"""
將消息哈希到曲線上的點
實際實現需要使用专门设计的哈希函数如 HashToField
"""
import hashlib
# 簡化實現:直接哈希並取模
h = int.from_bytes(hashlib.sha256(message).digest(), 'big')
return (h % self.curve.p, 0) # 這不是真正的哈希到曲線
def sign(self, private_key, message):
"""BLS 簽名"""
# 將消息哈希到曲線
Q = self.hash_to_curve(message)
# 計算簽名:σ = sk · Q
signature = self.curve.scalar_mul(Q, private_key)
return signature
def verify(self, public_key, message, signature):
"""驗證 BLS 簽名"""
# 將消息哈希到曲線
Q = self.hash_to_curve(message)
# 配對驗證:e(Q, P) = e(σ, G₂)
# 這裡需要真正的配對實現
# 使用 mcl 庫時:pairing(Q, public_key) == pairing(signature, G1)
return True # 佔位
def aggregate_signatures(self, signatures):
"""聚合多個簽名"""
result = (0, 0) # O 點
for sig in signatures:
result = self.curve.point_add(result, sig)
return result
def aggregate_public_keys(self, public_keys):
"""聚合多個公鑰"""
result = (0, 0, (0, 0)) # O 點
for pk in public_keys:
result = self.curve.point_add(result, pk)
return result
# 使用示例
def main():
bls = BLSSignature(BLS12_381)
# 生成密鑰對
sk1, pk1 = bls.keygen()
sk2, pk2 = bls.keygen()
# 簽名
message = b"Hello, Ethereum!"
sig1 = bls.sign(sk1, message)
sig2 = bls.sign(sk2, message)
# 聚合簽名
agg_sig = bls.aggregate_signatures([sig1, sig2])
print(f"聚合後的簽名大小: {len(str(agg_sig))} bytes")
# 驗證(需要真正的配對庫)
print("BLS 簽名驗證成功")
if __name__ == "__main__":
main()
6.2 以太坊共識層簽名聚合的 Go 實現
// 以太坊共識層簽名聚合的簡化概念實現
// 實際使用請參考 go-ethereum/consensus/consensusshim
package consensus
import (
"crypto/bls12381"
"fmt"
)
type BlsSignature struct {
// BLS12-381 簽名,96 bytes
data [96]byte
}
type BlsPublicKey struct {
// BLS12-381 公鑰,48 bytes
data [48]byte
}
type BlsPrivateKey struct {
// BLS12-381 私鑰,32 bytes
data [32]byte
}
// Sign 簽名
func (sk *BlsPrivateKey) Sign(msg []byte) *BlsSignature {
// 使用 BLS12-381 G1 簽名
sig, err := bls12381.G1().Sign(sk.data[:], msg)
if err != nil {
panic(err)
}
result := &BlsSignature{}
copy(result.data[:], sig)
return result
}
// AggregateSignatures 聚合簽名
func AggregateSignatures(sigs []*BlsSignature) *BlsSignature {
if len(sigs) == 0 {
return nil
}
// 將所有簽名點相加
aggregated := bls12381.NewG1()
for _, sig := range sigs {
point, err := bls12381.G1().FromBytes(sig.data[:])
if err != nil {
continue
}
aggregated.Add(aggregated, point)
}
result := &BlsSignature{}
out, _ := aggregated.ToBytes(result.data[:])
copy(result.data[:], out)
return result
}
// FastAggregateVerify 快速聚合驗證
func (pk *BlsPublicKey) FastAggregateVerify(
msgs [][]byte,
sig *BlsSignature,
) bool {
// 1. 將所有消息哈希到 G1
g1Points := make([]*bls12381.PointG1, len(msgs))
for i, msg := range msgs {
point, err := bls12381.G1().HashToCurve(msg)
if err != nil {
return false
}
g1Points[i] = point
}
// 2. 聚合公鑰
pubKey, err := bls12381.G2().FromBytes(pk.data[:])
if err != nil {
return false
}
// 3. 驗證
sigPoint, err := bls12381.G1().FromBytes(sig.data[:])
if err != nil {
return false
}
// e(σ, G₂) = e(Σ H(mᵢ), P)
return bls12381.AggregateVerifyNoCheck([]*bls12381.PointG1{sigPoint},
[]*bls12381.PointG2{pubKey}, g1Points)
}
// Verify 單一驗證
func (pk *BlsPublicKey) Verify(msg []byte, sig *BlsSignature) bool {
// 將消息哈希到曲線
hashPoint, err := bls12381.G1().HashToCurve(msg)
if err != nil {
return false
}
// 獲取公鑰點
pubKey, err := bls12381.G2().FromBytes(pk.data[:])
if err != nil {
return false
}
// 獲取簽名點
sigPoint, err := bls12381.G1().FromBytes(sig.data[:])
if err != nil {
return false
}
// 配對驗證
return bls12381.PairingCheck([]*bls12381.PointG1{sigPoint},
[]*bls12381.PointG2{pubKey},
[]*bls12381.PointG1{hashPoint},
[]*bls12381.PointG2{bls12381.NewG2()})
}
// 以太坊共識層 Attestation 聚合
type Attestation struct {
Data *AttestationData
Signature *BlsSignature
AggregationBits []byte
}
type AttestationAggregator struct {
// 每個 slot 的聚合器
aggregators map[uint64][]*BlsPublicKey
// 當前 slot 的簽名
pendingSigs map[uint64][]*Attestation
}
func (a *AttestationAggregator) AggregateAttestations(
slot uint64,
attestations []*Attestation,
) *BlsSignature {
// 收集同一 slot、同一數據的所有簽名
sigs := make([]*BlsSignature, 0)
for _, att := range attestations {
if att.Data.Slot == slot {
sigs = append(sigs, att.Signature)
}
}
// 聚合簽名
return AggregateSignatures(sigs)
}
// VerifyAggregate 驗證聚合後的簽名
func (a *AttestationAggregator) VerifyAggregate(
pk *BlsPublicKey,
attestation *Attestation,
) bool {
// 構建即時驗證訊息
msg := attestation.Data.Hash()
// 驗證簽名
return pk.Verify(msg, attestation.Signature)
}
七、性能分析
7.1 運算複雜度比較
┌─────────────────────────────────────────────────────────────┐
│ │
│ 操作對比表: │
│ │
│ ┌─────────────────┬──────────┬──────────┬────────────────┐ │
│ │ 操作 │ ECDSA │ BLS │ 說明 │ │
│ ├─────────────────┼──────────┼──────────┼────────────────┤ │
│ │ 簽名生成 │ O(1) │ O(1) │ 兩者相當 │ │
│ │ 單一驗證 │ O(1) │ O(1) │ BLS 稍慢 │ │
│ │ 聚合驗證(1000) │ O(n) │ O(1) │ BLS 完勝 │ │
│ │ 密鑰生成 │ O(1) │ O(1) │ 兩者相當 │ │
│ │ 密鑰大小 │ 32B │ 32B │ 相同 │ │
│ │ 簽名大小 │ 64B │ 96B │ ECDSA 較小 │ │
│ │ 公鑰大小 │ 64B │ 48B │ BLS 較小 │ │
│ └─────────────────┴──────────┴──────────┴────────────────┘ │
│ │
│ 以太坊共識層的實際數據: │
│ - 每個區塊簽名數:~100,000 │
│ - ECDSA 驗證時間:~100,000 × 1ms = 100s │
│ - BLS 聚合驗證:48 bytes + 1ms ≈ 可接受 │
│ │
└─────────────────────────────────────────────────────────────┘
7.2 以太坊的量化數據
BLS 在以太坊共識層的應用數據(2026 Q1):
┌─────────────────────────────────────────────────────────────┐
│ │
│ 驗證者規模: │
│ - 總驗證者:~1,290,000 │
│ - 活躍驗證者:~1,100,000 │
│ - 質押總量:~41,100,000 ETH │
│ │
│ 簽名統計: │
│ - 每 epoch(32 slots):2 × 1,100,000 簽名 │
│ - 每天:2 × 1,100,000 × 225 ≈ 5 億簽名 │
│ - 每年:~1800 億簽名 │
│ │
│ 聚合效率: │
│ - 原始數據:1800 億 × 96 bytes ≈ 17 PB/年 │
│ - 聚合後:365 天 × 48 bytes ≈ 17 KB/年 │
│ - 壓縮比:不可思議的 10¹² 倍! │
│ │
└─────────────────────────────────────────────────────────────┘
八、常見問題與誤解
8.1 誤解一:BLS 簽名不安全
真相:
BLS 簽名的安全性基於:
1. 橢圓曲線離散對數問題(ECDLP)
2. 哈希到曲線的安全性
3. 配對的安全性
這些假設在密碼學界被廣泛接受。
BLS12-381 的安全等級約為 128 位。
比較:
- 對稱加密:AES-128
- 橢圓曲線:BLS12-381
- RSA:~3072 位才能達到同等安全等級
8.2 誤解二:BLS 簽名比 ECDSA 慢
真相:
- 單一簽名/驗證:確實 BLS 稍慢(需要配對)
- 聚合驗證:BLS 快得多(O(1) vs O(n))
在需要大量簽名的場景(如區塊鏈共識),
BLS 是更好的選擇。
8.3 誤解三:配對很貴
真相:
配對計算曾經很貴,但現在已經快很多了:
- 1990 年代:一秒鐘能做幾十次配對
- 2000 年代中期:優化到毫秒級
- 現在:微秒級,配對已經不是瓶頸
BLS12-381 的配對:
- 單次配對:~1-2 ms(在現代 CPU 上)
- 批量配對:可以進一步優化
九、總結
┌─────────────────────────────────────────────────────────────┐
│ │
│ 這篇文章的核心要點: │
│ │
│ 1. 密碼學基礎 │
│ ├── 群論是理解密碼學的語言 │
│ ├── 離散對數是 RSA/ECC/BLS 的共同基礎 │
│ └── 雙線性配對讓「驗證乘法」變得高效 │
│ │
│ 2. BLS 簽名原理 │
│ ├── 簽名:σ = sk · H(m) │
│ ├── 驗證:e(Q, P) = e(σ, G) │
│ └── 聚合:σ₁ + σ₂ + ... = Σ σᵢ │
│ │
│ 3. 以太坊應用 │
│ ├── 每個區塊成千上萬簽名聚合成 48 bytes │
│ ├── 驗證時間從 O(n) 降到 O(1) │
│ └── 是以太坊 PoS 高效運作的關鍵 │
│ │
│ 4. 門限簽名 │
│ ├── Shamir 秘密分享:t-of-n 門限 │
│ └── 讓密鑰管理更安全 │
│ │
│ 理解這些原理,你就能更好地理解以太坊為什麼選擇 BLS, │
│ 以及區塊鏈共識層的設計邏輯。 │
│ │
└─────────────────────────────────────────────────────────────┘
BLS 簽名不僅僅是一個密碼學工具,它是以太坊 PoS 系統能夠高效運作的關鍵基礎設施。理解它的數學原理,不僅能讓你寫出更安全的代碼,還能讓你對整個區塊鏈行業的技術選擇有更深入的洞察。
參考資料
- Boneh, D., Lynn, B., Shacham, H. "Short Signatures from the Weil Pairing." 2004.
- Kate, A., Zaverucha, G., Goldberg, I. "Constant-Size Commitments to Polynomials and Their Applications." 2010.
- Ethereum Foundation. "BLS12-381 Curve Parameters."
- Ethereum Foundation. "Ethereum 2.0 Beacon Chain Specification." 2026.
- Zcash Foundation. "BLS12-381: A Guide to the Zcash Curve."
- IETF. "BLS Signatures." draft-irtf-cfrg-bls-signature-05.
COMMIT: Add BLS signature mathematical derivation with elliptic curve cryptography guide
相關文章
- 以太坊密碼學原語直覺解釋:橢圓曲線、布隆過濾器與 Keccak 的工程視角 — 本文從工程師的視角出發,提供橢圓曲線、布隆過濾器(Blooom Filter)等密碼學原語的直覺性解釋、完整的數學推導、以及可直接使用的程式碼範例,幫助讀者建立對這些密碼學原語的深入理解。涵蓋 ECDSA 簽名、Keccak-256 哈希、布隆過濾器的設計原理與實際應用。
- 橢圓曲線密碼學直覺式圖解說明:從基礎原理到以太坊應用 — 本文以直覺式圖解說明讓讀者無需深厚數學背景也能理解橢圓曲線密碼學的核心概念。涵蓋橢圓曲線加法的幾何意義、離散對數問題的安全性基礎、以太坊地址生成的完整流程、ECDSA 簽名演算法、Vitalik 恢復機制,以及零知識電路和 Layer 2 中的橢圓曲線應用。
- 以太坊密碼學原語直覺式解析:橢圓曲線、布隆過濾器與默克爾樹的視覺化理解指南 — 本文以視覺化思考為核心方法,提供橢圓曲線、布隆過濾器和默克爾樹的直覺式解析。從物理類比出發,用現實世界的概念解釋抽象的密碼學原理,並說明每個原語在以太坊中的實際應用場景。
- 橢圓曲線離散對數問題複雜度分析:從數學基礎到密碼學安全 — 橢圓曲線離散對數問題(ECDLP)是現代密碼學最重要的數學假設之一,也是橢圓曲線密碼學安全性的基石。本文深入分析ECDLP的數學定義、Pollard's Rho等已知攻擊算法的複雜度、以及為什麼ECDLP在當前計算能力下是安全的。我們從群論基礎出發,逐步推導各種攻擊算法的複雜度,建立對橢圓曲線密碼學安全性的直觀理解。
- 橢圓曲線離散對數問題:從代數幾何到密碼學安全的直覺解釋 — 橢圓曲線離散對數問題(ECDLP)是以太坊密碼學安全的數學基石。本文從直覺出發,逐步建立對ECDLP的完整理解,涵蓋群論基礎、橢圓曲線幾何、離散對數問題的定義與困難性、以及在以太坊中的實際應用場景。我們將深入分析為何256位金鑰能提供與4096位RSA相當的安全性,並探討量子計算對現有密碼系統的潛在威脅。這是理解以太坊底層密碼學安全性的必讀文章。
延伸閱讀與來源
- Ethereum.org Developers 官方開發者入口與技術文件
- EIPs 以太坊改進提案完整列表
- Solidity 文檔 智慧合約程式語言官方規格
- EVM 代碼庫 EVM 實作的核心參考
- Alethio EVM 分析 EVM 行為的正規驗證
這篇文章對您有幫助嗎?
請告訴我們如何改進:
評論
發表評論
注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。
目前尚無評論,成為第一個發表評論的人吧!