关于理论:替代熵源

Alternative Entropy Sources

好吧,我猜这完全是主观的,什么都不是,但我在考虑随机数生成器的熵源。大多数发电机都是按当前时间播种的,对吗?嗯,我很好奇还有什么其他的来源可以用来生成完全有效的随机(松散定义)数字。

使用多个数据源(比如时间+当前的HDD寻道时间[我们在这里简直太不可思议了])会不会一起创建一个比单个数据源"更随机"的数字?源数量的逻辑限制是什么?多少钱真的足够?时间的选择仅仅是因为它方便吗?

对不起,如果这类事情是不允许的,但我对消息来源背后的理论很好奇。


维基百科关于硬件随机数生成器的文章列出了一些使用物理属性的随机数的有趣来源。

我的最爱:

  • 一种由连接在个人计算机上的盖革计数器检测到的核衰变辐射源。
  • 光子穿过半透明的镜子。检测互斥事件(反射-传输),并分别与"0"或"1"位值关联。
  • 电阻产生的热噪声,被放大以提供随机电压源。
  • 雪崩二极管产生的雪崩噪声。(这有多酷?)
  • 大气噪声,由连接到PC的无线电接收器检测到

维基百科文章的"问题"部分还描述了许多这些源/传感器的脆弱性。当传感器老化/退化时,几乎总是产生逐渐减少的随机数。这些物理源应经常通过统计测试进行检查,这些测试可以分析生成的数据,确保仪器不会无声地损坏。


SGI曾经使用不同"地球相位"的熔岩灯照片作为熵源,最终演化成一个开源的随机数发生器,称为lavarnd。


我使用random.org,它们提供来自大气噪声的免费随机数据,我使用这些数据定期重新播种Mersene Twister RNG。它几乎是随机的,没有硬件依赖性。


不要担心随机数生成器的"好"种子。序列的统计属性不依赖于生成器的种子设定方式。不过,还有其他事情。担心。参见随机数生成中的陷阱。

对于硬件随机数发生器,必须对这些物理源进行测量,测量过程存在系统误差。您可能会发现"伪"随机数比"实数"随机数质量更高。


现代的RNG都是根据附近种子中的相关性进行检查的,并且在播种后运行几百次迭代。所以,不幸的是,无聊但真实的答案是,这其实并不重要。

一般来说,使用随机物理过程必须检查它们是否符合均匀分布,否则会造成减损。

在我看来,最好使用一个理解得很好的伪随机数生成器。


Linux内核使用设备中断时间(鼠标、键盘、硬盘)来生成熵。维基百科上有篇关于熵的好文章。


一些TPM(可信平台模块)"芯片"具有硬件RNG。不幸的是,我的戴尔笔记本电脑中的(Broadcom)TPM缺少这一功能,但今天销售的许多计算机都附带了一个硬件RNG,它使用真正不可预测的量子力学过程。英特尔已经实现了热噪声种类。

此外,不要单独使用当前时间为加密目的或任何不可预测性很重要的应用程序种子RNG。将一些低阶位与其他几个源结合使用可能是可以的。

类似的问题可能对你有用。


几年前我发现了热点——这些数字是由放射性衰变产生的,实际上是随机数字。

每天可以下载多少个数字是有限制的,但把这些数字当作RNG真正随机的种子总是让我很开心的。


我使用了一个加密程序,它使用用户的鼠标移动来生成随机数。唯一的问题是程序必须暂停并要求用户随机移动鼠标几秒钟才能正常工作,这可能并不总是可行的。


抱歉,我讨论迟到了(现在3.5岁是什么意思?)但我对prn的产生和熵的其他来源重新产生了兴趣。Linux内核开发人员RustyRussell最近在他的博客上讨论了熵的其他来源(除了/dev/urandom)。

但是,我并不是对他的选择印象深刻;一个NIC的MAC地址永远不会改变(尽管它是所有其他地址中唯一的),并且PID似乎太小了,可能是一个样本大小。

我曾经尝试过一个Mersenne Twister(在我的Linux机器上),它的种子是以下算法。如果有人愿意和感兴趣,我会征求任何意见/反馈:

  • 创建一个64位+256位*下面的/proc文件数的数组缓冲区。
  • 将时间戳计数器(TSC)值放在此缓冲区的前64位中。
  • 对于以下每个/proc文件,计算sha256和:

    • 埃多克斯1〔3〕
    • 江户十一〔四〕号
    • 埃多克斯1〔5〕
    • 埃多克斯1〔6〕
    • 江户十一〔七〕号
    • 埃多克斯1〔8〕

      将每个256位散列值放入(1)中创建的数组的自己区域中。

  • 创建整个缓冲区的sha256哈希。注意:我可以(也可能应该)使用完全独立于sha函数的另一个哈希函数-这种技术被认为是对弱哈希函数的"保护"。
  • 现在我有256位希望随机(足够)熵数据种子我的梅森缠绕。我使用上面的代码填充mt数组的开头(624个32位整数),然后用mt作者的代码初始化该数组的其余部分。另外,我可以使用不同的哈希函数(例如sha384、sha512),但我需要不同大小的数组缓冲区(显然)。

    最初的Mersenne Twister代码需要一个32位的种子,但我觉得这远远不够。运行"仅仅"2^32-1不同的MTS来破解密码,在当今这个时代并不超出实际可行的范围。

    我很想看看任何人对此的反馈。批评是不受欢迎的。我会为我使用上述/proc文件辩护,因为它们不断变化(尤其是/proc/self/*文件,TSC总是产生不同的值(纳秒(或更好的)分辨率,IIRC)。我已经对它进行了非常艰苦的测试(达到几千亿位),而且它看起来像是在飞舞着。但这或许更能证明梅森缠绕机作为prng的稳健性,而不是我如何播种。

    当然,这些并不是完全不受黑客攻击的,但我只是没有看到在我的有生之年所有这些(和sha*)都被黑客攻击和破坏。


    如何旋出一个线程,它将在杀死某个变量之前在一个固定的时间内在一个紧密的循环中操作该变量。最终结果将取决于处理器速度、系统负载等。非常矫揉造作,但比SRAND(时间(空))要好。


    种子的来源并不重要。更重要的是伪数生成器算法。不过,我在一段时间前就听说过为一些银行业务培育种子。他们综合考虑了许多因素:

    • 时间
    • 处理器温度
    • 风扇转速
    • CPU电压
    • 我不记得了:)

    即使其中一些参数在时间上变化不大,您也可以将它们放入一些好的散列函数中。

    如何生成好的随机数?

    也许我们可以考虑有限个宇宙?如果这是真的,那么所有新的平行宇宙都在被创造出来,我们可以这样做:

    1
    2
    3
    int Random() {
        return Universe.object_id % MAX_INT;
    }

    在每一刻,我们都应该在平行宇宙的另一个分支上,所以我们应该有不同的ID。唯一的问题是如何获得宇宙对象:)


    Don't worry about a"good" seed for a random number generator. The statistical properties of the sequence do not depend on how the generator is seeded.

    我不同意约翰·D·库克的建议。如果您在Mersenne Twister的种子中所有位都设置为零(除了一位),它最初将生成除随机数以外的任何数字。生成器需要很长时间才能将此状态转换为任何可以通过统计测试的状态。简单地将生成器的前32位设置为种子将具有类似的效果。此外,如果整个状态设置为零,则生成器将产生无休止的零。

    正确编写的RNG代码将有一个正确编写的种子设定算法,该算法接受一个64位的值,并为生成器种子设定,这样它将为每个可能的输入生成合适的随机数。因此,如果您使用的是可靠的库,那么任何种子都可以。但是,如果您对自己的实现进行黑客攻击,那么您需要小心。


    宇宙微波背景谱上的噪声。当然,你必须首先去除一些各向异性,前景物体,相关的探测器噪声,星系和局部群速度,极化等。许多陷阱仍然存在。


    有些人使用键盘输入(按键之间超时),我听说我在一本小说中认为可以使用无线电静态接收-但当然,这需要其他硬件和软件…