当前位置: 首页 > 知识库问答 >
问题:

英特尔的RDRAND是否有任何合法用途?

咸高谊
2023-03-14

今天我想:好吧,即使人们对NIST SP 800-90A的RDRAND实现有很大的怀疑,它仍然是伪随机数生成器(PRNG)的硬件实现,对于非敏感应用程序来说必须足够好。所以我想在我的比赛中使用它,而不是Mersenne Twister。

因此,为了查看使用该指令是否有任何性能提升,我比较了以下两个代码的时间:

// test.cpp
#include <cstdio>

int main()
{
    unsigned int rnd = 0;
    for(int i = 0; i < 10000000; ++i) {
        __builtin_ia32_rdrand32_step(&rnd);
    }
    printf("%x\n", rnd);
}

//test2.cpp
#include <cstdio>
#include <random>

int main()
{
    unsigned int rnd = 0;
    __builtin_ia32_rdrand32_step(&rnd);
    std::mt19937 gen(rnd);
    for(int i = 0; i < 10000000; ++i) {
        rnd ^= gen();
    }
    printf("%x\n", rnd);
}

通过运行这两个,我得到:

$ time ./test
d230449a

real    0m0.361s
user    0m0.358s
sys     0m0.002s

$ time ./test2 
bfc4e472

real    0m0.051s
user    0m0.050s
sys     0m0.002s

所以,Mersenne Twister在我的CPU上比RDRAND快得多。嗯,我很失望,被排除在比赛之外。但是RDRAND是一种加密安全的PRNG(CSPRNG),所以它在幕后做了很多事情。。。与其他CSPRNG相比更公平。因此,我采用了我的Rabbit实现(将RFC简单地翻译为C,无需花哨的性能技巧),并编写了以下测试:

// test3.cpp
#include <cstdio>

extern "C"
{
#include "rabbit.h"
}

int main()
{
    rabbit_state s;
    unsigned long long buf[2];
    __builtin_ia32_rdrand64_step(&buf[0]);
    __builtin_ia32_rdrand64_step(&buf[1]);
    rabbit_init_key(&s, (uint8_t*)&buf[0]);

    for(int i = 0; i < 10000000; ++i) {
        rabbit_extract(&s, (uint8_t*)&buf[0]);
    }
    printf("%llx\n", buf[0]);
}

令我惊讶的是,生成的伪随机数据是前两个的两倍,我得到了比RDRAND更好的时间:

$ time ./test3 
8ef9772277b70aba

real    0m0.344s
user    0m0.341s
sys     0m0.002s

这三个都是在启用优化的情况下编译的。

因此,我们普遍怀疑RDRAND是为了将NSA后门嵌入到每个人的软件密码学中。此外,我们至少有一个软件CSPRNG比RDRAND快,而且使用最广泛的体面PRNG,Mersenne Twister比RDRAND快得多。最后,我们有开源可审计的软件熵池,如/dev/随机/dev/urandom,它们不隐藏在AES的双重扰码层后面,如RDRAND。

那么,问题是:人们应该使用RDRAND吗?它有任何合法用途吗?或者我们应该完全停止使用它吗?

共有3个答案

元英朗
2023-03-14

英特尔的RDRAND是否有任何合法用途?

考虑蒙特卡洛模拟。它不需要密码学,所以它是否由国家安全局支持并不重要。

或者我们应该完全停止使用它?

我们无法回答这个问题。这是用例、需求和个人偏好的融合。

...此外,我们至少有一个比RDRAND更快的软件CSPRNG,以及使用最广泛的体面PRNG...”

Mersenne Twister在初始化后的某个单词可能更快,而没有Twists,因为它从状态数组返回一个单词。但我怀疑它是否像连续流的RDRAND一样快。我知道RDRAND可以根据连续流中的总线宽度达到理论限制。

根据Intel的DavidJohnston(设计电路的人),这大约是800 MB/s。请参阅DJ关于Ivy Bridge上RDRAND指令的延迟和吞吐量的回答?。

所以,我们有一种普遍的偏执狂,认为RDRAND是为了将NSA后门嵌入到每个人的软件加密中。

偏执狂至少有两个选择。首先,他们可以放弃使用RDRAND和RDSEED。其次,他们可以使用RDRAND和RDSEED的输出来播种另一个生成器,然后使用第二个生成器的输出。我相信Linux内核采取第二种方法。

花飞尘
2023-03-14

RDRAND不仅仅是一个PRNG。它是一个符合FIPS的白化TRNG。不同的是,您可以依靠RDRAND包含相当多直接从CPU检索的实际熵。所以RDRAND的主要用途是为操作系统/库/应用程序提供熵。

应用程序检索熵的另一个好方法通常是使用操作系统提供的熵源,如/dev/random/dev/uradom(通常从/dev/random提取熵)。然而,该操作系统还需要在某处找到熵。通常使用磁盘和网络访问时间的微小差异(其他半随机输入)。这些装置并不总是存在,也不是设计为熵源;它们通常不是很好的来源,也不是很快。因此,在支持它的系统上,RDRAND通常被用作操作系统加密安全随机数生成器的熵源。

关于速度,尤其是对于游戏,使用(不安全的)PRNG是完全有效的。如果你想有一个合理的随机种子,那么用RDRAND的结果播种可能是个好主意,尽管从操作系统提供的RNG播种可能是一个更便携甚至更安全的选择(以防你不完全信任英特尔或美国)。

请注意,目前RDRAND是使用(AES)CTR\U DRBG实现的,而不是为Rabbit这样的速度而创建的(分析较少的)流密码,因此Rabbit的速度更快也就不足为奇了。更重要的是,它还必须从CPU内的熵源中检索熵,然后才能运行。

岳良策
2023-03-14

正如在另一个答案中指出的那样,RDRAND被植入了真正的随机性。特别是,它经常使用128位硬件生成的随机性对其内部CSPRNG进行重新种子设定,从而保证每511×128位至少重新种子设定一次。见本文件第4.2.5节:

https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide

因此,在您的示例中,您使用单个128位种子从rabbit_extract生成1000万随机绘制。在RDRAND版本中,您拥有相当于250万128位绘制的内容,这意味着CSPRING至少被重新播种2,500,000/511 = 4,892次。

因此,在rabbit示例中没有128位的熵,而在RDRAND示例中至少有4892*128=626176位的熵。

这比没有硬件支持时在0.361秒内得到的熵要多得多。如果你在做一些真正随机性很重要的事情,这可能很重要。一个例子是Shamir秘密共享大量数据——不确定是否还有其他数据。

总之——这不是为了速度,而是为了高度安全。当然,它是否是后门的问题很麻烦,但是你总是可以将它与其他来源异或,至少它不会伤害你。

 类似资料:
  • 我正在使用Intel Ivy Bridge CPU,希望使用RDRAND操作码(https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide)在C#中。 如何通过C#调用此CPU指令?我在这里看到了一个从c#执行汇编代码的示例:C#

  • 问题内容: 从我读到的内容来看,它用于修复CPU中的错误,而无需修改BIOS。根据我对汇编的基本知识,我知道汇编指令在内部由CPU分解为微代码,并相应地执行。但是intel以某种方式可以在系统启动和运行时进行一些更新。 有人有更多信息吗?是否有关于微码可以做什么以及如何使用的文档? 编辑:我读过维基百科的文章:没弄清楚我怎么能自己写一些,以及它有什么用。 问题答案: 在较早的时期,微代码在CPU中

  • 问题内容: 每次与Hotspot一起使用时,都不得不烦恼我,不得不阅读可怕的AT&T语法。 有没有办法告诉它使用英特尔语法? 问题答案: 您所需要做的就是将一些选项解析到dis-asm.h和binutils代码上 对于Intel Asm(我也更喜欢),只需添加以下内容 如果您需要组合选项,请像这样用逗号分隔 任何未被识别为hsdis选项的内容都将被提供给反汇编程序,这些选项与您从中看到的选项相同

  • 本人背景算法工程师,cv方向论文两篇,nlp实习经历。 一轮 25min 自我介绍 询问项目论文 问题:resnet架构、c++程序执行过程 反问 二轮 40min 自我介绍 询问项目论文(论文很细致,结构、损失、数据集、实验结果、创新点) 问题:Transformer架构、核心公式以及采用什么的正则化、BN和LN的区别。其实大部分是根据论文内容发散 反问 三轮HR面 25min 没有自我介绍 问

  • Intel内存型号保证: 门店不会与其他门店一起重新订购 货物不会与其他货物一起重新订购 http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/ 我看到有人声称由于英特尔内存模型,SFENCE在x86-64上是多余的,但从来没有LFENCE。上述内存模型规则是否使任一指令冗余?

  • 如何使用Java中的Intel AVX矢量指令集?这是一个简单的问题,但答案似乎很难找到。