Random 单独使用PRNG生成的数字的每个字节是否可以接受?

Random 单独使用PRNG生成的数字的每个字节是否可以接受?,random,Random,假设您有一个生成64位输出的非加密安全设备 假设字节为8位,是否可以将64位输出的每个字节用作单独的8位随机数,或者这可能会破坏良好PRNG的随机性保证?还是取决于PRNG 因为PRNG不是加密安全的,所以我担心的“随机性保证”不是安全性,而是字节流是否具有与PRNG作者使用的“随机性”定义相同的随机性保证,即PRNG对于其64位输出具有相同的随机性保证。这对于CSPRNG应该是相当安全的。为了进行比较,它就像逐字节读取/dev/random。有了一个好的CSPRNG,简单地生成一个64位的样本

假设您有一个生成64位输出的非加密安全设备

假设字节为8位,是否可以将64位输出的每个字节用作单独的8位随机数,或者这可能会破坏良好PRNG的随机性保证?还是取决于PRNG


因为PRNG不是加密安全的,所以我担心的“随机性保证”不是安全性,而是字节流是否具有与PRNG作者使用的“随机性”定义相同的随机性保证,即PRNG对于其64位输出具有相同的随机性保证。

这对于CSPRNG应该是相当安全的。为了进行比较,它就像逐字节读取
/dev/random
。有了一个好的CSPRNG,简单地生成一个64位的样本8次,并为每个样本选取8位也是完全可以接受的(扔掉其他56位)

对于非CSPRNG的PRNG,您将对PRNG的原始输出产生“安全”顾虑,这超过了是否将输出切分为字节大小的块

在所有情况下,必须确保PRNG已正确播种并定期重新播种(以便定期刷新任何可能受损的内部状态)。安全性取决于内部状态的不可预测性,而内部状态最终由种子输入的质量驱动。好的CSPRNG实现将为您做的一件事是悲观地估计捕获的“熵”的数量,以保护输出不受可预测的内部状态的影响

然而,请注意,对于8位,在任何情况下,您只有256个可能的输出,因此如何使用这一点就成了一个更大的问题。例如,如果对PRNG的输出执行类似于基于XOR的加密的操作(即,将其视为基于某些预共享秘密种子的一次性pad),则使用已知的纯文本攻击可能相对容易地揭示PRNG内部状态的内容。这是另一种类型的攻击,好的CSPRNG实现应该通过其设计(例如使用计算安全的哈希函数)来防范这种攻击


编辑添加:如果您不关心“安全性”,但只需要输出看起来是随机的,那么这应该是非常安全的——理论上,一个好的PRNG很可能产生0和1,并且这在任何八位字节之间都不应该变化。因此,您期望可能输出值的线性分布。要验证这种分布是否有偏差,您可以做的一件事是对一些相当大的尺寸(例如1M)进行蒙特卡罗模拟,并将原始64位和8*8位输出的直方图与256个箱子进行比较。如果线性分布保持不变,则两种情况下都会出现大致平坦的图表。

这取决于生成器及其参数化。引用Wikipedia页面的话:“当m是2的幂时,LCG的低阶位不应依赖于任何程度的随机性。[…]当m是2的幂时,任何全周期LCG将交替产生奇数和偶数结果。”

你在说什么“保证”?如果您寻找的是一个良好的分布,如果您可以从统计上区分字节和随机数,那么您可以从统计上区分数字和随机数。如果是加密安全,如果你能切实区分字节和随机数,那么你就能切实区分数字和随机数。我忘了说我没有加密安全保证。我所指的保证是流看起来仍然是“随机的”,因为实际的PRNG编写者使用“随机”的定义。将更新问题。“保证”是一个强有力的词。如果一个生成器在随机性测试中表现良好,而你从中得到了一个字节生成器,那么它是否也表现良好?这是不可能的,因为你会得到不同的p值。对于一个好的发电机,它们应该仍然很小。当然,这是一个经过研究的问题。@GavinHoward更新了我的答案,但基本上:只需对你的PRNG进行蒙特卡罗模拟,看看你是否满意。“理论上,一个好的PRNG…”-实际上,有很多不好的PRNG。例如,许多C实现继续完全使用
rand()
的垃圾实现。“在理论上,理论和实践没有区别。在实践中,确实有区别。”@pjs。这就是为什么答案是:去比较直方图。特别是对于这个问题,PRNG的绝对质量与将本机64位输出样本分成8位大小的块的拟议方案是否会扭曲分布并不重要。通过比较两种情况下的输出直方图,可以测试这种效应是否由于PRNG偏差而过于显著。直方图是不够的。直方图会告诉你,两个比特序列“0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,…”是均匀分布的,但是我怀疑我们中的许多人会认为它是可接受的随机的。这就是为什么像Diehard这样的测试套件会检查连续行为,如高于平均值的运行与低于平均值的运行、向上或向下运行的长度等。连续行为与聚合行为一样重要。@pjs:这是非常正确的。在这种情况下,值得注意的是,如果不重新播种,所有PRNG最终都会循环(当然,除非它们只是为了停止提供输出而构建的)。事实上,更大的问题是它们在循环之前在做什么。例如,如果没有重复的值,那么在仅仅200000个值之后,你就可以使一个32位的数字流失败,
p>=0.99
——生日悖论告诉我们,如果这些值真的是独立的,那么到那时你至少会看到一个重复。相反,如果您使用的是具有128位或更多状态空间的现代生成器,则循环不是问题,因为它不会在您的生命周期内发生。