在平坦汇编器(flat assembler)留言板的 Linux 分论坛,杰西(Jessé)于 2026 年 5 月 11 日 05:13 发帖,标题用英文写着超威半导体(AMD)的随机数生成器无法生成 0,后面附加 + app,表示帖子还附带一个应用程序。这个主题出现在 flat assembler 留言板的 Linux 分类中,标题提到随机数生成器并声称它不能生成 0。帖子标题中的 + app 写在括号里。正文开头写道,最近在写一些汇编代码,试图重新……之后可见内容就停在这里,没有显示完整句子,正文没有继续显示下去。
正文
Jessé(2026年5月11日 05:13)最近写汇编代码渲染数据图表,用 rdrand 和 rdseed 提供显示数据,意外发现 AMD 处理器(可能仅 Zen2)有个问题:在指定长度下无法生成数字 0。同一程序在 Intel 上则正常出现 0。大家可用他的应用(https://github.com/Jesse-6/random-fryer)查找生成的 0 并反馈,该应用也详细展示如何在 Linux 命令行控制台任意位置控制渲染数据。附带的图表测试应用展示了 AMD RNG 的 0 问题:在 AMD 主机上,你大概永远看不到第一根柱子从绿色(自创 TSC 方法生成随机数)变色,也看不到图表基准从 0 上升;Intel 上正常,基准能低于 0。第一根柱子显示 rdrand(红)、rdseed(蓝)和 TSC 自定义(绿)生成的零的数量,其他柱子显示 16 位空间里其余 65535 个数。修复方法是将 rdrand 和 rdseed 改为生成 32 或 64 位寄存器,同时保留 16 位数据作图。附测试应用 gtk4-bargraph.tar.gz,编译需 fastcallv1 宏包(https://github.com/Jesse-6/fastcallv1)。



Jessé(同日 05:16)迄今他的结果如下。

revolution(同日 05:28)32/64 位输出时,最低 16 位是否出现过全零?
Jessé(同日 05:36)会,用 32 或 64 位数时低位能输出 0,正如附件示例的修改。但 AMD 上符合请求大小的真零从不出现。
revolution(同日 05:41)希望 AMD 没蠢到认为 0 不是随机数。也许某个高管执行 RDRAND 得到 0,以为坏了,让工程师“修”了。
Jessé(同日 06:05)哈哈,我也这么想。可能发邮件给 AMD,有回复再来分享。
sylware(同日 10:22)曾涉足信息安全时有个经验:绝不使用硬件加速加密。
revolution(同日 11:36)对于可信硬件,硬件加速加密是首选;不可信硬件则软硬都别用。RDRAND 可能留后门,切勿单独使用,总要和其他源混合。非加密用途无所谓。
alCoPaUL(2026年5月13日 05:04)也许因为任何数乘 0 得 0,除 0 溢出……
Jessé(2026年5月15日 10:38)那 Intel 结果正常(请求大小下生成了 0)怎么解释?
Jessé(同日 11:00)更新:AMD 已回复,但技术支持似乎完全误读结果,或用 AI 写回。已再发详细答复和故障代码片段。
alCoPaUL(同日 14:21)也许 AMD 想到了 RNG 的最终用途,不只是直接吐数,而是公式一部分。而且 AMD 发明了 x86_64。
AsmGuru62(同日 15:39)好奇这些 CPU 指令生成的随机数质量,有人做过 Big Crush 测试吗?
sylware(2026年5月16日 11:15)以前那些生成物有熵缺陷,可被暴力破解大幅减负,也听过质数农场传闻。
Jessé(2026年5月23日 17:43)作为汇编程序员和电子工程师,我能想出上百种高质量随机数的构建法(如基于半导体热噪声)。这对 Intel/AMD 工程精英不难。AMD 至今无进一步反馈,但从发帖前 9 天到现在,接触的两颗 AMD 没出一个 0。应用已更新,可基准测试,也支持无 rdseed 的 CPU。基准结果:2012 Core i5 每秒 1260 万数,2017 i7 7700 仅 75 万,Ryzen 7 约 260 万;AMD 生成器对时钟变化惰性,而 2012 i5 依赖时钟。目前仍未找到 RNG 单元工作原理的可靠信息。
revolution(2026年5月24日 00:56)RDRAND 初推出时 Intel 文献称:非稳态噪声发生器(单比特)送时钟采样器,去偏电路,串行移位成 128 位种子;种子经高速 AES 计数器模式 CSPRNG 输出 RDRAND 位,定期重播;RDSEED 直接输出部分原始种子。当时 RDRAND 全速,RDSEED 慢。管线里 PRNG 致其非“纯”随机,但无人测出问题。后门可藏多处,难检测。
ttd3v(2026年9月19日 00:37)据我所知 rdrand 用作内核熵源,AMD 把 0 判无效虽怪,但本就不该当主加密 RNG;加密请用 OS 的 RNG,非加密目的则无碍。
评论
这场讨论的核心分歧在于:RDRAND 永不返回全零到底算不算严重缺陷——多数人认为由于熵源通常先喂给 CSPRNG,实际安全影响有限,少数人则强调统计偏差本身就不该被容忍。另外有实测者发现该问题在部分 Zen 3 芯片上无法复现,让人怀疑是否与具体型号或微码版本有关。
认为对实际安全影响很小
- 硬件随机数一般不会直接当密钥或随机数使用,而是作为 CSPRNG 的种子,全零缺失只是熵分布上一个可忽略的缺口(高赞)
- 即便真要用,通常也会对 rdrand 结果取模,取模后仍可能得到零,偏差量级约等于最大值分之一,实践中无关紧要(较多人)
- 有人指出,从对抗角度看这甚至可能是刻意设计:数学上全零并不比别的值更可能,但真人真的会去试那个密钥,跳过它反而少一个可被猜测的目标(较多人)
数学上它并不比别的数更可能出现,但偏偏会有人真去试那个密钥。(@ZiiS)
- 生成零的概率本来就极低,没观测到零可能只是采样次数不够,而非硬件刻意屏蔽(较多人)
认为统计缺陷本身不可接受
- RNG 的目标是不可预测,不是每个值等概率;但反过来说,永不输出某个特定值也是一种可被利用的结构性偏差,不能简单说「那又怎样」(少数人)
- 有人担心零被悄悄映射成了别的固定值,这会抬高该值的输出频次,问题比单纯少一个零更严重(少数人)
- 单靠统计测试套件未必发现这类缺陷,有人是在做 KDF 时通过给 16 位抽取结果画直方图才逮到类似问题(较多人)
实测与复现情况
- 有用户在自己的 Zen 3 上跑 16 位采样,得到 +1、0、-1 三档计数大致均衡,因此怀疑该问题在 Zen 2 之后已被修复,并准备积累更多 32 位样本(较多人)
- 另一位用户起初无法在 Ryzen 5 3600 上复现,后来发现 rdrand32 正常而 rdrand16 永远出不了全零,确认自己的 CPU 也有此问题(较多人)
- 这不是 Zen 2 上第一个 RNG 缺陷:早前曾有 rdrand 恒返回全 1、导致程序启动即退出的问题,最后靠微码更新修复;于是有人调侃,难道是用「永不产生全零」去修「永远产生全 1」(较多人)
- AMD 已就此发布安全公告,被讨论中引用作为官方确认(较多人)
有价值的补充
- 一种规避思路是改用 XOF(可扩展输出函数):把 rdrand16 的多次输出、系统时间微秒、收包间隔毫秒等多个来源的熵一起喂进去,即使某一来源永远缺 0x0000,输出流仍不会带上这个痕迹。
- 硬件验证投入巨大却仍漏掉这类问题,让人好奇它究竟是怎么穿过重重测试的——这类缺陷往往不影响正常功能路径,只有专门做分布检查才会暴露。
- 一个值得追查的开放问题:零是否被映射成了其他固定值?rdrand 是否由多次内部状态读取拼成,导致更大位宽的随机数耗时更长?