一句话版本
MPC(多方安全计算)钱包把私钥拆成多个份额,分给不同的设备或服务器,签名时各方协同计算出一个普通签名,完整私钥从头到尾都不在任何一个地方出现。它比单把私钥更抗单点失守,链上看起来又和普通地址一样。 但门限 ECDSA 的协议非常复杂,理论上安全,不等于实现上安全。2023 年披露的 BitForge 和 TSSHOCK 等漏洞表明:参数没校验、零知识证明被省略,就可能让一个恶意参与方从别人的份额里算出完整私钥。
全文分三层:
- 通俗理解:从"拆钥匙"到"永远不拼钥匙"
- 实际用处:机构托管、交易所、个人 MPC 钱包,以及真实漏洞
- 原理与工程要点:门限 Schnorr 与门限 ECDSA 的难度差异、份额刷新、实现检查清单
第一层:通俗理解
1.1 从"拆钥匙"到"永远不拼钥匙"
| 方案 | 做法 | 弱点 |
|---|---|---|
| Shamir 分片 | 私钥拆成几份分开存,用的时候拼回来 | 拼回来的那一刻,完整私钥出现在某台机器上 |
| 多签(链上) | 链上合约要求多个独立私钥签名 | 规则公开、手续费高、每条链要单独部署 |
| MPC / 门限签名 | 各方各持一份,直接协同算出签名,从不拼回私钥 | 协议复杂,实现容易出错 |
1.2 一个比喻
三个人各知道一个数字的一部分,他们要一起算出"这个数字乘以某个公开的数"的结果。通过一套精心设计的交换信息的规则,三人最终都得到了正确结果,但谁也没有得知那个完整的数字。门限签名就是在做类似的事,只是"乘法"换成了签名运算。
第二层:实际用处
- 机构托管和交易所:Fireblocks、Coinbase 等机构的托管系统大量使用 MPC,把份额分布在不同的服务器、不同的云、硬件安全模块中。
- 个人 MPC 钱包:典型配置是"手机一份、服务商一份、备份一份",丢了手机可以用另外两份恢复,没有助记词。
- 链上无感:MPC 产生的是标准签名,链上看起来就是普通地址。这一点和EOA与智能合约钱包里的多签不同:不额外花手续费,但规则也不在链上强制执行。
真实漏洞:
| 披露 | 问题 |
|---|---|
| BitForge(Fireblocks 研究团队,2023) | 多个流行的门限 ECDSA 实现(基于 GG18 / GG20 等协议)省略或简化了对 Paillier 密钥参数的零知识证明。恶意参与方可以构造特殊参数,通过几次签名交互就算出其他人的份额 |
| TSSHOCK(Verichains,2023) | 一些实现中,零知识证明的哈希编码方式有歧义、或者挑战值空间太小,攻击者可以伪造证明 |
这些都不是协议论文里的数学错误,而是实现时为了性能或省事跳过了检查。
第三层:原理与工程要点
3.1 门限 Schnorr 容易,门限 ECDSA 难
Schnorr签名的签名值 对私钥 和随机数 都是线性的。如果 和 都用Shamir秘密分享拆开,各方算出自己的 ,再用拉格朗日系数加起来就是完整签名。FROST 协议就是这样做的。
ECDSA 的签名值是
里面有一个 ,还有 和 的乘积。分片之后的乘法和求逆都不能简单地"各算各的再相加",需要额外的密码学工具:常见做法是用 Paillier 同态加密(见《同态加密》)或不经意传输(OT)来做"秘密分享的乘法",并配合大量零知识证明保证每一方都诚实。协议步骤多、参数多,出错的地方也多。
3.2 份额刷新(proactive refresh)
如果攻击者能慢慢地一份一份偷,总有一天会凑够门限。对策是定期刷新:各方协同把份额换成一组新的,对应的私钥不变,旧份额作废。这样攻击者必须在同一个刷新周期内偷够门限份额。
刷新协议本身也要小心:刷新中途失败、或者有一方离线,不能留下"一半新一半旧"的混乱状态。
3.3 实现检查清单
| 检查 | 说明 |
|---|---|
| 所有零知识证明都必须验证,不能为了性能跳过 | BitForge 的根源 |
| 对其他参与方提供的参数做完整校验 | 例如 Paillier 模数确实是两个大素数之积、没有小因子(参见《素性检验》) |
| Fiat–Shamir 哈希要编码所有上下文,且无歧义 | TSSHOCK 的根源(见《Schnorr签名》 里的 Fiat–Shamir) |
| 挑战值空间足够大 | 太小会让伪造证明可行 |
| 签名随机数不能重复,也不能被单方控制 | 否则回到椭圆曲线里 重复的灾难 |
| 恶意参与方被发现时能识别并排除 | "可识别中止"(identifiable abort) |
| 使用经过审计、仍在维护的库,跟进安全公告 | 不要自己实现 |
3.4 MPC 不能解决的问题
- 策略在链下:MPC 服务端"只在满足策略时才参与签名",这个承诺靠的是服务端代码和运维,而不是链上规则。服务端被攻破,策略就可能失效。
- 前端被篡改:所有参与方都对同一笔被篡改的交易签名,MPC 照样会产出一个有效签名(参见《Bybit事件与前端完整性》)。
- 服务商依赖:如果某一方是服务商,服务商倒闭或拒绝服务时能否用剩余份额恢复?这一点在选择产品时要问清楚。
总结
| 层次 | 要点 |
|---|---|
| 思想 | 份额协同算签名,完整私钥永不出现 |
| 难点 | ECDSA 的 和乘积让门限化很复杂;Schnorr 简单得多 |
| 教训 | BitForge、TSSHOCK:协议没错,实现跳过了检查 |
| 局限 | 策略在链下;挡不住前端篡改;要定期刷新份额 |