优化EVM中的BLS多重签名

1. 引言

前序博客有:

BLS signautre要求能够将(相同或者不同)curve上的P和Q两个点映射a number:
e ( P , Q ) ↦ n e(P,Q)\mapsto n e(P,Q)n
同时,应满足如下属性:(使得secret number x x x unreveal。)
e ( x × P , Q ) = e ( P , x × Q ) e(x\times P,Q)=e(P,x\times Q) e(x×P,Q)=e(P,x×Q)
更通用的表达为应具有如下属性:
e ( a × P , b × Q ) = e ( P , a b × Q ) = e ( a b × P , Q ) = e ( P , Q ) ( a b ) e(a\times P,b\times Q)=e(P,ab\times Q)=e(ab\times P,Q)=e(P,Q)^{(ab)} e(a×P,b×Q)=e(P,ab×Q)=e(ab×P,Q)=e(P,Q)(ab)

由于以上同态属性,使得BLS签名支持:

  • signature aggregation:以非交互方式对同一消息生成聚合签名,以及对不同消息 m i m_i mi的不同签名进行聚合(即支持combine all signatures in the block)。
  • key aggregation:m-of-n签名。

2. BLS签名

BLS签名机制要求a pairing friendly curve以及可对基域 F q \mathbb{F}_q Fq以及2个source group G 1 , G 2 \mathbb{G}_1,\mathbb{G}_2 G1,G2进行快速计算。 F r \mathbb{F}_r Fr为该curve的scalar域。

回顾下适于EVM的BLS签名版本中有:

  • generator G ∈ G 2 G\in \mathbb{G}_2 GG2
  • 私钥 s k ∈ F r sk\in \mathbb{F}_r skFr
  • 公钥 p k ∈ G 2 pk \in \mathbb{G}_2 pkG2
  • 消息 m ∈ B ∗ m\in \mathbb{B}^* mB,为一组字节串
  • Hash to curve算法 H : B ∗ → G 1 H: \mathbb{B}^*\rightarrow \mathbb{G}_1 H:BG1
  • BLS签名 σ ∈ G 1 \sigma \in \mathbb{G}_1 σG1

BLS验签运算为:
e ( σ , − G ) ∗ e ( H ( m ) , p k ) = 1 e(\sigma ,-G)*e(H(m), pk)=1 e(σ,G)e(H(m),pk)=1

当然,角色也可reverse,签名可为 σ ∈ G 2 \sigma \in \mathbb{G}_2 σG2,但为何EVM的BLS签名版本中做如上 σ ∈ G 1 \sigma \in \mathbb{G}_1 σG1等约定,原因有多个,关键原因在于:

  • − G -G G可预计算,且仅需要一次pairing乘积运算;
  • 当采用BN254且签名 σ ∈ G 1 \sigma \in \mathbb{G}_1 σG1时, H ( m ) H(m) H(m) Hash to curve算法相对更易高效计算。

2.1 Hash to curve算法

在这里插入图片描述
Hash to curve算法流程中包括:

  • 1)hash to possible x x x坐标(为基域元素)
  • 2)取平方根——借助curve方程式获得 y y y坐标
  • 3)将获得的curve point ( x , y ) (x,y) (x,y) 与 cofactor 相乘,以 由larger group point 获得 指定的prime group G 1 \mathbb{G}_1 G1 point。
    由于BN254 curve的cofactor为1,因此无需与cofactor相乘,其获得的 ( x , y ) ∈ G 1 (x,y)\in \mathbb{G}_1 (x,y)G1,hash to curve算法效率更高。

BLS Signatures in Solidity中所讨论,可采用try-and-increment hash to curve算法(如上图所示) 或 Fouque-Tibouchi Hash to Curve 算法。Hubble项目合约中采用Fouque-Tibouchi Hash to Curve 算法。
若应用场景中支持中间aggregator,还可借助mapPointWithHelp 进一步优化其中昂贵的“sqrt”运算。

但是,若reverse到 G 2 \mathbb{G}_2 G2,执行以上运算将是昂贵的,因 G 2 \mathbb{G}_2 G2的cofactor约为254 bits,将其与某256-bit scalar相乘的开销约为400万gas,详细见https://github.com/musalbas/solidity-BN256G2所示。可借助endomorphisms——Efficient hash maps to G 2 \mathbb{G}_2 G2 on BLS curves的对scalar multiplication大幅优化,但gas开销仍将不低于100万。

3. 多重签名

如有一组validator set需协作对同一消息进行approve。

  • public key aggregation:在注册时注意获取参与者的proofs-of-possession,可将所有公钥直接相加以获得public key aggregation。
  • signature aggregation:简单相加即可。

由于签名属于 G 1 \mathbb{G}_1 G1效率更高,则公钥是属于 G 2 \mathbb{G}_2 G2。由于目前不存在 G 2 \mathbb{G}_2 G2的预编译加法运算,需在EVM中实现,根据https://github.com/musalbas/solidity-BN256G2,单次 G 2 \mathbb{G}_2 G2加法运算需约3万gas,而单次 G 2 \mathbb{G}_2 G2加法运算仅需约500 gas。

乐观情况下,大多数signer都参与了,仅有1到2个signer未参与,则需要从所有signer的fully aggregated public key中 减去 未参与signer的公钥,若签名足够频繁,这种移除操作也将是昂贵的。未参与signer越多,移除开销越大。

3.1 helped aggregation

既然 G 1 \mathbb{G}_1 G1上的加法运算很便宜,那么,可要求参与者在注册时,提供与其私钥 s k sk sk 对应的2个公钥:

  • p k 2 = s k ⋅ G ∈ G 2 pk_2=sk\cdot G\in\mathbb{G}_2 pk2=skGG2,与原始公钥相同
  • p k 1 = s k ⋅ H ∈ G 1 pk_1=sk\cdot H \in\mathbb{G}_1 pk1=skHG1,其中 H H H G 1 \mathbb{G}_1 G1的generator。这是新增加的公钥。
  • BLS验签为: e ( − σ , G ) ∗ e ( H 2 ( p k 2 ) , p k 2 ) = 1 e(-\sigma, G)*e(H_2(pk_2), pk_2)=1 e(σ,G)e(H2(pk2),pk2)=1,其中 H 2 H_2 H2为不同于之前 H H H的Hash to curve算法。如,其几乎与 H H H相同,但采用不同的domain。
  • 在参与者注册时,检查: e ( p k 1 , G ) ∗ ( − H , p k 2 ) = 1 e(pk_1,G)*(-H,pk_2)=1 e(pk1,G)(H,pk2)=1,确保 p k 1 , p k 2 pk_1,pk_2 pk1,pk2具有相同的私钥——基于B-KEA假设

The Power of Proofs-of-Possession: Securing Multiparty Signatures against Rogue-Key Attacks所述,BLS signature check为a proof-of-possession。

当submitter提交多重签名时,需包含:

  • 签名本身
  • 参与签名的参与者bitmap
  • 包含 p k 2 pk_2 pk2 variants on G 2 \mathbb{G}_2 G2的aggregated公钥,如: a p k = p k 2 , A l i c e + p k 2 , B o b + p k 2 , C h a r l i e apk=pk_{2,Alice}+pk_{2,Bob}+pk_{2,Charlie} apk=pk2,Alice+pk2,Bob+pk2,Charlie

而合约自身会:

  • 计算 p k 1 pk_1 pk1 variants on G 1 \mathbb{G}_1 G1的aggregated公钥,如: P 1 = p k 1 , A l i c e + p k 1 , B o b + p k 1 , C h a r l i e P_1=pk_{1,Alice}+pk_{1,Bob}+pk_{1,Charlie} P1=pk1,Alice+pk1,Bob+pk1,Charlie
  • 检查 e ( P 1 , g ) ∗ e ( − H , a p k ) = 1 e(P_1,g)*e(-H,apk)=1 e(P1,g)e(H,apk)=1

合约会提供如下伪接口:

function verifySignature(bool[] signersBitmap, G2Element apk, G1Element signature)

其中:

  • a p k apk apk:由链下计算,为对应 s i g n e r s B i t m a p signersBitmap signersBitmap中参与签名者的 p k 2 pk_2 pk2公钥之和。
  • 从合约stoarge获取所有签名者 p k 1 pk_1 pk1聚合公钥,再减去 s i g n e r s B i t m a p signersBitmap signersBitmap中未参与签名者的 p k 1 pk_1 pk1公钥。【假设大多数签名者都将参与每次签名,则做减法操作比做加法操作可消耗更少的gas。】

这样,可高效聚合 G 1 \mathbb{G}_1 G1公钥,并验证在链下计算的 G 2 \mathbb{G}_2 G2公钥。

3.2 进一步优化

为避免引入额外的pairing check e ( p k 1 , G ) ∗ ( − H , p k 2 ) = 1 e(pk_1,G)*(-H,pk_2)=1 e(pk1,G)(H,pk2)=1,可将其与现有的BLS验签方程结合:
引入随机 α \alpha α,借助Schwartz-Zippel lemma,将2个独立的pairing check方程式结合在一起,有:
e ( σ , − G ) ∗ e ( H ( m ) , a p k ) ∗ ( e ( P 1 , G ) ∗ e ( − H , a p k ) ) α = 1 e(\sigma, -G)*e(H(m),apk)*(e(P_1,G)*e(-H,apk))^{\alpha}=1 e(σ,G)e(H(m),apk)(e(P1,G)e(H,apk))α=1
借助pairing bilinearity属性,将 α \alpha α移到 G 1 \mathbb{G}_1 G1上,有:
e ( σ , − G ) ∗ e ( H ( m ) , a p k ) ∗ e ( α P 1 , G ) ∗ e ( − α H , a p k ) = 1 e(\sigma, -G)*e(H(m),apk)*e(\alpha P_1,G)*e(-\alpha H,apk)=1 e(σ,G)e(H(m),apk)e(αP1,G)e(αH,apk)=1
借助pairing的结合属性,有:
e ( σ − α P 1 , − G ) ∗ e ( H ( m ) − α H , a p k ) = 1 e(\sigma-\alpha P_1,-G)*e(H(m)-\alpha H,apk)=1 e(σαP1,G)e(H(m)αH,apk)=1

根据https://gist.github.com/kobigurk/257c1783ddf556e330f31ed57febc1d9中的原型实现,hashing into α \alpha α以及2次scalar multiplication的开销约为1.6万gas,还存在进一步优化的空间。

3.3 结论

通过引入额外的元素,以及对参与方注册时的check,可获得更高效的链上BLS multisignature verification算法。聚合公钥的每次修改将引入小的gas开销,少量元素的hash仅需固定的便宜的gas开销,存在2次scalar multiplication,每个需6千gas开销。

参考资料

[1] Geometry团队2022年11月博客 优化EVM中的BLS多重签名

附录1 B-KEA是malleable的

若仅使用B-KEA,存在rogue-key攻击的问题。
假设Alice有公钥 A 1 = a H , A 2 = a G A_1=aH,A_2=aG A1=aHA2=aG,满足 e ( A 1 , G ) ∗ e ( − H , A 2 ) = 1 e(A_1,G)*e(-H,A_2)=1 e(A1,G)e(H,A2)=1
Bob选择 B 1 = X 1 − A 1 , B 2 = X 2 − A 2 B_1=X_1-A_1,B_2=X_2-A_2 B1=X1A1B2=X2A2,其中 X 1 = x H , X 2 = x G X_1=xH,X_2=xG X1=xHX2=xG,Bob声称 B 1 和 B 2 B_1和B_2 B1B2为其公钥,但其并不知道相应的私钥,但仍满足 e ( B 1 , G ) ∗ e ( − H , B 2 ) = 1 e(B_1,G)*e(-H,B_2)=1 e(B1,G)e(H,B2)=1

若Bob可验证verification function的bitmap,提交其以 x x x的BLS签名(声称其来自于Bob和Alice双方),则多签验证可通过,因 A 1 + B 1 = A 1 + X 1 − A 1 = X 1 A_1+B_1=A_1+X_1-A_1=X_1 A1+B1=A1+X1A1=X1

附录2 批量注册

在3.2节中展示了如何在验签环节批量合并验证方程式,此处也可进行批量注册检查。
注册时需验证以下2个方程式:
e ( − σ , G ) ∗ e ( H 2 ( p k 2 ) , p k 2 ) = 1 e(-\sigma, G)*e(H_2(pk_2), pk_2)=1 e(σ,G)e(H2(pk2),pk2)=1
e ( p k 1 , G ) ∗ ( − H , p k 2 ) = 1 e(pk_1,G)*(-H,pk_2)=1 e(pk1,G)(H,pk2)=1

引入随机数 α = h a s h ( σ , m , p k 1 , p k 2 ) \alpha=hash(\sigma,m,pk_1,pk_2) α=hash(σ,m,pk1,pk2),将以上2个方程式合并为:
e ( − σ , G ) ∗ e ( H 2 ( p k 2 ) , p k 2 ) ∗ ( e ( p k 1 , G ) ∗ ( − H , p k 2 ) ) α = 1 e(-\sigma, G)*e(H_2(pk_2), pk_2)*(e(pk_1,G)*(-H,pk_2))^{\alpha}=1 e(σ,G)e(H2(pk2),pk2)(e(pk1,G)(H,pk2))α=1
从而有:
e ( − σ − α ⋅ p k 1 , G ) ∗ e ( H 2 ( p k 2 ) − α H , p k 2 ) = 1 e(-\sigma-\alpha\cdot pk_1, G)*e(H_2(pk_2)-\alpha H, pk_2)=1 e(σαpk1,G)e(H2(pk2)αH,pk2)=1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值