本文介绍了英特尔的 RDRAND 有任何合法用途吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Today I thought: well, even if there is great suspicion on RDRAND implementation of NIST SP 800-90A, it is still a hardware implementation of pseudo-random number generator (PRNG) that must be good enough for non-sensitive applications. So I thought of using it on my game instead of Mersenne Twister.

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

So, to see if there was any performance gain on using the instruction, I compared the time of the two following codes:

// test.cpp
#include <cstdio>

int main()
{
    unsigned int rnd = 0;
    for(int i = 0; i < 10000000; ++i) {
        __builtin_ia32_rdrand32_step(&rnd);
    }
    printf("%x
", 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
", rnd);
}

通过运行这两个我得到:

and by running the two I get:

$ 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,没有花哨的性能技巧),并编写了以下测试:

So, Mersenne Twister is much faster than RDRAND on my CPU. Well, I was disappointed, ruled out from my game. But RDRAND is a cryptographically secure PRNG (CSPRNG), so it does much behind the scenes... more fair would be compare it to other CSPRNG. So I took my Rabbit implementation (plain translation of the RFC to C, no fancy tricks for performance), and wrote the following test:

// 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
", buf[0]);
}

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

And for my surprise, generating twice as much pseudo-random data as the first two of them, I got a better time than RDRAND:

$ time ./test3
8ef9772277b70aba

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

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

All three were compiled with optimization enabled.

因此,我们普遍认为 RDRAND 被制造为将 NSA 后门嵌入到每个人的软件加密中.此外,我们至少有一个软件 CSPRNG 比 RDRAND 快,并且使用最广泛的体面 PRNG Mersenne Twister 比 RDRAND 快很多.最后,我们有开源的可审计软件熵池,比如 /dev/random/dev/urandom,它们没有隐藏在 AES 的双重加扰器层之后,比如 RDRAND.

So, we have a widespread paranoia that RDRAND was made to embed NSA backdoors into everybody's software cryptography. Also we have at least one software CSPRNG faster than RDRAND, and the most widely used decent PRNG, Mersenne Twister, is much faster than RDRAND. Finally, we have open-source auditable software entropy pools, like /dev/random and /dev/urandom, that are not hidden behind twofold scrambler layers of AES, like RDRAND.

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

So, the question: should people be using RDRAND? Is there any legitimate use for it? Or should we stop using it altogether?

推荐答案

正如指出的在另一个答案中,RDRAND播种了真正的随机性.特别是,它经常使用 128 位硬件生成的随机性为其内部 CSPRNG 重新播种,保证每 511 * 128 位至少重新播种一次.请参阅本文档的第 4.2.5 节:

As pointed out in the other answer, RDRAND is seeded with true randomness. In particular, it frequently reseeds its internal CSPRNG with 128 bits of hardware-generated randomness, guaranteeing a reseed at least once every 511 * 128 bits. See section 4.2.5 of this doc:

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 次.

So in your examples, you used a single 128-bit seed to generate 10 million random draws from rabbit_extract. In the RDRAND version, you had the equivalent of 2.5 million 128-bit draws, meaning that the CSPRING was reseeded at least 2,500,000/511 = 4,892 times.

因此,不是 128 位熵进入您的兔子示例,而是至少 4,892*128 = 626,176 位熵进入 RDRAND 示例.

So instead of 128 bits of entropy going into your rabbit example, there were at least 4,892*128 = 626,176 bits of entropy going into the RDRAND example.

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

That's much, much more entropy than you're going to get in 0.361 seconds without hardware support. That could matter if you're doing stuff where lots of real randomness is important. One example is Shamir secret sharing of large quantities of data -- not sure if there are others.

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

So in conclusion -- it's not for speed, it's for high security. The question of whether it's backdoored is troubling, of course, but you can always XOR it with other sources, and at the very least it's not hurting you.

这篇关于英特尔的 RDRAND 有任何合法用途吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-28 17:04