关于算法:真随机数发生器

关于算法:真随机数发生器

True random number generator

抱歉,这不是一个"真实"的问题,但是有一段时间我记得在这里看到过有关随机随机化随机数以生成真正的随机数而不仅仅是伪随机数的文章。 如果我搜索它,我看不到。

有人知道那篇文章吗?


我不得不不同意这个问题的很多答案。

可以在计算机上收集随机数据。 SSL,SSH和VPN不能保证安全。

软件随机数发生器的工作方式是存在一个从许多不同地方收集的随机数据池,例如时钟漂移,中断定时等。

这些方案的诀窍在于正确估计熵(随机性的时髦名称)。只要您正确估计熵,来源是否为偏差都无关紧要。

为了说明这一点,我在此注释中击中字母e的机会比z的机会高得多,因此,如果我将键中断用作熵的来源,则可能会产生偏差-但仍然存在一些随机性在该输入中。您无法准确预测本段中接下来的字母顺序。您可以从这种不确定性中提取熵,并将其用作随机字节的一部分。

像Yarrow这样的高质量真实随机数生成器内置了相当复杂的熵估计,并且只会发出与其可靠的"随机池"中所能说的一样多的字节。


我相信那是在thedailywtf.com-即。不是您想做的事。

无论调用多少次randomize(),都不可能从伪随机数中获得真正的随机数。

您可以从特殊硬件获得"真实"随机数。您还可以从鼠标移动和类似的东西收集熵。


真正随机数的算法不能存在,因为随机数的定义是:

Having unpredictable outcomes and, in
the ideal case, all outcomes equally
probable; resulting from such
selection; lacking statistical
correlation.

伪随机数生成器(PRNG)有好有坏,即完全可预测的数字序列,如果不知道称为种子的信息,就很难预测这些序列。

现在,很难推断出种子的PRNG在密码上是安全的。如果需要的话,您可能希望在Google中查找它们。

另一种方法(这是否是真正的随机性是一个哲学问题)是使用随机数据源。例如,不可预测的物理量,例如噪声或测量的放射性衰变。

这些仍会受到攻击,因为它们可以被独立地测量,有偏差等等。因此,这确实很棘手。这是通过定制硬件完成的,而定制硬件通常非常昂贵。我不知道/dev/random有多好,但是我敢打赌它对于密码学还不够好(大多数密码学程序都带有自己的RNG,Linux在启动时也要寻找硬件RNG)。


在文章的结尾,我将回答您的问题,为什么您可能要使用多个随机数生成器来"提高随机性"。

关于随机性的含义存在哲学争论。在这里,我的意思是"在所有方面都与所抽取的样本在均匀(0,1)iid分布上没有区别",我完全忽略了关于什么是随机数的哲学问题。

Knuth第2卷进行了分析,其中他尝试按照您的建议创建一个随机数生成器,然后分析其失败的原因以及真正的随机过程是什么。第2卷详细研究了RNG。

其他人则建议您使用随机物理过程来生成随机数。但是,正如我们在Espo / vt互动中看到的那样,这些过程可能具有微妙的周期性元素和其他非随机元素,部分原因是具有确定性行为的外部因素。通常,最好永远不要假设随机性,而要始终对其进行测试,并且如果知道这些伪影,通常可以对其进行校正。

可以创建确定性完全随机的"无限"比特流。不幸的是,这样的方法随着要求的位数增加而在内存中增长(它们必须这样做,以避免重复循环),因此它们的范围受到限制。

实际上,使用具有已知属性的伪随机数生成器几乎总是更好。要寻找的关键数字是相空间维数(大致均匀地分布在样本之间,您仍然可以指望它们之间的偏移量)和位宽(每个样本中的比特数相对于彼此是均匀随机的) ),循环大小(分布开始重复之前可以获取的样本数量)。

但是,由于来自给定生成器的随机数确定性地处于已知序列中,因此可能有人搜索生成器并找到对齐序列而暴露了您的过程。因此,如果您维护两个生成器,则有可能避免您的分布被立即识别为来自特定的随机数生成器。首先,对i进行采样,然后将其均匀地映射到一个到n,其中n最多是相位维。然后,在第二秒中对i采样,并返回第i个结果。在最坏的情况下,这会将循环大小减小为(原始循环大小/ n),但是对于该循环,仍将生成统一的随机数,并且这样做的方式使得在n中搜索比对指数。它还将减少独立相的长度。除非您了解缩短周期和独立相位长度对您的应用意味着什么,否则请不要使用此方法。


根据Wikipedia /dev/random,在类似Unix的操作系统中,是一个特殊的文件,充当真正的随机数生成器。

/ dev / random驱动程序从各种不确定性源中收集环境噪声,这些不确定性源包括但不限于操作系统环境中发生的键盘间定时和中断间定时。噪声数据被采样并与类似CRC的混合函数组合成一个不断更新的``熵池''。随机位串是通过对该池的内容进行MD5哈希获得的。单向哈希函数从池数据中提取出真正的随机位,并向对手隐藏池的状态。

/ dev / random例程维护池中真实随机性的估计,并在每次请求使用随机字符串时减小该估计。当估计值降为零时,例程将锁定并等待非确定性事件的发生以刷新池。

/ dev / random内核模块还提供了另一个接口/ dev / urandom,它不等待熵池重新加载并返回所需的字节数。结果,与/ dev / random相比,/ dev / urandom在生成时要快得多,后者仅在需要非常高质量的随机性时才使用。


约翰·冯·诺伊曼(John von Neumann)曾经说过一句话,"任何试图通过算法手段生成随机数的人当然都生活在犯罪之中"。

在数学家或物理学家的意义上,甚至/ dev / random都不是随机的。甚至放射性同位素衰减测量也不是随机的。 (衰减率是。测量结果不是。在每个检测到的事件之后,Geiger计数器的复位时间都很短,在此期间它们无法检测到新事件。这会导致细微的偏差。有很多方法可以缓解这种情况,但是不能完全消除它。)

停止寻找真正的随机性。一个好的伪随机数生成器确实是您想要的。


计算机通常具有许多随时可用的随机噪声物理源:

  • 麦克风(希望在嘈杂的地方)
  • 来自网络摄像头的压缩视频(指向可变的东西,例如熔岩灯或街道)
  • 键盘和鼠标计时
  • 网络数据包的内容和时间(全世界做出的贡献)

有时

  • 基于时钟漂移的硬件
  • 盖革计数器和其他罕见事件检测器
  • 各种传感器连接到A / D转换器

困难的是估算这些源的熵,尽管数据速率高且变化很大,但在大多数情况下仍很低。 但是可以通过保守的假设(或至少不会浪费掉)来估计熵,以供养Yarrow或Fortuna之类的系统。


总而言之,我们对什么是安全的随机性源的工作定义类似于我们对密码安全的定义:如果精明的人已经看过并且无法证明它是随机的,则它看起来是随机的。 t完全不可预测。

就像没有加密密码无法破解一样,没有一种系统可以生成无法想象的随机数。用于重要工作的可信赖解决方案仅是迄今为止证明难以克服的解决方案。如果有人告诉你否则,他们就是在卖给你东西。

密码学很少会奖励聪明。尝试可靠的解决方案。


如果您相信确定性的宇宙,那么就不存在真正的随机性。 :-)例如,有人建议放射性衰变确实是随机的,但是恕我直言,仅仅因为科学家尚未弄清楚这种模式,并不意味着就没有一个模式可以解决。通常,当您需要"随机"数字时,您需要的是没有其他人能够猜到的加密数字。

您可以随机获得的最接近的结果是,自然地测量出任何敌人也无法测量的东西。通常,您会丢弃测量中的最高有效位,而留下的数字更有可能被平均分配。硬核随机数用户会获得用于测量放射性事件的特殊硬件,但是您可以从使用计算机的人身上获得一些随机性,例如按键间隔和鼠标移动;如果计算机没有直接用户,则可以从CPU温度传感器获得一些随机性,和网络流量。您还可以使用网络摄像头和连接到声卡的麦克风之类的东西,但我不知道是否有人这样做。


无法获得"真实"随机数,计算机是一种逻辑构造,它不可能创建"真正"随机的任何东西,只能创建伪随机数。但是,有更好和更坏的伪随机算法。

为了获得"真实的"随机数,您需要一个物理随机源,有些赌博机实际上内置了这些源-通常是一个放射源,放射衰变(据我所知是真正的随机性)用于生成号码。


生成随机数的最佳方法之一是通过Clock Drift。这主要用于两个振荡器。

比方说这是如何工作的,想象一辆赛车在一个简单的椭圆形赛道上,在大圈开始时有一条line线,在一条轮胎上还有一条while线。汽车完成一圈后,将根据道路和轮胎上白线的位置之差生成一个数字。

非常容易生成,无法预测。


推荐阅读