std::random_device是否真的随机?有没有一种方法可以进行检查?

8
引用自cppreference
std::random_device是一种不确定性随机数生成器,尽管实现允许使用伪随机数生成器来实现std::random_device,如果没有支持不确定性随机数生成器的话。
是否有一种方法可以检查当前实现是否使用PRNG而不是RNG(然后退出并显示错误),如果不能,为什么?
需要注意的是,少量的谷歌搜索显示至少MinGW以这种方式实现了std::random_device,因此如果要使用std::random_device,则存在真正的危险。
---编辑--- 此外,如果答案是否定的,有人能够给出为什么没有这样的函数/特性/某些东西的见解,我会非常感兴趣。

9
真正的危险?你不应该在加密应用中使用 <random> 库,如果存在真正的危险,应该使用专用且可审计的解决方案。 - Kerrek SB
6
std::random_device 是一个非确定性的随机数生成器,除非它不是。 - Brett Hale
请查看“Dieharder”随机数测试套件 http://www.phy.duke.edu/~rgb/General/dieharder.php 注意:需要超过2GB的随机数据来执行其测试。 - Richard Critten
3个回答

10
有一种方法:使用std::random_device::entropy可以检查当前实现是否使用PRNG而非RNG(如果不是,会输出错误信息),并且如果它是基于随机数生成器(即具有确定性)实现的,将返回0.0

根据标准:

double entropy() const noexcept;

返回值:若实现采用随机数引擎,则返回0.0。否则,返回operator()生成的随机数的熵估计值,范围为min()log_2(max() + 1)


5
根据标准,您是完全正确的。然而,我在 cppreferece.com 上读到过这样的话:“一些标准库并没有完全实现此函数。例如,尽管设备是非确定性的,但 gcc 和 clang 总是返回零。与之相比,Visual C++ 总是返回32,而 boost.random 则返回10。” - Christophe
1
@Christophe 我认为从技术上讲,GCC和clang这样做并没有错。唯一的要求是PRNG将返回0,但RNG可能仅因为标准仅在脚注中定义了“熵估计”而返回0。至少它们只是悲观的。然而,VC++和boost.random过于乐观有点令人担忧。 - Joseph Mansfield
然而,这种悲观主义也使得该方法无法区分基于RNG和PRNG的实现,因此并不十分有用。此外,VC++可能是现实的选择,但要检查它可能需要对Windows有很多内部知识。 - Xarn
@Xarn 是的,这意味着你应该对整个库持悲观态度,这可能是正确的。 - Joseph Mansfield
@JosephMansfield 是的,这些库正在使用谨慎原则。因此,您必须假设最坏的情况。但是我有印象OP想要一种客观的方法来找出它是PRNG还是真正的RNG。 - Christophe
即使假设估计是相当准确的,函数被正确实现了,也无法区分永久为零的熵(即PRNG)和当前为零的熵(即恰好用尽所有熵的RNG)。 - n. m.

0

没有一种100%安全的方法可以确定真正的随机性。通过黑盒方法,你能做到最好的事情就是在它不完全是随机的情况下展示证据:

首先,您可以通过生成大量随机数字并统计它们的分布(例如,在0和1000之间生成100万个随机数字),验证分布是否看起来是随机的。如果某些数字出现比其他数字更频繁,则显然不是真正的随机数。
接下来,您可以运行几次生成随机数的程序,使用相同的初始种子。如果获得相同的随机数序列,则它肯定是PRNG而不是真正的随机性。但是,如果您没有获得相同的序列,它并不能证明任何事情:库可能使用某种自动种子(使用时钟滴答或其他内容)来隐藏/改善伪随机性。
如果您的应用程序高度依赖于随机性质量(例如,加密质量),则应考虑一些更多的测试,例如NIST SP 800-22建议的测试。

0

Xarn如上所述:

但是,这种悲观主义也排除了该方法区分基于RNG和PRNG的实现,使其变得相当无用。而VC++可能是现实的,但要检查这一点可能需要大量关于Windows的内部知识。

如果您调试Windows实现,那么您会发现最终进入RtlGenRandom,这是更好的加密随机字节源之一。如果您调试Linux实现,则应该从dev/urandom读取,这也可以。他们没有告诉我们我们不使用像rand这样可怕的东西,这一事实很烦人。

PS-您不必具有内部Windows知识,只需要将符号附加到调试器即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接