密码学之 Ecdsa 签名、GG20、MPC 钱包 (四) 完整版

  • 皓码
  • 发布于 2小时前
  • 阅读 34

GG20协议(One Round Threshold ECDSA with Identifiable Abort)是基于GG18协议的改进,是当前实现ECDSA阈值组签名最主流、最安全的协议之一。它专为MPC钱包设计,支持分布式密钥生成和签名。

GG20 协议(One Round Threshold ECDSA with Identifiable Abort)是基于 GG18 协议的改进,是当前实现 ECDSA 阈值组签名最主流、最安全的协议之一。它专为 MPC 钱包设计,支持分布式密钥生成和签名。旨在解决 BitForge 漏洞,提高效率并增强安全性。GG20 通过引入无小因子证明和 Blum 模数证明来验证 Paillier 参数的安全性,并通过原子性签名来确保签名过程的安全性。此外,GG20 还优化了密钥生成和签名流程,提高了整体性能。

我们知道,BitForge 漏洞(CVE-2023-33241)是 GG18 的核心痛点,即已经理解攻击原理(恶意 Paillier 参数+迭代提取私钥),所以 GG20 主要是围绕这一痛点来展开的,以及如何通过强化的零知识证明(如无小因子证明、Blum 模数证明)和原子性签名来封堵这一漏洞。即使采用 GG20,Paillier 参数验证和密钥管理仍是审计重点。

以前的文章

基本原理介绍

基本技术

GG20 协议所涉及的技术与 GG18 协议有很多重合的地方,这里只是简单的罗列出来,不做详细介绍,详细介绍请自行查看以往的文章:

  • 签名技术
  • 阈值组签名技术 (Threshold-Signature)
  • 可识别终止 (Identifiable Abort)
  • 加法同态加密 (Paillier 加密)
  • 不可延展的模糊承诺(NM-E-Commitment)(具有不可延展性和模糊性的承诺方案)
  • 可验证秘密分享(VSS,Verifiable Secret Sharing)
  • DSA 签名
  • DDH 假设、Strong-RSA 假设
  • 乘法转换协议(MtA)
  • 同态运算
  • 零知识证明

带可识别中止的阈值组签名协议流程

GG20 协议主要包括以下几个步骤:

密钥生成
  1. 每个参与方 $P_i$ 随机选择 $u_i\in_RZ_q$,即多项式的常数项,计算承诺 $[KGC_i,KGD_i]=Com(g^{u_i})$,并广播 $KGC_i$。每个 $P_i$ 广播自己的 Paillier 公钥 $E_i$。

  2. 每个 $P_i$ 广播 $KGD_i$,并做解承诺运算,记 $y_i=g^{u_i}$。运行 $(t,n)-$FVSS 协议,得组公钥 $y=\Pi_i{y_i}$,组私钥 $x=\sum_i{u_i}$,每个 $P_i$ 的私钥分片 $x_i=\sum_j{f_j(i)}$,公钥分片 $X_i=g^{x_i}$。

  3. 每个 $P_i$ 使用 ZK 证明其知道 $x_i$。$N_i=p_iq_i$ 是与 $E_i$ 相关的 RSA 模数。使用 ZK 证明 $N_i$ 无平方因子,以及证明无小因子。

签名过程

令 $S\subseteq[1..n]$ 表示被选出来的参与签名的成员集合,其大小为 $|S|=t+1$。$\lambda_{i,S}$ 表示拉格朗日系数,记 $\omegai=(\lambda{i,S})xi$,于是得到 $x=\sum{i\in S}\omega_i$,$W_i=g^{\omega_i}=Xi^{\lambda{i,S}}$。

  • Phase 1

    $P_i$ 随机选择 $k_i,\gamma_i\in_RZ_q$,计算承诺 $[C_i,D_i]=Com(g^{\gamma_i})$,并广播 $Ci$。定义 $k=\sum{i\in S}ki,\gamma=\sum{i\in S}\gammai$。所以 $$ k\gamma=\sum{\substack{i,j\in S}}^{n}k_i\gammaj\ kx=\sum{\substack{i,j\in S}}^{n}k_i\omega_j $$

  • Phase 2

    执行 MtA 协议,对于 $k_i\gamma_j$ 的乘法分享,协议执行结果如下: $$ k_i\gammaj=\alpha{ij}+\beta_{ij}\ $$ 其中 $Pi$ 拥有 $\alpha{ij}$ ,$Pj$ 拥有 $\beta{ij}$。

    $P_i$ 计算 $$ \delta_i=k_i\gammai+\sum{j\neq i}^{n}\alpha{ij}+\sum{j\neq i}^{n}\beta{ji}\ $$ 于是得到 $k\gamma=\sum{i\in S}\delta_i$。

    执行 MtAwc 协议,对于 $k_i\omega_j$ 的乘法分享,协议执行结果如下: $$ k_i\omegaj=\mu{ij}+\nu_{ij}\ $$ 其中 $Pi$ 拥有 $\mu{ij}$,$Pj$ 拥有 $\nu{ij}$。

    $P_i$ 计算 $$ \sigma_i=k_i\omegai+\sum{j\neq i}^{n}\mu{ij}+\sum{j\neq i}^{n}\nu{ji}\ $$ 于是得到 $kx=\sum{i\in S}\sigma_i$。

  • Phase 3

    $P_i$ 广播各自的 $\deltai$,并计算 $\delta=\sum{i\in S}\delta_i=k\gamma$, 并计算 $\delta^{-1}\text{ mod q}$。

    计算 $T_i=g^{\sigma_i}h^{l_i}$,并广播各自的 $T_i$。并且使用 ZK 证明其知道 $\sigma_i,l_i$。

  • Phase 4

    $P_i$ 广播各自的 $D_i$,并做解承诺运算,得到 $\Gamma_i=g^{\gammai}$。计算 $\Gamma=\Pi{i\in S}{\Gamma_i}$。

    所以得到组签名承诺 $R=\Gamma^{\delta^{-1}}=g^{k^{-1}}$,这里很容易推导出来。接下来计算出 $r=H'(R)$。

  • Phase 5

    每个 $P_i$ 计算 $\bar{R_i}=R^{k_i}$ 并广播。

    并对 $\bar{R_i}$ 和 $E_i(K_i)$ 做一致性零知识证明。其中 $E_i(ki)$ 是 Phase 2 中 MtA 协议所发送的 paillier 密文。验证: $$ g\xlongequal{?}\Pi{i\in S}\bar{R_i} $$ 如果验证失败,则协议终止

  • Phase 6

    每个 $P_i$ 计算 $S_i=R^{\sigma_i}$ 并广播。

    并对 $S_i$ 和 $T_i$ 做一致性零知识证明。其中 $Ti$ 是 Phase 3 中所发送的消息。验证: $$ y\xlongequal{?}\Pi{i\in S}S_i $$ 如果验证失败,则协议终止

  • Phase 7

    每个 $P_i$ 计算 $s_i=mk_i+r\sigmai$,并计算 $s=\sum{i\in S}s_i$。若签名 $(r,s)$ 是正确的则接受,否则终止。

零知识证明
  1. 上一节中的 Phase 3 里的 ZK,$T=g^{\sigma}h^l$。
  • Prover 随机选择 $a,b\in_R Z_q$,并计算 $\alpha=g^ah^b$,并发送。
  • Verifier 发送一个随机挑战 $c\in_RZ_q$。
  • Prover 计算 $t=a+c\sigma\text{ mod q},u=b+cl\text{ mod q}$,并发送$(t,u)$。
  • Verifier 验证 $g^th^u\xlongequal{?}\alpha T^c$。
  1. 上一节中的 Phase 5 里的 ZK,$\bar{R}=R^k,C=E(k)$,证明 $\bar{R}$ 中的 $k$ 与 paillier 密文 $C$ 中的 $k$ 是一致的。可以思考下如何去做?

  2. 上一节中的 Phase 6 里的 ZK,参与者 $P$ 输出 $S=R^\sigma$,必须证明其知道 $\sigma,l$,满足 $S=R^\sigma,T=g^{\sigma}h^l$。

    • Prover 随机选择 $a,b\in_R Z_q$,并计算 $\alpha=R^a,\beta=g^ah^b$,并发送 $(\alpha,\beta)$。
    • Verifier 发送一个随机挑战 $c\in_RZ_q$。
    • Prover 计算 $t=a+c\sigma\text{ mod q},u=b+cl\text{ mod q}$,并发送 $(t,u)$。
    • Verifier 验证 $R^t\xlongequal{?}\alpha S^c,g^th^u=\beta T^c$。

可识别中止(Identifiable Abort)

所有已知的 ECDAS 阈值组签名协议的一个关键问题是,在中止的情况下,无法确定是哪一个参与方导致的签名失败,也就无法确定由谁负责任和受到惩罚,在本节中,我们将展示如何做到可识别中止。

需要注意的是,我们假设有一个广播信道,所以如果参与方作恶,每个参与方都会知道,这要求协议的每条消息都必须可靠地广播(这包括对 MtA 协议)。在这里,我们将注意力集中在:一方在正确的时间发送了正确形式的消息,但该消息的内容被精心设计成导致协议失败的方式,说白了就是假设消息传递和广播都是可靠的,忽略不可靠通信带来的影响,只专注协议本身以及消息内容。

密钥生成协议中的可识别中止
  • 在第 2 步中,通过多项系数承诺验证 Feldman share 值是否正确,若不正确则中止。
  • 在第 3 步中,通过 ZK 证明参与者知道私钥分片值 $x_i$,以及证明 paillier 密钥的正确性,若其中任何一个验证不通过则中止。

这两个地方的中止都是可识别的,在 F-VSS 协议中,假设 $P_j$ 收到 $P_i$ 发来的秘密$f_i(j)$,$P_j$ 验证: $$ g^{fi(j)}\xlongequal{?}\prod{k=0}^{t-1} A_{ik}^{j^k} $$ 第 2 步中,若验证失败,则说明 $P_i$ 所公开的信息与它发来的秘密值不一致,$P_j$ 就可以投诉 $P_i$,并终止协议,在这种情况下可以确定 $P_i$ 是那个坏的参与者,并将其剔除出去,并重新运行密钥生成协议。不过这里可能存在歧义,即 $P_j$ 可能陷害 $P_i$,怎么解决,其实很简单,密钥生成协议是全局的基础操作,它的中止意味着没有生成密钥,更不会有密钥泄露的风险,一旦发生 $P_j$ 投诉 $P_i$ ,$P_j$ 必须公开它从 $P_i$ 接收的秘密分享值,其他参与者可以根据这个分享值验证 $P_j$ 是否陷害 $P_i$,如果 $P_j$ 陷害 $P_i$,则 $P_j$ 必须承担相应的责任或者被剔除出去。

第 3 步中,每个参与者的私钥分片 $x_i$ 是公开可验证的,只要是 ZK 验证失败就能确定作弊参与者,同样 paillier 密钥也是公开可验证的,所以第 3 步中止也是可识别的。

签名协议中的可识别中止

在签名协议中,以下是协议发生中止的情况:

  1. Phase 2 若 MtA 和 MtAwc 范围证明不通过或者 MtAwc 的零知识证明不通过,则中止。

  2. Phase 3 若关于 $\sigma_i,l_i$ 的零知识证明不通过,则中止。

  3. Phase 4 若对 $D_i$ 的解承诺操作验证失败,则中止。

  4. Phase 5 若对 $\bar{R_i}$ 的零知识证明验证失败,则中止。

  5. Phase 5 若 $g\neq \prod \bar{R_i}$,则中止。

  6. Phase 6 若对 $S_i$ 的零知识证明验证失败,则中止。

  7. Phase 6 若 $y\neq \prod S_i$,则中止。

  8. Phase 7 若消息 $m$ 的阈值组签名 $(r,s)$ 无效,则中止。

对于情况 1、2、3、4、6 识别作弊参与者是比较容易的,如果参与者给出一个错误的 ZK 证明或者打开一个错误的承诺,那么即可确定作弊者。

对于情况 8,若 $g = \prod \bar{R_i}, y = \prod S_i$ 且 $m$ 的阈值组签名 $(r,s)$ 无效,则说明参与者给出了错误的签名分片,此时需要确定是哪个参与者给出了错误的签名分片,此时需要 $P_i$ 广播它们的 $s_i=mk_i+r\sigma_i\text{ mod q}$,只需要公开可验证: $$ R^{s_i}=\bar{R_i}^{m}\cdot S_i^r \tag{1} $$ 如果上面的等式全部成立,则组签名必定验证成功,事实上 $$ R^s=R^{\sum s_i}=[\prod\bar{R_i}]^m\cdot [\prod S_i]^r=g^m\cdot y^r $$ 成立,所以通过等式 (1) 是否成立就能识别出作弊参与者。

对于情况 5、7 是比较复杂的,但从 $g \neq \prod \bar{R_i}, y \neq \prod S_i$ 发生是无法确定作弊参与方的。在较高的级别上,这意味着用于计算签名的分布式值是错误的,但它没有指示出哪里出了问题。实际上,这可能是由 MtA 协议本身的故障引起的,其中一个参与者向另一个参与方发送了错误的密文(Phase 2)。但是,即使 MtA 协议本身成功了,失败也可能是由于参与方后来透露的错误值与他们在 MtA 协议期间收到的值不一致造成的。如果参与方透露了错误的 $\delta_i$ 或 $\Gamma_i$(Phase 3Phase 4),这将导致错误的 $R$,从而导致无效的签名,就会发生这种情况。这也可能是由于参与者在 Phase 3Phase 6 中输入了错误的 $\sigma_i$(这将导致错误的 $s$)。以前的协议,如 GG18 ,无法有效地从类似的分布式验证检查中分离出不良参与者的身份。

为了证明参与者确实正确地运行了协议,有必要证明以下几种情况:

  1. 运行 MtA 协议时输入的 $k_i,\gamma_j$ 和运行 MtAwc 协议时输入的 $k_i,w_j$,这两者的 $k_i$ 必须是一致的。

  2. 运行 MtAwc 时,输入的 $w_j$ 公开值 $W_j=g^{w_j}$ 必须时一致的。

  3. MtA 中的 $\gamma_j$ 与 Phase 4 中解承诺操作得到的值 $\Gamma_j$ 必须是一致的。

  4. Phase 3 中公开的 $\delta_i$ 与 MtA 中输出的分享值必须保持一致,即: $$ \delta_i=k_i\gammai +\sum{j\neq i} \alpha{ij}+\sum{j\neq i} \beta_{ji} $$ 成立。

  5. Phase 6 中公开的 $S_i$ 与 MtAwc 中输出的分享值必须保持一致,即: $$ \begin{aligned} S_i &= R^{\sigma_i}\ \sigma_i &=k_i\omegai +\sum{j\neq i} \mu{ij}+\sum{j\neq i} \nu_{ji} \end{aligned} $$ 成立。

情况 1,因为 MtA 和 MtAwc 协议的第一条消息确实是共享的,而且双方只发送一条消息,因此一致性得到了保证。

情况 2 ,由于运行 MtAwc,该情况也得到协议的保证,它保证 $P_j$ 输入的值确实与 $g^{w_j}$ 一致。

为了使协议可识别,只需要考虑情况 3、4、5 如何保证。

回想一下,当签名公开时,重要的是 $k$ 要保密,因为给定 $k$ 和使用 $k$ 的签名,可以计算私钥 $x$。类似地,如果一方公布了它的值 $s_i$ 和 $k_i$,那么这将泄露它的秘密共享 $x_i$,问题源于同时发布 $k_i$ 和使用 $k_i$ 的签名分片 $s_i$。然而,如果 $s_i$ 没有被发布,$k_i$ 就没有特殊的意义,并且确实可以在不泄露任何关于密钥信息的情况下发布。

现在考虑 Phase 5 中 $g\neq\prod \bar{R_i}$ 中止的情况。此时,签名协议中的值 $s_i$ 还没有被发布出去甚至没有被计算。事实上,在这一点上,各方明显地透露其值 $k_i$ 是完全可以接受的。对于临时值 $\gamma_i$ 也是如此。如果没有值 $s_i$ ,则不需要对值 $\gamma_i$ 进行保密。这意味着 $k_i$ 和 $\gamma_j$ 的 MtA 协议可以完全打开。这可以立即检查情况 3 和情况 4 是否满足,因为组成 $\sigma_i$ 的所有值都是公开的。

因此对于 Phase 5 中 $g\neq\prod \bar{R_i}$ 中止的识别可以执行以下操作:

  • 每一方 $P_i$ 公开发布其所有的值 $k_i,\gammai,\alpha{ij},\beta_{ji}$ ( 遍历所有的 $j$ ) 以及公开在 MtA 协议期间用于加密这些值的随机值。

  • 现在每一方 $P_j$ 都可以清晰地验证 $\delta_i$ 的正确性。若对于任何一方的验证不通过,则将中止归因于该方,并且识别协议终止。

现在把重点放在 Phase 6($y\neq \prod S_i$)的中止上。在这里,各方不能完全打开与 $k_i$ 和 $w_j$ 相关的 MtAwc 协议,因为 $w_j$ 是 $P_j$ 的长期私钥,而且与临时值 $k_i$ 和 $\gamma_j$ 不同,即使签名终止,值 $wi$ 也需要保密。然而,清晰地揭露值 $\mu{ij}$ 是安全的,并且可以检查指数中 $\sigma_i$ 的正确性,允许识别作弊的一方。下面是具体操作:

  • 每一方 $P_i$ 发布 $ki$ 和 $\mu{ij}$ 作为 MtAwc 协议中相应密文的解密。

  • 现在每一个其他方 $P_l$ 都可以验证 $k_i$ ( $P_i$ 发送给 $Pj$ ),$\mu{ij}$ ( $P_j$ 发送给 $P_i$ ),此外,对于所有 $j$,因为 $g^{w_j}$,$ki$ 和 $\mu{ij}$ 是公开的,现在任何人都可以使用方程 $g^{\mu_{ij}}=g^{w_jki}\cdot g^{-\nu{ij}}$ 计算出 $g^{\nu_{ij}}$。现在他们可以进行额外的计算: $$ g^{\sigma_i}=g^{w_iki}\cdot \prod{j\neq i}\mu{ij} \cdot \prod{j\neq i}\nu_{ji} $$

  • 每个参与者 $P_i$ 使用 ZK 证明前一步计算的 $g^{\sigma_i}$ 与 $S_i=R^{\sigma_i}$ 之间的一致性。若对任何一方来说这都不成立,则认为该方是作弊方。

以上就是签名协议中的可识别中止。

不带可识别中止的签名协议流程

如果不关心可识别的中止,可以进一步简化协议。虽然带可识别的协议已经非常有效,并且有一个循环优化的在线阶段,但如果我们能够容忍不带可识别中止,则离线协议可以进一步简化。该协议与带可识别中止的协议非常相似,下面是其完整的描述。

密钥生成协议与带可识别中止的协议相同。

签名协议
  • Phase 1

    $P_i$ 随机选择 $k_i,\gamma_i\in_RZ_q$,计算承诺 $[C_i,D_i]=Com(g^{\gamma_i})$,并广播 $Ci$。定义 $k=\sum{i\in S}ki,\gamma=\sum{i\in S}\gammai$。所以 $$ k\gamma=\sum{\substack{i,j\in S}}^{n}k_i\gammaj\ kx=\sum{\substack{i,j\in S}}^{n}k_i\omega_j $$

  • Phase 2

    执行 MtA 协议,对于 $k_i\gamma_j$ 的乘法分享,协议执行结果如下: $$ k_i\gammaj=\alpha{ij}+\beta_{ij}\ $$ 其中 $Pi$ 拥有 $\alpha{ij}$ ,$Pj$ 拥有 $\beta{ij}$。

    $P_i$ 计算 $$ \delta_i=k_i\gammai+\sum{j\neq i}^{n}\alpha{ij}+\sum{j\neq i}^{n}\beta{ji}\ $$ 于是得到 $k\gamma=\sum{i\in S}\delta_i$。

    执行 MtAwc 协议,对于 $k_i\omega_j$ 的乘法分享,协议执行结果如下: $$ k_i\omegaj=\mu{ij}+\nu_{ij}\ $$ 其中 $Pi$ 拥有 $\mu{ij}$,$Pj$ 拥有 $\nu{ij}$。

    $P_i$ 计算 $$ \sigma_i=k_i\omegai+\sum{j\neq i}^{n}\mu{ij}+\sum{j\neq i}^{n}\nu{ji}\ $$ 于是得到 $kx=\sum{i\in S}\sigma_i$。

  • Phase 3

    $P_i$ 广播各自的 $\deltai$,并计算 $\delta=\sum{i\in S}\delta_i=k\gamma$, 并计算 $\delta^{-1}\text{ mod q}$。

  • Phase 4

    $P_i$ 广播各自的 $D_i$,并做解承诺运算,得到 $\Gamma_i=g^{\gammai}$。计算 $\Gamma=\Pi{i\in S}{\Gamma_i}$。

    所以得到组签名承诺 $R=\Gamma^{\delta^{-1}}=g^{k^{-1}}$,这里很容易推导出来。接下来计算出 $r=H'(R)$。

  • Phase 5 $P_i$ 计算 $\Lambda_i=\Gamma^{k_i}$ 并广播,使用 ZK 去证明 $\Lambda_i$ 与 $E_i(k_i)$ 之间的一致性

  • Phase 6 每个 $Pi$ 计算 $\Lambda=\prod{i\in S}\Lambda_i$。若$\Lambda=g^\delta$,则 $P_i$ 广播 $s_i$ ,否则终止。

GG20 相对于 GG18 的关键安全改进

安全特性 GG18 GG20
Paillier模数验证 仅验证“无平方因子”(Square-Free),允许小素数存在,导致漏洞。 强制强零知识证明,验证模数 N 是安全的大素数乘积(无小因子),从根本上杜绝恶意参数注入。
签名中止攻击 协议可能部分失败,泄露错误信息,被利用来提取私钥分片。 引入签名原子性,确保操作“全成功或全回滚”,阻断通过错误信息泄露的渠道。
审计与追踪 新增审计追踪功能。如果签名失败,可以定位到恶意节点,增强了协议的可问责性。
其他优化 优化了零知识证明的逻辑,极大减少了通信量。

GG20 的优缺点分析

优点:

  1. 高安全性:修复了 GG18 的关键漏洞,是目前最安全的 ECDSA 门限签名方案之一。

  2. 兼容性极佳:生成的是标准 ECDSA 签名,与比特币、以太坊等所有支持 ECDSA 的区块链原生兼容。

  3. 无需链上变更:MPC 的复杂性在链下,对区块链网络本身无任何要求。

  4. 灵活的治理模型:支持 (t-n) 多种门限设置(如2-of-3,3-of-5),适应企业多签、个人备份等场景。

  5. 相比 GG18 网络通信量优化:通过协议的优化大幅减少了通信量,提高了效率。

缺点/挑战:

  1. 计算和通信开销大:多轮交互和 Paillier 加密计算导致延迟较高,不太适合高频交易场景。

  2. 实现复杂性:协议极其复杂,依赖非常多的密码学组件,自行实现难度高,容易因编码错误引入新漏洞。

  3. 依赖传统密码学:基于离散对数问题,不抗量子计算(但量子计算机问世尚需时日)。

应用生态与开源实现

  • 主要用户:众多知名的加密货币托管服务商、交易所和钱包提供商,如 Fireblocks、Qredo、ZenGo 等,其核心均采用或兼容 GG20/GG18 协议。

  • 主流开源库:

总结与建议

GG20 协议是 MPC 钱包发展史上的一个里程碑。 它继承了 GG18 的架构优势,并通过强化的零知识证明和原子性设计,有效解决了前代协议的重大安全漏洞,为大规模商业应用奠定了基础。

给开发者和企业的建议:

  • 新项目选型:如果业务需要兼容比特币/以太坊等 ECDSA 链,应直接选择基于 GG20 的实现,并确认其已完整集成针对 BitForge 漏洞的修复(强 Paillier 参数验证)。

  • 存量系统升级:如果正在使用基于 GG18 的库,必须立即计划升级到 GG20 或应用相应的安全补丁。

  • 安全审计:无论采用何种库,在上线前都必须由专业机构进行密码学实现审计,重点关注 Paillier 参数验证、错误处理和零知识证明的正确性。

  • 考虑替代方案:对于新链或可接受 Schnorr 签名的场景(如比特币 Taproot),可以评估更高效的 FROST 协议,其通信轮次更少,且无 Paillier 以及大量 ZK 计算开销。

总而言之,GG20 为高价值的数字资产托管提供了一个在安全性和兼容性之间取得优异平衡的解决方案,是当前企业级 MPC 钱包的首选技术方案之一。

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论