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

时间:2013-07-12 14:12:25

标签: c++ assembly c++11 random rdrand

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

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

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

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

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

  4. 如何在编译程序时检查是否真正调用RdRand

5 个答案:

答案 0 :(得分:46)

我设计了随机数发生器,为RdRand指令提供随机数。所以对于改变,我真的知道答案。

1)随机数是从符合SP800-90 AES-CTR DRBG的PRNG生成的。 AES使用128位密钥,因此数字具有高达128位的乘法预测电阻和128以上的附加值。

然而,PRNG经常从完整的熵源中重新接种。对于隔离的RdRand指令,它将被重新接种。对于4个核心上的8个线程尽可能快地拉动,它将比每14个RdRands更频繁地重新接种。

种子来自真正的随机数发生器。这涉及一个2.5Gbps的熵源,使用AES-CBC-MAC输入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操作码。

答案 1 :(得分:5)

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

答案 2 :(得分:3)

由于PRISM和Snowden的启示,我会非常小心地在有安全问题的应用程序中使用硬件随机生成器或依赖单个库。我更喜欢使用独立的开源加密随机生成器的组合。通过组合,我的意思是例如: 我们rarbrc是三个独立的加密随机生成器,r是返回给应用程序的随机值。 让sasbsc成为他们的种子,tatbtc,重新设定期间,例如每rb次抽奖重新tb次。 通过独立:尽可能属于独立的库,并依赖于不同的密码或算法。

的伪代码:

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

答案 3 :(得分: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节)。不得不为一堂课阅读。

答案 4 :(得分:-2)

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

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

    祝你好运

    xiangpisaiMM