使用C++11和RDRAND的真随机数
True random numbers with C++11 and RDRAND
我看到英特尔似乎包含了一个新的汇编函数,可以从硬件中获得真实的随机数。该指令的名称为RdRand
,但在互联网上似乎只能访问其中的少量详细信息:http://en.wikipedia.org/wiki/RdRand
关于这个新指令及其在C++11中的使用,我的问题如下:
-
用
RdRand
生成的随机数真的是随机的吗?(由不相关的白噪声或量子过程产生的每个比特?) -
这是常春藤桥处理器的一个特殊功能吗?英特尔会在下一代cpu中继续实现这一功能吗?
-
如何通过C++11使用它?也许使用
std::random_device
,但如果指令可用,编译器是否已经调用了RdRand
? -
当我编译程序时,如何检查
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操作码即可。
- 这当然取决于你对宇宙决定论的看法,这更像是一个哲学问题,但许多人认为这是随机的
- 只有英特尔知道,但由于有人要求增加它,很可能会有人要求保留它
std::random_device
不需要硬件驱动,即使是硬件驱动,也不需要使用rdrand
。您可以询问其double entropy() const noexcept
成员函数是否为硬件驱动。使用rdrand
是一个QoI问题,但我希望每一个正常的实现都能做到这一点(我看到过例如gcc这样做)。如果不确定,您可以随时检查组装,但其他方式的硬件随机性应该足够好(还有其他专用硬件可用)- 参见上文,如果您对其是否仅硬件感兴趣,请使用
entropy
,如果对rdrand感兴趣,则扫描生成的机器代码
由于PRISM和Snowden的爆料,我会非常小心地在有安全问题的应用程序中使用硬件随机生成器,或依赖于一个库。我更喜欢使用独立的开源密码随机生成器的组合。例如,我所说的组合是指:假设ra
、rb
、rc
是三个独立的密码随机生成器,r
是返回给应用程序的随机值。让sa
、sb
、sc
是它们的种子,ta
、tb
、tc
,重新种子化的周期,即例如,每次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节)。必须在课堂上阅读。
- 我认为它们"据说是"随机的。。。因为它是用于加密的。我不会太担心随机数的质量
- 我认为英特尔会继续这样做,因为他们总是认为向后兼容性很重要,即使这条指令在未来可能毫无用处
- 很抱歉我不能回答这个问题,因为我不使用C++11
- 如果你不想深入研究汇编代码,你可以试试librdrand.a。英特尔在其网站上提供了免费下载的库。我已经测试过了,它非常方便,并且有错误报告机制(因为随机数生成器生成随机数的概率很小)。因此,如果使用这个库,只需要检查函数在librdrand中的返回值
如果我的答复有什么问题,请告诉我。感谢
祝好运
香皮赛MM
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 整数不会重复超过随机数
- if数组上的随机数
- 在将数字随机生成为数组期间从内存输出随机数的数组
- 半随机数生成C++
- 程序在尝试猜测它选择的随机数时进入无限循环?
- 有没有办法在 c++ 中同时生成随机数?如果没有,是否有解决方法?
- 具有随机数的二维数组不会更改
- 随机数未达到限制
- 我想生成许多矩阵并用随机数填充它
- <random>在实践中应该实际使用哪个随机数引擎? std::mt19937?
- 制作具有平均值的随机数生成器
- 为什么 rand 不在我的代码中生成随机数?
- C++ 随机数生成器:尝试将结果作为向量获取,但通过制作 void 函数来执行此操作而出现错误
- 从给定种子生成相同的随机数序列C++
- 随机数生成函数说明
- C++ 尝试生成随机数时弹出警告帮助?
- 尝试在 c++ 中创建随机数生成器并收到错误
- 从给定的随机数组值生成随机数 Arduino程序C++
- 使用C++11和RDRAND的真随机数