首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >英特尔的RDRAND有什么合法的用途吗?

英特尔的RDRAND有什么合法的用途吗?
EN

Stack Overflow用户
提问于 2014-11-06 03:39:42
回答 5查看 14.8K关注 0票数 16

今天我想:嗯,即使对NIST SP 800-90A的RDRAND实现有很大的怀疑,它仍然是伪随机数生成器(PRNG)的硬件实现,对于非敏感应用程序来说必须足够好。所以我想把它用在我的游戏里,而不是梅森·图斯特。

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

代码语言:javascript
复制
// 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);
}

代码语言:javascript
复制
//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);
}

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

代码语言:javascript
复制
$ time ./test
d230449a

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

$ time ./test2 
bfc4e472

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

所以,在我的CPU上,Mersenne Twister比RDRAND快得多。嗯,我很失望,被排除在比赛之外。但是RDRAND是一个密码安全的PRNG (CSPRNG),所以它在幕后做了很多事情.更公平的做法是将其与其他CSPRNG进行比较。因此,我采用了我的兔子实现(将RFC平移到C,没有性能方面的花招),并编写了以下测试:

代码语言:javascript
复制
// 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更好:

代码语言:javascript
复制
$ time ./test3 
8ef9772277b70aba

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

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

因此,我们有一种广泛的妄想,即RDRAND是用来将NSA后门嵌入到每个人的软件密码学中的。此外,我们至少有一个比RDRAND更快的软件CSPRNG,最广泛使用的PRNG,Mersenne Twister,比RDRAND快得多。最后,我们有开源的可审计软件熵池,比如/dev/random/dev/urandom,它们并不隐藏在像RDRAND这样的双重扰码层的背后。

那么,问题是人们应该使用RDRAND吗?它有什么合法用途吗?还是我们应该完全停止使用它?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-12-06 00:22:29

正如在另一个答案中指出的那样,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生成1,000万个随机抽签。在RDRAND版本中,您有相当于250万128位的绘图,这意味着CSPRING至少被重新加载了2,500,000/511 = 4,892乘以

所以,在你的兔子例子中没有128位熵,而是至少有4,892*128 = 626,176位熵进入RDRAND示例。

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

总之,这不是为了速度,而是为了更高的安全性。当然,它是否落后的问题是令人不安的,但您可以始终将其与其他来源异或,而且至少不会对您造成伤害。

票数 29
EN

Stack Overflow用户

发布于 2014-11-06 14:30:03

RDRAND不仅仅是一个PRNG。这是一个白化TRNG是FIPS兼容。不同之处在于,您可以依赖RDRAND来包含从CPU直接检索到的相当多的实际熵。因此,RDRAND的主要用途是向OS/库/应用程序提供熵。

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

关于速度,特别是在游戏中,使用(非安全) PRNG是完全有效的。如果你想要一个合理的随机种子,然后用RDRAND的结果播种它也许是个好主意,尽管从操作系统提供的RNG中播种它可能是一个更便携甚至更安全的选择(如果你不完全信任英特尔或美国)。

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

票数 11
EN

Stack Overflow用户

发布于 2015-10-12 20:54:35

英特尔的RDRAND有什么合法的用途吗?

是。

蒙特卡罗模拟为例。它不需要密码,所以不管它是否被美国国家安全局破坏了。

还是我们应该完全停止使用它?

我们不能回答。这是一个汇合用例、需求和个人偏好。

..。此外,我们至少有一个比RDRAND更快的软件CSPRNG,以及使用最广泛的最合适的PRNG.“

Mersenne在初始化后的时间内,由于从状态数组返回一个单词,所以在没有曲折的情况下,它的速度可能更快。但是我怀疑它的速度和RDRAND一样快,因为它是一条连续不断的河流。我知道RDRAND可以在连续流中实现基于总线宽度的理论极限。

根据英特尔的大卫约翰斯顿(谁设计的电路),这是类似于800+ MB/s。参见DJ在在常春藤桥上RDRAND指令的延迟和吞吐量是多少?的答案。

因此,我们有一种广泛的妄想,即RDRAND是用来将NSA后门嵌入到每个人的软件密码学中的。

偏执的人至少有两个选择。首先,他们可以放弃使用RDRAND和RDSEED。第二,它们可以使用RDRAND和RDSEED的输出为另一个生成器注入种子,然后使用第二个生成器的输出。我相信Linux内核采用了第二种方法。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26771329

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档