16

我已经看到英特尔似乎包含了一个新的汇编函数来获取从硬件获得的真实随机数。该指令的名称是RdRand,但在 Internet 上似乎只有少量细节可以访问:http ://en.wikipedia.org/wiki/RdRand

我对这条新指令及其在 C++11 中的使用的问题如下:

  1. 生成的随机数RdRand真的是随机的吗?(由不相关的白噪声或量子过程产生的每一位?)

  2. 它是 Ivy Bridge 处理器的一个特殊功能吗?英特尔会在下一代 cpu 中继续实现这个功能吗?

  3. 如何通过 C++11 使用它?也许有,std::random_deviceRdRand如果指令可用,编译器是否已经调用?

  4. 编译程序时如何检查是否RdRand真的被调用?

4

5 回答 5

53

我设计了随机数生成器,为 RdRand 指令提供随机数。所以换一个,我真的知道答案。

1) 随机数由符合 SP800-90 AES-CTR DRBG 的 PRNG 生成。AES 使用 128 位密钥,因此这些数字具有高达 128 位的乘法预测阻力和超过 128 位的加法预测阻力。

然而,PRNG 经常从全熵源重新播种。对于孤立的 RdRand 指令,它将重新播种。对于 4 个内核上的 8 个线程尽可能快地拉动,它的重新播种总是比每 14 个 RdRands 一次更频繁。

种子来自真正的随机数生成器。这涉及使用 AES-CBC-MAC 将 2.5Gbps 熵源输入到 3:1 压缩比熵提取器中。

因此,它实际上是一个 TRNG,但它在重负载时会回退到用于短序列的加密安全 PRNG 的属性。

这正是 Linux 上 /dev/random 和 /dev/urandom 之间的语义差异,只是快了很多。

熵最终是从一个量子过程中收集的,因为这是我们在自然界中所知道的唯一基本随机过程。在 DRNG 中,特别是 4 个晶体管栅极中的热噪声驱动亚稳态锁存器的分辨率状态,每秒 25 亿次。

熵源和调节器旨在符合 SP800-90B 和 SP800-90C,但这些规范仍处于草案形式。

2) RdRand 是标准 intel 指令集的一部分。未来所有CPU产品都会支持。

3)您要么需要使用内联汇编,要么需要使用 RdRand 的库(如 openssl)。如果您使用库,则该库正在实现您可以直接实现的内联汇编器。英特尔在其网站上提供了代码示例。

其他人提到了 librdrand.a。我是这么写的。这很简单。

4) 只需在二进制文件中查找 RdRand 操作码。

于 2013-08-01T21:30:03.083 回答
5
  1. 这当然取决于你对宇宙决定论的看法,所以这更像是一个哲学问题,但许多人认为它是随机的。
  2. 只有英特尔会知道,但由于有添加它的需求,它可能会有保留它的需求
  3. std::random_device不需要硬件驱动,即使是,也不需要使用rdrand. 你可以询问它的double entropy() const noexcept成员函数是否是硬件驱动的。使用rdrand它是一个 QoI 问题,但我希望每个理智的实现都可以这样做(我已经看到例如 gcc 这样做)。如果不确定,您可以随时检查组装,但硬件随机性的其他方法也应该足够好(还有其他可用的专用硬件)。
  4. 见上文,如果您对它是否只有硬件感兴趣,请使用entropy,如果对 rdrand 感兴趣,请扫描生成的机器码。
于 2013-07-12T14:22:22.470 回答
3

自从 PRISM 和斯诺登披露以来,我会非常小心地使用硬件随机生成器,或者在有安全问题的应用程序中依赖一个单一的库。我更喜欢使用独立的开源密码随机生成器的组合。通过组合,我的意思是例如:让我们成为三个独立的密码随机生成器,ra成为返回给应用程序的随机值。让我们, ,成为他们的种子,, , , 重新播种期,即每次抽奖重新播种。By independant:尽可能属于独立的库,依赖不同的密码或算法。rbrcrsasbsctatbtcrbtb

伪代码:

// init
seed std rand with time (at least millisec, preferably microsec)
sa = std rand xor time // of course, not the same time evaluation
// loop
sb = ra every tb
sc = rb every tc
r = rb xor rc
sa = rc every ta

当然,每次抽奖只能使用一次。

可能有两个来源就足够了:

// init
seed std rand with time (at least millisec, preferably microsec)
sa = std rand xor time // of course, not the same time evaluation
// loop
sb = ra every tb
sa = rb every ta
r = rb xor ra

为 ta、tb、tc 选择不同的值。它们的范围取决于您使用的随机源的强度。

编辑:我为此目的启动了新库ABaDooRand 。

于 2014-03-26T11:52:50.773 回答
1

1) 不,来自 RdRand 的数字并不是真正随机的,因为它们来自加密安全的伪随机数生成器。但是,RdRand、RdSeed 和英特尔安全密钥技术可能是您能找到的最接近真正随机的技术。

2) 是的,从您提到的 Ivy Bridge 处理器开始,所有出现在笔记本电脑、台式机和服务器中的英特尔处理器都提供该功能。如今,这些功能也在 AMD 芯片中实现。

3 和 4) 英特尔软件开发指南是寻找这些答案的地方。这里有一个关于英特尔安全密钥如何应用于天体物理问题的有趣讨论(http://iopscience.iop.org/article/10.3847/1538-4357/aa7ede/meta;jsessionid=A9DA9DDB925E6522D058F3CEEC7D0B21.ip-10-40- 2-120)和非付费版本(https://arxiv.org/abs/1707.02212)。本文描述了该技术的工作原理、实现方式以及性能(第 2.2.1 节和第 5 节)。不得不读一堂课。

于 2017-11-13T22:10:02.990 回答
-2
  1. 我认为它们“据说是”随机的......因为它是用于加密的。我不会太担心随机数的质量。
  2. 我认为英特尔会继续这样做,因为他们始终认为向后兼容性很重要,即使这条指令将来可能无用。
  3. 很抱歉我无法回答这个问题,因为我不使用 C++11。
  4. 如果您不想深入研究汇编代码,可以尝试 librdrand.a。英特尔在其网站上提供了免费下载的库。我测试过,挺方便的,有报错机制(因为随机数生成器生成随机数失败的概率很小)。所以如果你使用这个库,你只需要检查librdrand中函数的返回值

如果我的回复有任何问题,请告诉我。谢谢

祝你好运

相皮赛MM

于 2013-07-12T15:45:34.753 回答