Random 英特尔'有任何合法用途吗;斯德兰?

Random 英特尔'有任何合法用途吗;斯德兰?,random,cryptography,stream-cipher,rdrand,Random,Cryptography,Stream Cipher,Rdrand,今天我想:好吧,即使对的RDRAND实现有很大的怀疑,它仍然是一个伪随机数生成器(PRNG)的硬件实现,对于非敏感应用来说必须足够好。所以我想在我的游戏中使用它而不是Mersenne Twister 因此,为了查看使用该指令是否有任何性能提升,我比较了以下两个代码的时间: // test.cpp #include <cstdio> int main() { unsigned int rnd = 0; for(int i = 0; i < 10000000; +

今天我想:好吧,即使对的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);
}
所以,在我的CPU上,Mersenne Twister比RDRAND快得多。我很失望,被排除在比赛之外。但是RDRAND是一个加密安全的PRNG(CSPRNG),所以它在幕后做了很多事情。。。与其他CSPRNG相比更公平。因此,我采用了我的实现(将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是为了将NSA后门嵌入每个人的软件加密中。此外,我们至少有一个软件CSPRNG比RDRAND快,而使用最广泛的正派PRNG,Mersenne Twister,比RDRAND快得多。最后,我们有开源的可审计软件熵池,比如
/dev/random
/dev/uradom
,它们不会隐藏在AES的两层扰码器层后面,比如RDRAND


所以,问题是:人们应该使用RDRAND吗?它有合法的用途吗?或者我们应该完全停止使用它吗?

RDRAND
不仅仅是一个PRNG。这是一个符合FIPS的白色TRNG。不同之处在于,您可以依靠
RDRAND
来包含大量直接从CPU检索的实际熵。因此,
RDRAND
的主要用途是为操作系统/库/应用程序提供熵

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

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


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

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

因此,在您的示例中,您使用单个128位种子从rabbit_extract生成1000万个随机抽取。在RDRAND版本中,您有250万个128位的抽取,这意味着CSPRING至少被重新设定了2500000/511=4892次

因此,与兔子示例中的128位熵不同,RDRAND示例中至少有4892*128=626176位熵

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

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

英特尔的RDRAND有合法用途吗

考虑一个例子。它没有加密的需要,所以它的后门是否被美国国家安全局屏蔽并不重要



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

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


。。。此外,我们至少有一款软件CSPRNG比RDRAND快,而且是使用最广泛的体面PRNG……”

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

根据设计电路的英特尔公司的大卫·约翰斯顿(David Johnston)的说法,这大约是800+MB/s


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


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

这里有一篇天体物理学研究论文(),(非付费)此处的版本()提供了RdRand的合法使用

正如前一篇文章所建议的那样,它检查了RdRand对蒙特卡罗模拟器的影响。
$ time ./test
d230449a

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

$ time ./test2 
bfc4e472

real    0m0.051s
user    0m0.050s
sys     0m0.002s
// 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]);
}
$ time ./test3 
8ef9772277b70aba

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