Caloogy 文章
English

双线性配对与 BLS 签名:一万个签名压缩成一个

日期
2026 年 2 月 4 日
系列
密码学
阅读
3 分钟
主题
PairingBilinear mapBLSSignature aggregation

一句话版本

双线性配对是一个特殊的映射 e:G1×G2→GTe: G_1 \times G_2 \to G_T,满足 e(aP,bQ)=e(P,Q)abe(aP, bQ) = e(P, Q)^{ab}:两边的"系数"可以自由地在括号之间挪动。 有了它,BLS 签名只需要一行验证等式;更厉害的是,很多人的签名可以直接相加成一个,验证时只验这一个。以太坊每个时段有几十万验证者投票,靠的就是它。

全文分三层:

  1. 通俗理解:配对能做什么,签名聚合为什么重要
  2. 实际用处:以太坊共识层、zk-SNARK、Filecoin、门限签名
  3. 数学原理:双线性、BLS 签名与聚合、恶意公钥攻击,附玩具手算例子

第一层:通俗理解

1.1 椭圆曲线上缺了什么

在椭圆曲线群里,我们可以把点相加、乘以整数:已知 aPaP 和 bPbP,能算 aP+bP=(a+b)PaP + bP = (a+b)P。但不能把两个点"相乘"得到 abPabP,否则 Diffie–Hellman 就不安全了。

配对提供了一个折中:它不能直接算出 abPabP,但能检验"a⋅ba \cdot b 是否等于 cc",即使你只看到 aPaP、bQbQ、cPcP 而不知道 a,b,ca, b, c。这就像一台天平:你不知道每块砝码的重量,但能看出两边是否平衡。

1.2 为什么签名聚合重要

想象一个委员会有 1 万名成员,每个人都要对同一个区块签名。

对区块链来说,存储空间和验证时间都极其昂贵,这个区别是决定性的。


第二层:实际用处

场景 怎么用
以太坊共识层(2020 起,信标链) 验证者用 BLS12-381 曲线签名投票,同一委员会的签名聚合成一个;全网每个时段数十万验证者,靠聚合才扛得住
zk-SNARK(Groth16、KZG 承诺) 验证者用配对检查多项式等式
以太坊 EIP-4844(blob) KZG 承诺依赖配对
Filecoin、Chia、Dfinity BLS 签名、门限 BLS 产生随机信标
门限签名 BLS 天然适合配合Shamir秘密分享:tt 个份额签名用拉格朗日系数相加,就得到完整签名

代价:配对运算本身比较慢(一次配对约为一次椭圆曲线标量乘法的几倍到十几倍),而且依赖专门构造的"配对友好曲线"。

配对最早是一种攻击

1993 年的 MOV 攻击用配对把某些椭圆曲线上的离散对数"搬到"有限域里去解,从而攻破了这些曲线。直到 2000 年前后,Joux 的三方密钥交换、Boneh–Franklin 的基于身份加密、BLS 签名才把它变成建设性工具。


第三层:数学原理

3.1 双线性配对的定义

设 G1,G2,GTG_1, G_2, G_T 都是 rr 阶群(rr 为素数),G1,G2G_1, G_2 写成加法,GTG_T 写成乘法。映射 e:G1×G2→GTe: G_1 \times G_2 \to G_T 叫双线性配对,如果:

  1. 双线性:e(P1+P2,Q)=e(P1,Q) e(P2,Q)e(P_1 + P_2, Q) = e(P_1, Q)\,e(P_2, Q),e(P,Q1+Q2)=e(P,Q1) e(P,Q2)e(P, Q_1 + Q_2) = e(P, Q_1)\,e(P, Q_2)。由此推出 e(aP,bQ)=e(P,Q)abe(aP, bQ) = e(P, Q)^{ab}。
  2. 非退化:e(P,Q)≠1e(P, Q) \ne 1(对生成元)。
  3. 可高效计算(Miller 算法)。

用抽象代数的话说:固定一边,它在另一边是群同态。

实际的配对(Weil 配对、Tate 配对及其优化版本 ate 配对)定义在椭圆曲线的 rr-挠点上,GTG_T 是有限域扩张 Fpk×\mathbb{F}_{p^k}^\times 的子群,kk 叫嵌入次数。BLS12-381 的 k=12k = 12。

3.2 BLS 签名

设 PP 是 G1G_1 的生成元,HH 是把消息映射到 G2G_2 上的哈希函数("hash-to-curve")。

正确性一行搞定:

e(P,xH(m))=e(P,H(m))x=e(xP,H(m)).e(P, xH(m)) = e(P, H(m))^x = e(xP, H(m)).

BLS 签名还是确定性的(不需要随机数),天然避免了 ECDSA 那种随机数重用的事故(见《椭圆曲线》)。

3.3 聚合

nn 个人对同一条消息 mm 签名,把签名和公钥分别相加:

σ=∑iσi,pk=∑ipki.\sigma = \sum_i \sigma_i,\qquad \mathrm{pk} = \sum_i \mathrm{pk}_i.

由双线性,

e(P,σ)=∏ie(P,xiH(m))=e(∑ixiP, H(m))=e(pk,H(m)).e(P, \sigma) = \prod_i e(P, x_i H(m)) = e\Big(\sum_i x_i P,\ H(m)\Big) = e(\mathrm{pk}, H(m)).

一次配对等式就验完了所有人。不同消息也能聚合,只是验证时需要 n+1n+1 次配对。

3.4 手算例子(玩具配对)

真实配对没法手算,这里用一个不安全的玩具模型演示代数结构:

玩具:G1=G2=GT=(Z11,+)G_1 = G_2 = G_T = (\mathbb{Z}_{11}, +),P=1P = 1,e(a,b)=ab mod 11e(a, b) = ab \bmod 11

这个 ee 确实是双线性的(就是乘法的分配律),但这里的离散对数是平凡的(aPaP 就是 aa),所以毫无安全性,只用来看结构。

消息哈希 H(m)=5H(m) = 5。

私钥 公钥 签名 σ=x⋅5\sigma = x \cdot 5 验证 e(P,σ)e(P, \sigma) vs e(pk,H(m))e(\mathrm{pk}, H(m))
Alice 3 3 15≡415 \equiv 4 1⋅4=41 \cdot 4 = 4 vs 3⋅5=15≡43 \cdot 5 = 15 \equiv 4 ✓
Bob 7 7 35≡235 \equiv 2 1⋅2=21 \cdot 2 = 2 vs 7⋅5=35≡27 \cdot 5 = 35 \equiv 2 ✓
聚合 3+7=103 + 7 = 10 4+2=64 + 2 = 6 1⋅6=61 \cdot 6 = 6 vs 10⋅5=50≡610 \cdot 5 = 50 \equiv 6 ✓

聚合签名 66 对聚合公钥 1010 验证通过。(已用 Python 验算。)

3.5 恶意公钥攻击

聚合有一个陷阱。Mallory 看到 Alice 的公钥 pkA\mathrm{pk}_A 后,故意宣布自己的"公钥"为

pkM=yP−pkA.\mathrm{pk}_M = yP - \mathrm{pk}_A.

于是聚合公钥 pkA+pkM=yP\mathrm{pk}_A + \mathrm{pk}_M = yP,Mallory 知道 yy,可以独自伪造"Alice 和 Mallory 共同签名"。

对策:


总结

层次 要点
直觉 配对是一台"天平":不知道 a,ba, b 也能检验 ab=cab = c
代数 双线性:固定一边是群同态,e(aP,bQ)=e(P,Q)abe(aP, bQ) = e(P, Q)^{ab}
BLS 签名 =xH(m)= x H(m);签名和公钥都能直接相加聚合
工程 以太坊共识、zk-SNARK、KZG;要防恶意公钥;配对较慢