【问题标题】:how to find the "true" entropy of std::random_device?如何找到 std::random_device 的“真实”熵?
【发布时间】:2015-04-08 01:48:27
【问题描述】:

我想检查我是否执行了std::random_device 具有非零熵(即不确定),使用std::random_device::entropy() 函数。然而,根据 给cppreference.com

"这个功能在一些标准库中没有完全实现。 例如,gcc 和 clang 总是返回零,即使设备 是非确定性的。相比之下,Visual C++ 总是返回 32, boost.random 返回 10。”

有没有办法找到真正的熵?特别是做现代 计算机(MacBook Pro/iMac 等)具有不确定的来源或随机性,例如使用散热监视器?

【问题讨论】:

  • en.wikipedia.org/wiki/RdRand - Ivy Bridge x86 处理器提供了一个随机数,至少可以保存用于加密目的。
  • 有一个很好的老技巧,即生成大量随机数,将它们写入文件并使用 gzip 或类似方法对其进行压缩。然后将压缩比与从已知高熵源(如/dev/random)和已知低熵源(如1、2、3,...)获得的样本的压缩率进行比较。
  • 我只是这样做了,发现std::random_device/dev/urandom 之间没有区别(这并不奇怪,因为 GCC 的 libstdc++ 在后者方面实现了前者)。 但是,我认为未播种的std::rand()(来自cstdlib)没有区别,这表明基准测试不够严格。
  • @5gon12eder 感谢您的想法和尝试。是的,这并不奇怪,因为区分好的 PRNG 和 RNG 是一件相当棘手的事情。如果 zip 算法达到压缩限制(即源的香农熵),它可能很有用,但实际上并非如此。
  • 您是否考虑过尝试诸如TestU01diehard 之类的随机基准?

标签: c++ c++11 random


【解决方案1】:

所有标准给你的都是你已经看到的。您需要了解给定标准库如何实现random_device 才能回答这个问题。例如,在 Visual Studio 2013 Update 4 中,random_device 转发到 rand_s,后者转发到 RtlGenRandom,这实际上可能(总是?)一个加密安全的伪随机数生成器,具体取决于您的 Windows 版本和可用的硬件。

如果您不相信该平台能够提供良好的熵源,那么您应该使用自己的加密安全 PRNG,例如基于 AES 的 PRNG。也就是说,平台供应商强烈鼓励他们的随机数实际上是随机的,并且将 PRNG 嵌入到您的应用程序中意味着如果发现 PRNG 不安全,则无法轻松更新它。只有您可以自己决定权衡:)

【讨论】:

  • 但是您再次看到我对 Microsoft 如何实现一些生成随机性的内部函数的信任度为 0%,因为这是密钥交换协议中最重要的部分之一。然而,标准 C++ 似乎确实没有提供/强制执行标准方式。
  • @vsoftco:那么random_device,它被指定为实现定义的随机源,不适合你:)
  • 是的,这正是次要问题,我可以“信任”多少random_device。我对它进行了测试,确实“似乎”是随机的,但我不会把我的生命押在严肃的加密应用程序上。
  • @vsoftco:是的,如果你不信任这个平台,你就不能依赖它。由实施者提供随机源。即使是像rdrand 这样的硬件答案也会让您相信硬件实际上是随机的。
  • @vsoftco Steven T. Lavavej(微软 C++ 标准库实现的维护者)说,他们在他的演讲 rand() Considered Harmful(18 分钟标记)中保证它是加密安全的,所以“总是?”在答案中可能可以删除。至于其他实现,请查看文档。而且,如果您不信任实施者,则只能自己实施……即使标准规定了一种正确的区分方式,您仍然必须信任他们才能正确实施。
【解决方案2】:

我向你推荐这篇文章的讲座。

Myths about /dev/urandom

§ 26.5.6

random_device 统一随机数生成器生成非确定性随机数。

如果实施限制阻止生成不确定的随机数,则实施可能会使用随机数引擎。

所以基本上它会尝试使用内部系统“真”随机数生成器,在 linux /dev/{u}random o windows RltGenRandom。

不同的一点是您不信任这些随机性来源,因为它们依赖于内部噪声或者是紧密的实现。

此外,您如何测量熵的质量,正如您所知,这是试图找到好的 rng 生成器的最大问题之一。

一种估计可能非常好,而另一种估计可能报告的熵不太好。

Entropy Estimation

在各种科学/工程应用中,例如独立 成分分析、图像分析、遗传分析、语音 识别、流形学习和时间延迟估计 估计系统或过程的微分熵,给定 一些观察。

正如它所说,你必须依赖最终的观察,而这些可能是错误的。

我你觉得内部rng不够好,你可以随时尝试为此购买硬件设备。这个list on wikipedia 有一个供应商列表,您可以查看有关他们的互联网评论。

性能

您必须考虑的一点是使用实随机数生成器在应用程序中的性能。一种常见的技术是在 mersenne twister 中使用通过 /dev/random 获得的数字作为种子。

如果用户无法物理访问您的系统,您将需要平衡可靠性和可用性,一个有安全漏洞的系统就像一个不工作一样糟糕,最后您必须加密您的重要数据。

编辑 1:作为建议,我已将文章移至评论顶部,是一本不错的读物。感谢您的提示:-)。

【讨论】:

    【解决方案3】:

    熵作为一个科学术语在描述随机数时被误用。复杂性可能是一个更好的术语。物理学中的熵被定义为可用量子态数量的对数(在 RNG 中没有用),信息论中的熵由香农熵定义,但这面向另一个极端——如何将尽可能多的信息放入一个嘈杂的比特流,而不是如何最小化信息。

    例如,Pi 的数字看起来是随机的,但一旦您知道这些数字源自 Pi,它们的实际熵就为零。在 RNG 中增加“熵”基本上是一个使数字来源尽可能模糊的问题。

    【讨论】:

    • 谢谢,不过我很清楚熵的含义 :) 我在这里真正的意思是源的香农熵。
    【解决方案4】:

    熵只是衡量 RNG 质量的一种方式(确实,无法测量精确的熵)。要对您的std::random_device 的随机数质量进行实用且合理准确的测量,请考虑使用标准随机性测试套件,例如TestU01diehard 或其继任者dieharder。它们会运行一系列统计测试,旨在对您的 RNG 施加压力,确保它产生统计上的随机数据。

    请注意,统计随机性本身并不能证明 RNG 适用于加密应用。


    许多现代计算机都有易于访问的硬件随机性来源,即音频输入、摄像头和各种传感器中的模数转换器。这些表现出低水平的热或电噪声,可用于产生高质量的随机数据。但是,据我所知,没有操作系统真正使用这些传感器来提供其系统随机数源(例如/dev/[u]random),因为此类物理随机数源的比特率往往非常低。

    相反,操作系统提供的随机数源往往由硬件计数器和事件播种,例如页面错误、设备驱动程序事件和其他不可预测的源。理论上,考虑到精确的硬件状态,这些事件可能是完全可预测的(因为它们不是基于例如量子或热噪声),但实际上它们具有足够的不可预测性,可以产生良好的随机数据。

    【讨论】:

    • 这就是我要求熵的原因。熵本身是加密应用程序中经过认证的随机性度量,因为您可以从非零熵源中提取真正的随机性。无论如何,感谢您的链接,将看看。 PS:我感觉/dev/random在类UNIX系统中使用热噪声(即使比特率很低)
    • @vsoftco:问题在于测量“真实”熵基本上是不可能的(它需要了解 RNG 源的完整物理过程)。相反,统计测试可以作为一种有用的替代品。
    • 似乎是合理的,现在如果我想多一点,C++ 标准不可能保证真正的随机性,因为它的模型基于一些抽象的确定性图灵机类设备。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    • 2016-08-30
    • 1970-01-01
    • 2017-12-05
    • 1970-01-01
    相关资源
    最近更新 更多