本文深入探讨了多方计算(MPC)和门限签名方案中协议设计上的缺陷,这些缺陷不同于代码层面的漏洞,而是源于协议本身的设计决策。文章分析了MtA Oracle攻击、密钥重共享协议中的“Forget-and-Forgive”攻击,以及确定性Nonce生成在门限Schnorr签名中的风险,并讨论了一种潜在的针对门限Schnorr方案自适应安全性的理论攻击。
在第一部分中,我们讨论了实现漏洞——缺失的检查、跳过的验证以及编码歧义,这些会将可证明安全的协议变成可利用的系统。这些都是代码层面的失败:开发者信任他们应该验证的输入,使用不足的安全参数,或者误解了密码学需求。 这一部分将更深入。这里我们检查源于协议本身的攻击,这些设计决策在论文中看起来合理,但在对抗性条件下却崩溃了,这是原始作者没有完全考虑到的。我们还将研究最近的一个理论结果,该结果挑战了广泛部署的阈值 Schnorr 方案的自适应安全性。 这些不是你可以通过参数检查或额外的验证来修复的错误。它们是根本性问题,需要重新设计协议或仔细理解协议的安全保证何时真正成立。
Multiplicative-to-Additive (MtA)(乘法到加法)共享转换在阈值 ECDSA 中无处不在。此协议使用 Paillier 加密。Alice 方持有秘密 $a$ 和模数为 $N$ 的 Paillier 密钥对 $(E_A, D_A)$。Bob 方持有秘密 $b$。他们的流程如下:
Alice 加密:计算 $c_A = E_A(a)$,以及 $a$ 在正确范围内的零知识范围证明,并将 $(c_A, \pi_A)$ 发送给 Bob。
Bob 回应:
Alice 解密:验证 Bob 的证明 $\pi_B$,然后计算 $\alpha = D_A(c_B) \bmod q$(她的输出份额)
范围证明确保 $a$ 和 $b$ 足够小,以至于解密不会溢出。具体来说,$\alpha' = D_A(c_B) = ab + \beta'$(在整数上计算),然后 $\alpha = \alpha' \bmod q$。如果 $a$ 和 $b$ 在范围内,则 $\alpha'$ 不会以模 $q$ 环绕,并且我们得到 $\alpha + \beta = ab \bmod q$,正如期望的那样。
“快速”版本
GG18 论文提出了一个变体 (MtAwc),它省略了范围证明。相反,$(B, B')$ 被发布,作者推测公共值 $B = g^b$ 和 $B' = g^{\beta'}$“不会泄漏任何额外数据,并弥补了缺失的范围证明。” 他们错了。
攻击
攻击者(例如,Alice/Party 1)选择 $a = \lfloor \frac{2N}{q} \rfloor$。这比协议预期的要大得多,$a$ 应该大致为 $q$ 大小,但这个 $a$ 大约为 $2N$。
Bob 诚实地进行:计算 $c_B = b \cdot c_A +_E E_A(\beta')$ 并发送 $(c_B, B = g^b, B' = g^{\beta'})$。
Alice 解密:$\alpha = D_A(c_B) = ab + \beta'$。让我们将 $\alpha'$ 表示为整数上的原始值(没有模约简)。 现在,$\beta' \in \mathbb{Z}_N$,所以 $\beta' \in [0, N)$。关键观察:根据 $\alpha'$ 的大小,它将落入三个不相交的范围之一:
$g^{ab} \cdot g^{\beta'} = g^{\alpha'} = g^{\alpha}$
$g^{ab} \cdot g^{\beta'} = g^{\alpha'} = g^{\alpha} \cdot g^N$
$g^{ab} \cdot g^{\beta'} = g^{\alpha'} = g^{\alpha} \cdot g^{2N}$
Alice 计算 $g^{ab} \cdot g^{\beta'} = g^a \cdot B \cdot B'$(使用公共值 $B$ 和 $B'$)并检查哪个情况成立。这揭示了 $\alpha'$ 属于哪个区间,进而揭示了关于 $b$ 的信息:
Alice 仅从一次 MtA 执行中学到了对 Bob 的秘密 $b$ 的约束。
推广攻击
Alice 可以为某个整数 $M$ 选择 $a = \lfloor \frac{MN}{q} \rfloor$。现在 $\alpha'$ 将落入 $M+1$ 个区间之一 $[sN, (s+1)N)$,其中 $s \in {0, 1, \ldots, M}$。每个签名都揭示了哪个区间,从而为 Alice 提供了一个约束:
$b \in \left[\frac{(s-1)q}{M}, \frac{(s+1)q}{M}\right]$
仅需几个签名(每个签名都带有不同的恶意 $a$ 值)后,Alice 即可重建 Bob 的整个私钥。
为什么会发生
“额外数据”$B = g^b$ 和 $B' = g^{\beta'}$ 应该可以防止泄漏。但是当 Alice 选择超出范围的 $a$ 时,解密会创建一个侧信道:$g^{ab} \cdot g^{\beta'}$ 和 $g^{\alpha}$ 之间的关系揭示了发生了多少模约简,从而泄漏了关于 $b$ 的信息。
这是来自 "Alpha-Rays: Key Extraction Attacks on Threshold ECDSA Implementations" 的 对不存在的范围证明的攻击。该论文报告了对 ZenGo 和 ING 库的影响。
解决方法: 使用带有范围证明的“慢速”版本。像 CGGMP20 这样的现代协议为所有 MtA 输入包含适当的范围证明。不要跳过它们。
密钥重新共享协议应该刷新份额,而不会更改底层秘密。这保持了对资金的持续访问,同时限制了逐渐的密钥泄露造成的损害。但是,如果协议缺乏关于何时删除旧份额的适当协调,则攻击者可以将其武器化,从而导致永久的钱包锁定。
重新共享协议
易受攻击的实现使用基于 VSS 的重新共享,采用 $(t,n)$ 阈值设置。高级流程:
攻击
对手(旧方之一)通过发送选择性构造错误份额来利用步骤 4:
在步骤 5 中,验证结果将新方分成两组:
现在问题来了:删除之前没有同步。A 组中的各方不知道 B 组已中止。他们删除他们的旧份额并切换到新份额。
后果: 该秘密无法再重建:混合旧份额和新份额不起作用,它们不再是同一秘密的加法份额。即使所有各方都合作,他们也无法生成有效的签名。钱包被永久锁定。

这是 "Attacking Threshold Wallets" 中描述的 Forget-and-Forgive(忘记和原谅)攻击。
解决方法
在删除之前添加一个指责阶段。验证后(步骤 5),各方必须协调:
数字签名中的 Nonce 重用是一个经典的埋雷点。每个人都知道这个故事:在 ECDSA 或 Schnorr 中重用你的 Nonce,你的私钥就会泄漏。标准的防御措施是:(1)为每个签名采样一个新的随机 Nonce,或者(2)确定性地将 Nonce 派生为 $n = H(m | sk)$。
选项 2 似乎非常适合单方签名,它是确定性的,因此你不会意外地重用随机性,并且它将 Nonce 绑定到消息和私钥。但是在阈值签名中,确定性成为一种武器。
为什么 Nonce 重用会破坏 Schnorr
快速回顾一下为什么 Nonce 重用是致命的。假设你使用相同的 Nonce $n$ 签署两条不同的消息 $m_1, m_2$:
$s_1 = n + c_1 \cdot sk, \quad s_2 = n + c_2 \cdot sk$
其中 $c_1 = H(nG | pk | m_1)$ 和 $c_2 = H(nG | pk | m_2)$。相减:
$s_1 - s_2 = (c_1 - c_2) \cdot sk \implies sk = \frac{s_1 - s_2}{c_1 - c_2}$
游戏结束。攻击者从两个签名中恢复了你的密钥。
阈值设置
现在考虑双方 Schnorr(一个玩具模型,但这个想法可以推广)。Alice 和 Bob 各自持有私钥的份额 $sk_1, sk_2$,公钥为 $pk = (sk_1 + sk_2) \cdot G$。要签署消息 $m$:
$n_1 = H(m | sk_1), \quad n_2 = H(m | sk_2)$
他们交换公共 Nonce $N_1 = n_1 \cdot G$ 和 $N_2 = n_2 \cdot G$。聚合公共 Nonce 为 $N = N_1 + N_2$。
$s_1 = n_1 + c \cdot sk_1, \quad s_2 = n_2 + c \cdot sk_2$
到目前为止,一切都很好。每个人的 Nonce 都取决于他们自己的密钥和消息,因此看起来很安全。
攻击
问题是:Alice(攻击者)控制自己的 Nonce。她可以选择在第二次签名请求中使用不同的 Nonce,即使消息相同。
第一个签名(在消息 $m$ 上):
第二个签名(在相同的消息 $m$ 上):
Alice 现在有来自 Bob 的两个部分签名:
$s_2 = n_2 + c \cdot sk_2, \quad s_2' = n_2 + c' \cdot sk_2$
Bob 重用了 $n_2$,但具有不同的挑战。相减:
$s_2 - s_2' = (c - c') \cdot sk_2 \implies sk_2 = \frac{s_2 - s_2'}{c - c'}$
Alice 提取了 Bob 的密钥份额。凭借 $sk_1$(她自己的)和 $sk_2$(被盗的),她现在可以单方面签署任意消息。
Jake Craige 的一篇文章也介绍了这种情况。
大多数阈值签名方案都被证明在静态损坏下是安全的:对手在协议开始之前选择要损坏哪些方。但是自适应损坏呢?在这种情况下,对手可以在任何时候损坏各方,甚至在看到公钥、承诺和部分签名之后。 自适应安全性更难实现,也更难证明。最近的一篇论文(https://eprint.iacr.org/2025/1001.pdf)提出了一个问题:广泛部署的阈值 Schnorr 方案实际上是自适应安全的吗?如果某个计算问题结果比我们想象的要容易,那么答案可能是否定的。
设置
考虑一个 $(t,n)$ 阈值 Schnorr 方案,其中:
$pk = g^{q(0)}, \quad pk_i = g^{q(z_i)}$
其中 $z_i$ 是公共评估点,而 $sk_i = q(z_i)$ 是秘密份额。
这描述了 FROST 和大多数现代阈值 Schnorr 变体。
问题
作者提出了一个计算问题。如果这个问题可以在多项式时间内解决,则上述方案的自适应安全性将崩溃。
子集跨度问题: 给定一个目标向量 $\mathbf{v} \in \mathbb{Z}_p^t$ 和向量 $\mathbf{k}_1, \ldots, \mathbf{k}_n \in \mathbb{Z}p^t$,找到一个子集 $F \subset {1, \ldots, n}$,其中 $|F| = f \leq t-1$,使得 $\mathbf{v} \in \text{span}({\mathbf{k}*i}\{i \in F})$(如果存在)。
换句话说:你能否找到一个小的向量子集,其跨度包含目标?
攻击
假设对手想要伪造一个新消息 $m^$ 的签名。他们需要生成 $(R^, z^)$,使得 $g^{z^} = R^ \cdot pk^{c^}$,其中 $c^ = H(R^, pk, m^)$。这需要知道 $\log_g(R^ \cdot pk^{c^*})$,即验证方程右侧的离散对数。
这是计划:
*步骤 1:仔细选择 $R^$**
令 $X_i = g^{x_i}$ 为多项式系数的承诺(注意:给定 $pk_1, \ldots, pk_n$,你可以通过基变换计算 $X0, \ldots, X{t-1}$)。设置:
$R^* = X_0^{\alpha_0} X_1^{\alpha1} \cdots X{t-1}^{\alpha_{t-1}}$
对于随机的 $\alpha0, \ldots, \alpha{t-1}$。由于 $X_0 = g^{x_0} = g^{q(0)} = pk$,我们有:
$R^ \cdot pk^{c^} = X_0^{\alpha_0 + c^*} X_1^{\alpha1} \cdots X{t-1}^{\alpha_{t-1}}$
其中 $c^ = H(R^, pk, m^)$ 取决于我们对 $R^$ 的选择(并且可以计算)。
步骤 2:表示为公钥的线性组合
定义向量:
注意:
$X^{K0} = \prod{i=0}^{t-1} X_i^{(K_0)*i} = X_0 = pk$ $X^{Kj} = \prod*{i=0}^{t-1} X_i^{z_j^i} = g^{\sum\{i=0}^{t-1} x_i z_j^i} = g^{q(z_j)} = pk_j$
现在,如果我们能找到系数 $\mu_1, \ldots, \mu_f$ 和一个子集 $F \subset {1, \ldots, n}$ 且 $|F| = f \leq t-1$,使得:
$(\alpha_0 + c^*, \alpha1, \ldots, \alpha{t-1}) = \sum_{j \in F} \mu_j K_j$
那么:
$R^ \cdot pk^{c^} = X^{(\alpha_0 + c^*, \alpha1, \ldots, \alpha{t-1})} = X^{\sum_{j \in F} \mu_j Kj} = \prod{j \in F} (X^{K_j})^{\muj} = \prod{j \in F} pk_j^{\mu_j}$
取离散对数:
$\logg(R^ \cdot pk^{c^}) = \sum{j \in F} \mu_j sk_j$
步骤 3:自适应损坏
攻击者现在自适应地损坏 $F$ 中的各方,了解他们的秘密份额 $sk_j$,其中 $j \in F$。由于 $|F| \leq t-1$(低于阈值),这在损坏预算之内。他们计算:
$z^* = \sum_{j \in F} \mu_j sk_j$
并输出伪造的签名 $(R^, z^)$。验证通过构造。
为什么这可能有效 对于大小为 $f$ 的任何固定子集 $F$,随机目标向量 $\mathbf{v}$ 位于 ${\mathbf{k}*j}_{j \in F}$ 的跨度内的概率大约为 $p^{f-t}$(非常小)。但是有 $\binom{n}{f}$ 个可能的子集,呈指数级增长。如果 $n$ 足够大,则并集界限表明某个子集 $F$ 将以不可忽略的概率起作用。
问题是:我们能否有效地找到该子集?如果这个问题可以在多项式时间内解决,那么自适应安全性就会被破坏。
上述想法在论文 "A Plausible Attack on the Adaptive Security of Threshold Schnorr Signatures" 中有详细描述。
通过更好的测试、更严格的验证和仔细阅读安全证明,可以修复实现错误。协议问题需要理解你实际拥有的安全属性与你认为拥有的安全属性。MtA oracle 攻击之所以有效,是因为该协议的安全论证依赖于被省略的范围证明。重新共享攻击之所以有效,是因为该协议缺乏同步原语。阈值 Schnorr 的自适应安全问题表明,即使是经过充分分析的协议也可能在更强大的对抗模型下无法成立。
阈值方案仍然是我们分布式信任的最佳工具之一,但理论与实践之间的差距是真实且多方面的。确保你的实现和你的威胁模型与安全证明实际保证的内容相匹配。
- 原文链接: hexens.io/blog/mpc-attac...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!