一句话版本
双线性配对是一个特殊的映射 e:G1×G2→GT,满足 e(aP,bQ)=e(P,Q)ab:两边的"系数"可以自由地在括号之间挪动。
有了它,BLS 签名只需要一行验证等式;更厉害的是,很多人的签名可以直接相加成一个,验证时只验这一个。以太坊每个时段有几十万验证者投票,靠的就是它。
全文分三层:
- 通俗理解:配对能做什么,签名聚合为什么重要
- 实际用处:以太坊共识层、zk-SNARK、Filecoin、门限签名
- 数学原理:双线性、BLS 签名与聚合、恶意公钥攻击,附玩具手算例子
第一层:通俗理解
1.1 椭圆曲线上缺了什么
在椭圆曲线群里,我们可以把点相加、乘以整数:已知 aP 和 bP,能算 aP+bP=(a+b)P。但不能把两个点"相乘"得到 abP,否则 Diffie–Hellman 就不安全了。
配对提供了一个折中:它不能直接算出 abP,但能检验"a⋅b 是否等于 c",即使你只看到 aP、bQ、cP 而不知道 a,b,c。这就像一台天平:你不知道每块砝码的重量,但能看出两边是否平衡。
1.2 为什么签名聚合重要
想象一个委员会有 1 万名成员,每个人都要对同一个区块签名。
- 普通签名(ECDSA、Schnorr):要存储和验证 1 万个签名。
- BLS 签名:1 万个签名直接相加成一个 96 字节的签名,验证时把 1 万个公钥也加起来,做一次检查即可。
对区块链来说,存储空间和验证时间都极其昂贵,这个区别是决定性的。
第二层:实际用处
| 场景 |
怎么用 |
| 以太坊共识层(2020 起,信标链) |
验证者用 BLS12-381 曲线签名投票,同一委员会的签名聚合成一个;全网每个时段数十万验证者,靠聚合才扛得住 |
| zk-SNARK(Groth16、KZG 承诺) |
验证者用配对检查多项式等式 |
| 以太坊 EIP-4844(blob) |
KZG 承诺依赖配对 |
| Filecoin、Chia、Dfinity |
BLS 签名、门限 BLS 产生随机信标 |
| 门限签名 |
BLS 天然适合配合Shamir秘密分享:t 个份额签名用拉格朗日系数相加,就得到完整签名 |
代价:配对运算本身比较慢(一次配对约为一次椭圆曲线标量乘法的几倍到十几倍),而且依赖专门构造的"配对友好曲线"。
配对最早是一种攻击
1993 年的 MOV 攻击用配对把某些椭圆曲线上的离散对数"搬到"有限域里去解,从而攻破了这些曲线。直到 2000 年前后,Joux 的三方密钥交换、Boneh–Franklin 的基于身份加密、BLS 签名才把它变成建设性工具。
第三层:数学原理
3.1 双线性配对的定义
设 G1,G2,GT 都是 r 阶群(r 为素数),G1,G2 写成加法,GT 写成乘法。映射 e:G1×G2→GT 叫双线性配对,如果:
- 双线性:e(P1+P2,Q)=e(P1,Q)e(P2,Q),e(P,Q1+Q2)=e(P,Q1)e(P,Q2)。由此推出 e(aP,bQ)=e(P,Q)ab。
- 非退化:e(P,Q)=1(对生成元)。
- 可高效计算(Miller 算法)。
用抽象代数的话说:固定一边,它在另一边是群同态。
实际的配对(Weil 配对、Tate 配对及其优化版本 ate 配对)定义在椭圆曲线的 r-挠点上,GT 是有限域扩张 Fpk× 的子群,k 叫嵌入次数。BLS12-381 的 k=12。
3.2 BLS 签名
设 P 是 G1 的生成元,H 是把消息映射到 G2 上的哈希函数("hash-to-curve")。
- 私钥:x;公钥:pk=xP
- 签名:σ=x⋅H(m)
- 验证:e(P,σ)=?e(pk,H(m))
正确性一行搞定:
e(P,xH(m))=e(P,H(m))x=e(xP,H(m)).
BLS 签名还是确定性的(不需要随机数),天然避免了 ECDSA 那种随机数重用的事故(见《椭圆曲线》)。
3.3 聚合
n 个人对同一条消息 m 签名,把签名和公钥分别相加:
σ=i∑σi,pk=i∑pki.
由双线性,
e(P,σ)=i∏e(P,xiH(m))=e(i∑xiP, H(m))=e(pk,H(m)).
一次配对等式就验完了所有人。不同消息也能聚合,只是验证时需要 n+1 次配对。
3.4 手算例子(玩具配对)
真实配对没法手算,这里用一个不安全的玩具模型演示代数结构:
玩具:G1=G2=GT=(Z11,+),P=1,e(a,b)=abmod11
这个 e 确实是双线性的(就是乘法的分配律),但这里的离散对数是平凡的(aP 就是 a),所以毫无安全性,只用来看结构。
消息哈希 H(m)=5。
|
私钥 |
公钥 |
签名 σ=x⋅5 |
验证 e(P,σ) vs e(pk,H(m)) |
| Alice |
3 |
3 |
15≡4 |
1⋅4=4 vs 3⋅5=15≡4 ✓ |
| Bob |
7 |
7 |
35≡2 |
1⋅2=2 vs 7⋅5=35≡2 ✓ |
| 聚合 |
|
3+7=10 |
4+2=6 |
1⋅6=6 vs 10⋅5=50≡6 ✓ |
聚合签名 6 对聚合公钥 10 验证通过。(已用 Python 验算。)
3.5 恶意公钥攻击
聚合有一个陷阱。Mallory 看到 Alice 的公钥 pkA 后,故意宣布自己的"公钥"为
pkM=yP−pkA.
于是聚合公钥 pkA+pkM=yP,Mallory 知道 y,可以独自伪造"Alice 和 Mallory 共同签名"。
对策:
- 持有证明(proof of possession):注册公钥时必须用对应私钥签一条特定消息,证明你知道私钥。以太坊验证者存款时就要提交这个。
- 或者给每个公钥乘一个由所有公钥哈希出来的系数(类似 MuSig 对 Schnorr 的处理,见《Schnorr签名》)。
总结
| 层次 |
要点 |
| 直觉 |
配对是一台"天平":不知道 a,b 也能检验 ab=c |
| 代数 |
双线性:固定一边是群同态,e(aP,bQ)=e(P,Q)ab |
| BLS |
签名 =xH(m);签名和公钥都能直接相加聚合 |
| 工程 |
以太坊共识、zk-SNARK、KZG;要防恶意公钥;配对较慢 |