一文说透跨链桥技术中的核心:随机数「k」和「R」值
随着大部分 DeFi 项目逐渐开始从以太坊走向多链布署,用户在各条链之间转移资产变成了一种刚需。而跨链的资产转移从资产所有权这个技术维度上可以分为:托管型 Custodial Service 和去中心化型 Decentralization (或者叫非托管型 Non-custodial)两个大类。由此应运而生了众多提供给用户进行资产链间转移的「桥」。很有意思的一个现象是继前几个月的 DeFi 协议频繁被黑客盯上之后,由于这些跨链「桥」上同样储存了大量的资产,其逐渐成为了黑客攻击的一个热点。近期我们就留意到业界几次针对跨链桥的攻击,跨链桥被⿊造成了协议和用户价值数百万美元等值的损失。 一般来说,黑客都会选择去中心化型的跨链桥作为目标,因为托管型的桥属中心化方式控制资产,被攻破的难度较大;而去中心化的跨链桥,由于涉及比较精细的密码学设计和计算机代码的工程实现,往往容易在某处生产漏洞从而被黑客抓住利用进行攻击。
本文将介绍分析用户一般了解较少的跨链桥的核心:多方安全计算中的核心-随机数「k」和由 k 推导出的 R 值的过程,科普一下这些攻击事件到底是如何发生的以及一座可靠的去中心化跨链桥应该是怎么实现。以飨读者。
Anyswap安全事故是由于链上出现了两笔具有相同 R 值数字签名的交易,黑客通过两个签名值计算出了 Anyswap 跨链桥 MPC 控制的账户的私钥,进而盗走了其中的资产。那么私钥究竟是如何通过签名计算得到的呢?有什么办法去防范这一安全漏洞的产生呢? 首先我们要了解一下这个 R 值是什么。
「R」值——账户安全的阿卡琉斯之踵
众所周知,区块链账户的权限是通过数字签名实现的,即用户用私钥对交易数据签名来完成账户资产的转移。目前区块链中广泛使用的数字签名算法是 ECDSA,它属于「非确定性」一类的数字签名算法,即同一数据会有多个合法的签名,这是由于 ECDSA 在每次签名过程中都会引入随机数 k,而 R 值就是通过 k 计算得到的。这就等于说:要想破解出来私钥,必须要获得同样的 R 值;获得同样的 R 值,就等同于随机数 k 值暴露了或者发生碰撞(即两个签名具有相同的 R)。所以随机数 k 的重要性等同于私钥。
假设有两笔交易的签名过程使用了相同的随机数 k,那么两个签名值的 R 是相同的。不妨设两个签名为 (R, s1) 和 (R, s2),那么根据 ECDSA 的算法过程有以下代表这两笔交易的两个等式:
其中 m1 和 m2 是交易数据,而 sk 是账户私钥。
观察上面两个等式,其中 s1、s2、R 是签名数据,m1 和 m2 是交易数据,都是公开透明所有人都知道的,而未知数只有两个,即 A)随机数 k 和 B)账户私钥 sk。根据简单的计算,两个未知数,两个方程,那就可以求解得到未知数的值,这就是中学数学中的「解方程」!所以可以自然地求解得到私钥公式如下:
由于在 Anyswap 攻击事件中,黑客发现两次交易过程中的签名都使用了相同的随机数 k!所以黑客很容易的就计算出来控制跨链资产桥的私钥 sk 出来!然后就是拿着还原的私钥把跨链锁定合约里的所有资产转走!
那么问题来了:这个这么重要的随机数 k 值为什么会重复出现?接下来就引入为什么要用多方安全计算这样一个方案来产生随机数的原因。
真正采用 MPC 账户签名的话,k 值是不可能被泄露的!
相比普通账户签名,多方安全计算 MPC,Multi-party Computation (这里要特别说明,多方安全计算不是多重签名!)账户签名过程无疑是非常复杂的。因为签名参与者不再是单一控制人,而是 N 多个控制人合作完成签名过程,简单点类比,就是多人协作的过程。在普通账户签名过程,只需要在 R 值生成过程中使用真随机数发生器,基本可保证安全;而在 MPC 账户签名过程中,由于参与者不唯一,而且理论上认同可以存在恶意节点,因此 R 值的生成不再可以依赖单一用户生成,因为一旦该用户是恶意的,他将能够自己控制随机数 k,从而控制 R,进而计算得到 MPC 账户私钥,窃取资产。因此在 MPC 账户签名过程中,R 的生成必须满足以下 3 大原则:
非单一用户生成
任何人都无法获得 R 对应的 k 值
随机数 k 的生成要足够的随机,满足无偏性和不可预测性
用一句通俗的话形容这个过程就是:既要一群人一起协作干活,又不能让你们知道你们在干什么!
典型的 MPC 的设计实例:可验证秘密分享- Wanchain MPC 账户 R 值安全性的核心保证
在 Wanchain 跨链桥机制中,跨链资产是由锁定账户保管,而锁定账户则是由 25 个匿名(这个数值可以根据需要扩展或者减少) Storeman 节点通过多方计算(MPC)的方式共同管理。在锁定账户签名过程中,R 值是由 25 个 Storeman 节点通过可验证秘密分享(PVSS)共同决定,保证不会发生两笔交易签名 R 值相同的情况。具体步骤如下:
第一步:各 Storeman 节点在本地通过真随机数发生器产生一个随机数;
第二步:各 Storeman 节点将进行 Shamir 秘密分享,并将秘密碎片通过安全信道传输给其他节点;
第三步:收到其他节点传输的秘密碎片后,各 Storeman 节点在本地进行累加,得到一个组秘密碎片,然后将该组秘密碎片与椭圆曲线基点相乘,并将结果广播;
第四步:各 Storeman 节点对广播的数据进行拉格朗日插值计算,得到一个椭圆曲线点,其横坐标即为 R 值。
虽然以上过程稍显复杂,但是核心思想很简单,那就是 R 值是由 25 个 Storeman 节点共同确定的,每个 Storeman 节点贡献一部分加密的碎片,最终通过密码运算合成了 R 值。也就是实现了上面那句话描述的状态:既要你们协作一起干活,但是你们都不知道你们在干什么,其他人是谁。
可验证秘密分享可以确保:
任何两笔交易具有同样的 R 值是不可能发生的
首先,R 值是有 25 个 Storeman 节点共同确定的,而不是由单一节点确定,理论上只要 25 个 Storeman 节点中存在 1 个诚实节点,那么 R 值就是随机的;其次,各节点对 R 值贡献的部分是通过真随机数发生器产生的,分布足够均匀。综合两点,两笔交易具有同样 R 值的情况只有在 25 个 Storeman 节点在两次签名中选择的随机数加和相等的时候才会发生,这一概率是 2-256,形象地说,比走在路上被陨石砸到脑袋的概率都小。
R 值对应的 k 是完全保密的
在前文我们说过,k 一旦泄露,私钥就可以计算得到。在 Wanchain 锁定账户签名过程中,k 是由 25 个 Storeman 节点共同决定,但是由于秘密碎片是通过安全信道传输给各节点,因此没有任何一个节点能够恢复出完整的 k 值。也就是说,k 值是仅仅是一种理论中的存在,能够正常完成 MPC 签名过程,但是确实任何人都不可见的。
通过 1 和 2 两点的分析,得出 Wanchain 跨链桥的实例中锁定账户安全性是极高的,不会出现私钥泄露的情况。
那什么样的情况会导致出现 Anyswap 的两笔交易出现相同的 R 值?
我们没有全部读完 Anyswap 项目的 MPC 这部分代码,只能通过上述的 MPC 的理论和实现机制推导这样的结论:1)要不是没有采用真正 MPC 的实现过程而只是挂了一个 MPC 的名义,还是由单一个体产生随机数 k,从而造成 k 重复出现的情况;或 2)代码在实现上出现了重大的代码问题,而这种重大技术失误在严谨的开发团队看来是完全不应该出现的。
在另外一篇文章《理想中的跨链桥,是什么样?》 中关于 MPC 跨链桥有一段这样的表述:「Anyswap:用一句话来解释「黑客发现了 Anyswap 的代码漏洞,从而拿到了公私钥对,盗走了资产」,更像是各类项目都会出现的漏洞。」 笔者并不太认同各类采用 MPC 都会出现的漏洞这句话的论断。业界我们交流的几个实现了 MPC 的同行都不认为这样的漏洞或者错误是个都会出现的普遍现象,采用 MPC 的精髓就是实现了多方的匿名安全计算,否则如果连这个都不能保证,何必采用 MPC,用个多签,单签的方案岂不更简单,安全性更高?「如果能够使用足够多节点的公链共识,则能很大程度上避免类似这次被攻击的情况(MPC 不够去中心化的选型)。」 这句话的结论同样不敢苟同。不同交易签名 R 值是否重复并不取决于节点的个数,而是取决于签名过程中随机数的生成方式。如果签名过程中随机数是多个节点通过多方计算共同决定,那么仅 20 个节点也同样能够产生安全随机数;反之,如果签名过程中随机数是并不是以安全的、分布式的方式产生,那么堆积再多的节点也是徒劳。该项目浏览器上显示有超过 20 多个节点参与 MPC 计算,如果计算方式的确为 MPC,那么发生 R 值碰撞的概率是忽略不计的。因此该项目将两笔交易签名 R 值相同的原因归结于参与 MPC 节点数量不足,无疑是避重就轻,具有很强的误导性。
在文章的最后,特别想和大家强调一下随机数对于区块链的重要性,它不仅仅用在账户签名过程,而且也用在 PoS 共识和分片 Shard 算法等领域,直接决定整个系统的安全性,万万不可忽视。一个小小的随机数生产,并不是那么简单,是整个数学界,密码学界一直以来孜孜追求不断优化的一个圣杯领域。一个区块链团队还是应该多在分布式随机数生成算法领域不断积累,设计并不断优化链上随机数发生器,这样才能够为跨链和共识过程提供安全随机数,为整个区块链,DeFi 领域提供可靠、可用、可信的跨链桥。
微信掃描關注公眾號,及時掌握新動向
2.本文版權歸屬原作所有,僅代表作者本人觀點,不代表比特範的觀點或立場
2.本文版權歸屬原作所有,僅代表作者本人觀點,不代表比特範的觀點或立場