使用C++11和RDRAND的真随机数

True random numbers with C++11 and RDRAND

本文关键字:随机数 RDRAND C++11 使用      更新时间:2023-10-16

我看到英特尔似乎包含了一个新的汇编函数,可以从硬件中获得真实的随机数。该指令的名称为RdRand,但在互联网上似乎只能访问其中的少量详细信息:http://en.wikipedia.org/wiki/RdRand

关于这个新指令及其在C++11中的使用,我的问题如下:

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

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

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

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

我设计了随机数生成器,将随机数提供给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是标准英特尔指令集的一部分。它将在未来的所有CPU产品中得到支持。

3) 您需要使用内联程序集或使用RdRand的库(如openssl)。如果您使用一个库,则该库正在实现您可以直接实现的内联汇编程序。英特尔在其网站上给出了代码示例。

还有人提到了剧本。a.是我写的。这很简单。

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

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

由于PRISM和Snowden的爆料,我会非常小心地在有安全问题的应用程序中使用硬件随机生成器,或依赖于一个库。我更喜欢使用独立的开源密码随机生成器的组合。例如,我所说的组合是指:假设rarbrc是三个独立的密码随机生成器,r是返回给应用程序的随机值。让sasbsc是它们的种子,tatbtc,重新种子化的周期,即例如,每次tb抽取都重新种子化rb。通过独立:尽可能地属于独立库,并依赖于不同的密码或算法。

伪代码:

// 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。

1)不,RdRand中的数字不是真正随机的,因为它们来自加密安全的伪随机数生成器。然而,RdRand、RdSeed和Intel Secure Key技术可能是最接近真正随机的。

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节)。必须在课堂上阅读。

  1. 我认为它们"据说是"随机的。。。因为它是用于加密的。我不会太担心随机数的质量
  2. 我认为英特尔会继续这样做,因为他们总是认为向后兼容性很重要,即使这条指令在未来可能毫无用处
  3. 很抱歉我不能回答这个问题,因为我不使用C++11
  4. 如果你不想深入研究汇编代码,你可以试试librdrand.a。英特尔在其网站上提供了免费下载的库。我已经测试过了,它非常方便,并且有错误报告机制(因为随机数生成器生成随机数的概率很小)。因此,如果使用这个库,只需要检查函数在librdrand中的返回值

如果我的答复有什么问题,请告诉我。感谢

祝好运

香皮赛MM