看看审计团队眼中的Monero RandomX有哪些问题

原文 | OSTIF 翻译 | Tracey 我们与门罗币社区、Arweave、门罗研究实验室和四个审计团队合作,深入彻底地审查RandomX算法。RandomX是一种新型工作证明算法,旨在实现加密货币的“平等主义”。
《财富代码》-深度分析、挖掘区块链价值项目,https://www.first.vip/hodl

原文 | OSTIF
翻译 | Tracey

我们与门罗币社区、Arweave、门罗研究实验室和四个审计团队合作,深入彻底地审查RandomX算法。RandomX是一种新型工作证明算法,旨在实现加密货币的“平等主义”。

RandomX算法旨在让那些经过高度优化的定制硬件的挖矿效率降低或低于通用计算机硬件。通用计算机属于人人都可以使用的普通计算机。Randomx背后的想法是,让普通大众和门罗爱好者加入挖矿,避免验证加密货币交易的算力集中化。

加密货币的经典问题之一,如果一方(或作恶者通过结盟)拥有51%以上的网络算力,他们就可以通过重写交易来“复制”货币、让真正的交易失效、或者操纵网络。专用设备(ASIC和和FPGA)的兴起,让那些投入设备资源的联盟在算力上占据上风。

RandomX算法提升了算法的复杂度,让ASIC和FPGA无法高效地优化运算。与通用硬件相比,ASIC和FPGA设备要么速度明显放缓,要么因为算法过于复杂而增加构建成本,或增加运行成本。

RandomX虽是一个新概念,但它以一种有趣的方式应用了许多著名加密函数。

为了验证RandomX算法的安全性,Monero Research Lab、Monero社区和Arweave都大力赞助了此次与我方合作的安全性研究。

四次审计属于一个系列,每次审计的结果和修改都会提交到下一次审计中。此次联合审计给我们带来了各自团队的视角,以及查看其他人审核的代码的机会,形成一次全面的安全审核。

审计范围

审计的目标不仅仅是确定编码和密码学的正确性,还要确定ASIC和FPGA难以设计出比通用硬件更优的运算。

大框架

四个安全团队一致认同RandomX的代码质量非常高,但文档还可以改进,避免非Monero或非Arweave区块链应用RandomX算法时出现错误,四个团队均未发现能够显著提高算力的漏洞,没有专用软件(ASIC或FPGA)可以轻轻松松地绕开RandomX的函数和组件。各个团队达成的共识是,RandomX代码几乎可以直接部署,随着RondomX不断演进和更新,一些小型编码实践和文档编写会逐渐改善,进一步提升安全性。

当然,团队还针对进一步增强RandomXs对专用硬件抗性提出了一些建议。

“已修复(FIXED)”是指应用了补丁来纠正错误。

“已解决(SOLVED)”指由RandomX团队给出的澄清,证明该问题无需修复。

“存有争议(DISPUTED)”指RandomX团队反对评估结果。

如果一个问题没有状态,是因为该问题仍处于团队间讨论之中。没有状态不代表存在争议,只是说明OSTIF(撰写本文方)不知道目前的状态。随着我们对问题的了解深入,会逐渐更新问题状态。

第一次审计——由Arweave赞助Trail of Bits

问题1——AesGenerator Single Round问题——“已修复”

RandomX使用一轮AES来实现数据扩散,但我们至少要两轮AES才能混淆源数据。这是有问题的,因为在一个攻击场景中,如果攻击者能在RandomX中的其他组件中找到相似的偏差,他们无需计算就可以直接跳过算法部分,使得简易型ASIC和FPGA的设计成为可能。只有许多RandomX函数出现类似问题时,才会出现这种情况。尽管如此,RandomX现在已更新,开始使用AesGenerator4R,AesGenerator4R执行四次AES循环来正确地混合和扩散数据。

问题2——虚拟机正确性的测试和验证不足——“已修复”

RandomX应用了虚拟机,但缺乏用于测试的机器可读规范。这一点非常关键,因为随着RandomX的实施有所变动,极小的更改都可能引发区块链在不可预知的位置发生分叉。根据规范来测试,就能在(极少发生且难以检测的)问题在链上发生时,检测出来。现在测试得到了显著扩展,针对每个RandomX指令都可以进行单元测试。

问题3——脆弱的RandomX可配置参数——改进请求59——“已修复”

RandomX有大量配置参数,便于多个加密货币项目实施RandomX。其中一些参数会严重削弱RandomX的安全性和ASIC抗性。强烈建议一定要在对RandomX的安全性和健壮性产生明显影响的参数中添加注释,并将移除修改危险参数的权限作为一个长期目标。RandomX团队增加了对参数的检查,确保参数的正确性。同时还大大增加了关于如何选择参数的文档数量。

附加讨论

要提高代码质量,建议改进SuperscalarHash的随机性。Trail of Bits还对RandomX做了复杂的随机性分析,发现RandomX的各种路径选择充分,防止那些经常利用偏差优化特定路径的做法。团队还提供了一个极佳资源,支持安全地更改RandomX可调参数。还为Trail of Bits的赞助商Arweave推荐了具体的参数值。

第二次审计——由OSTIF、Monero研究实验室和Monero社区赞助Kudelski Security
(与Trail of Bits审计结果相同的部分已略去)

问题1——使用未优化的BLAKE2——“已解决”

RandomX的BLAKE2版本哈希函数没有经过优化,并且没有利用AVX512 CPU进行优化。使用优化版的BLAKE2,速度可以加快40%。然而,RandomX的整体性能并不依赖BLAKE2,因此改进这一代码的唯一真正好处是缩小功耗/cpu时间。RandomX团队正在探索未来发布BLAKE2的优化版本LibSodium。

问题2——缺少空值检查——改进请求88——“已修复”

当RandomX在大部分代码区域取消引用指针时,不执行空值检查。对于那些允许取消空指针引用的语言中,不执行空值检查一个常见安全问题。即使你对自己的代码很自信,也要保证空值检查,因为后面通过空值检查捕获的更新可能引入错误。

问题3——randomx_reciprocal()可以除以0——改进请求88——“已解决”

除以0可能导致崩溃和其他破坏行为。在与开发团队讨论之后,代码的其他区域会保证结果不为零,并在改进请求88中增加了检查。

问题4——randomx.cpp出现类型不匹配错误——改进请求88——“已修复”

攻击者可能会利用精心设计的输入,强制执行破坏行为(整数溢出)。于是RandomX团队增加了代码检查和判断提示,避免无效输入导致应用程序奔溃。

问题5——getCodeSize()存在潜在的整数下溢问题——改进请求95——“已修复”

问题6——randomx.cppw无法手动检查Blake2b哈希错误——“已解决”

哈希错误可能导致RandomX进入失效状态,允许用户绕过RandomX中的一些步骤。虽然在此之前,已有在编译时检查哈希错误的规定,但开发团队还是向RandomX添加了第二保护层,以便手动检查Blake2b哈希错误,并在遇到错误时跳出判断提示(应用程序奔溃)。

问题7——fillAes1Rx4()和fillAes4Rx4()中存在越界写入——改进请求95——“已解决”

这不算是一个问题,因为在编译时(compile-time)检查边界,可以增加安全性。

问题8——isPowerOf2()的输入为0,而非2的幂值——改进请求95——“已解决”

检查出一个值被错误地标记为“isPowerOf2()”,且函数isPowerOf2()允许调用0值,导致潜在的失效行为。与RandomX团队讨论之后,支持在函数中调用0,我们希望支持函数调用0,但为了更清楚地表示检查的作用,将isPowerOf2()重命名为isZeroOrPowerOf2()。

第三次审计——由OSTIF、Monero研究实验室、Monero社区赞助X41 D-Se

问题1——JIT编译器的硬编码代码大小——改进请求98——“已修复”

RandomX JIT编译器的硬编码大小为64k,更改RandomX设置可以增加硬编码代码大小,

(对非monero实现会有影响),也可能影响安全性和稳定性。

问题2——跳转目标计算(Jump-Target Calculation)中的整数处理问题——“已解决”

跳转目标计算未考虑极端情况,这种情况可能导致整数溢出或整数循环。与RandomX团队讨论之后,问题得以解决,有一些有效输入可以防止该问题发生。

问题3——32位系统不考虑数据集大小——改进请求99——“已修复”

在32位系统中,由于32位寻址内存分配的大小限制,数据集大小可能溢出到非常小的数字。与RandomX团队交谈之后,不打算将RandomX应用于32位遗留系统,因为与现代PoW算法相比,RandomX不具竞争力。改进请求99新增了一个检查来正确引出问题,而不是隐藏错误。

问题4——使用模拟模式时生成错误代码——改进请求98——“已修复”

X41发现RandomX在非默认参数的模拟模式下运行时存在诸多问题。这一发现很重要,因为只有Monero适用默认参数,其他项目都使用非默认参数。改进请求98纠正了这些问题。

问题5——AesGenerator4R无法广播——改进请求76——“已修复”

X41发现,AesGenerator4R函数中的密钥重用允许函数细微逆转。在AesGenerator4R中使用单一密钥是最佳实践。而且RandomX使用AesGenerator4R函数并不存在安全风险,因为输入是经过加密的哈希函数。

问题6——坏码问题——改进请求73——“已修复”

X41指出RandomX属于单片驱动程序,相比测试RandomX各个组件,测试整个RandomX更为容易。未经直接测试的组件出现问题的概率很低。在改进请求73中,在代码中添加了测试向量和附加回归测试。

问题7——JIT内存页生成的代码是可写且可执行的——改进请求112——“可选修复”

JIT编译器具有不必要的读、写和执行权限。消除JIT编译器同时编写和执行的能力可以减少攻击者利用JIT编译器中的错误执行任意代码的可能性。在改进请求112中修正了这一问题,但是这种切换对挖矿性能造成了很大的冲击(约30%),这是大多数人无法接受的。因此,JIT编译器被设置为启用/禁用选项。

问题8——沙箱RandomX执行问题——“已解决”

因为RandomX的应用场景是从外部(区块)获取和处理用户数据,不排除攻击者找到绕过RandomX虚拟机安全属性的输入的可能性。如AppContiner或seccomp提供的沙箱技术,可以减少攻击者找到目标输入的可能性。但RandomX团队不同意这种说法,因为攻击者如果修改值(发送伪造区块),Blake2哈希会立即得到反馈,这意味着如果RandomX中存在漏洞,无法通过有效控制输入发起攻击。

问题9——当程序过小时会导致超标量哈希(SuperScalarHash)延迟——改进请求98——“已修复”

即使应用程序没有足够的内存正常运行,一些参数组合也可能导致RandomX运行无效状态,建议全面检查程序内存大小。

问题10——缺乏机器可读的规范

RandomX缺乏测试机器可读的规范,因此无法简单地测试RandomX其他实现的结果。机器可读规范可以防止互操作性问题,帮助开发人员检测和修复替代实现中的代码漏洞。随着RandomX成熟,必定要建立一个机器可读规范。

ASIC/FPGA抗性1——低依赖于分支预测单元——“存有争议”

CPU的分支预测单元是一个复杂的、占用CPU大量内存的大型组件。RandomX不依赖于分支预测的逻辑,因此ASIC通过简化分支预测单元可以大大简化潜在的ASIC。与RandomX团队讨论之后,这点上我们仍然存有分歧,因为任何由分支预测器预测的逻辑都可以在ASIC中实现,而且可能更有效。

ASIC/FPGA抗性2——低依赖于前端调度逻辑

RandomX某些逻辑可用预处理器取代JIT并行执行,这使得专用芯片比cpu具有优势。与RandomX团队讨论之后,认为这部分代码的影响并不大,也不会显著影响性能,但是它会为ASIC节省一些电能。

ASIC/FPGA抗性3——低依赖于其他现代CPU元件——“存有争议”

RandomX没有使用过多复杂的现代CPU特性,比如:特权指令、中断和中断路由(x86 APIC)、TLB 8 s、MMU 9和虚拟内存、内核间通信和缓存一致性。虽然这些特性不占用大量的模具空间,但它们非常复杂,需要大量的研发来实现。向RandomX添加使用这些CPU特性将显著增加定制芯片的成本。RandomX不能实现许多自定义特性,因为它要适用于不同的CPU架构,而许多CPU架构可能缺乏这些特性。

第四次审计——由OSTIF、Monero研究实验室和Monero社区赞助QuarksLab

在前三次审计结果公布之后,由QuarksLab执行复杂的第四次审计。为了最大限度地发挥审计的效果,QuarksLab将RandomX的最新构建和前面团队做的所有工作都纳入了考虑范围。

问题1—— (RNDX-N1) 硬编码字符串的使用问题

Monore努力使RandomX协议完全支持定制,以实现安全重用。用6个硬编码字符串作为各个常数和密钥的种子。建议将字符串添加到配置集中,便于管理和定制字符串。问题1属于一个次要的代码实践问题,而非安全漏洞。

问题2——(RNDX-N2)警告不要重用RandomX组件——改进请求111——“已修复”

虽然现有AesHash1R、AesGenerator1R和AesGenerator4R组件的实现是可靠的,但需警告那些打算在自己的RandomX实现中使用RandomX组件的开发人员。如果在不同的语境中使用RandomX组件,将非常危险。

问题3——(RNDX-M1)Argon2实现不限制Salt大小——改进请求111——“已修复”

Argon2需要的salt最低大小为8字节,RandomX不强制执行此操作,如果salt过小,也不会显示错误。需要添加一个下限完整性检查。

问题4——(RNDX-L1) randomx_argon_lane和randomx_argon_iteration需要设立上限值——改进请求111——“已修复”

randomx_argon_lane上限为2^24-1,randomx_argon_iteration上限为2^32-1。

问题5—— (RNDX-L2)RANDOMX_ARGON_MEMORY需要设立下限值8——改进请求111——“已修复”

RANDOMX_ARGON_MEMORY的下限值目前是1,不考虑ARGON2_SYNC_POINTS=4的情况。

问题6—— (RNDX-L3) 规范中缺少与64字节对齐的mx和ma

问题7—— (RNDX-M2) 数据偏移计算错误——“已修复”

数据偏移计算不符合规范。QuarksLab与RandomX团队讨论后,发现这是RandomX较早实现的遗留代码片段,目前该问题已纠正。

问题8——RandomX密钥大小不受限制——改进请求111——“已修复”

RandomX指定的是一个60字节的输入密钥,但也支持加载更大字节的密钥。与RandomX团队讨论之后,根据设计,较大密钥将被截为60字节,RandomX正在通知用户截短大密钥字节的时间。

本文由 区块链资讯平台头等仓 作者:筋斗云 发表,其版权均为 区块链资讯平台头等仓 所有,文章内容系作者个人观点,不代表 区块链资讯平台头等仓 对观点赞同或支持。如需转载,请注明文章来源。
《财富代码》-深度分析、挖掘区块链价值项目,https://www.first.vip/hodl

发表评论