我可以看一下一个函数吗?具有高抗碰撞性的特性,并期望它也具有高度均匀的分布?
#1 楼
定义$ H(x)= \ operatorname {SHA-256}(x)\ mathbin \ | 1 $;也就是说,将单个1位附加到SHA-256。您可以在$ H $下找到碰撞吗? $ H $是否有类似于均匀分布的东西?这个反例不仅是病态的,而且是病态的。像Rumba20和VSH这样的设计提供了抗碰撞能力,但既没有抗原像性,也没有提供均匀性。更广泛地用于随机oracle建模(禁止SHA-256进行长度扩展攻击),这意味着可以合理地将不同输入上的输出建模为独立均匀分布。
在黑暗时代在90年代初期,当美国仍禁止出口密码术作为弹药时,该禁令本身就涵盖了加密,例如DES,但对身份验证有明确的例外规定(22CFR§121.1(XIII)(b)( 1)(vi),因为已废除),因此允许散列函数Snefru进行发布和导出。
1992年,一位名叫Dan的研究生指出,您可以在其中使用Snefru作为子例程。否则,无需加密的程序即可对消息进行加密。当他将其非凡的发现告知美国国务院,并请他们确认他的理解,即与免税的Snefru一起发布他的无密码程序不会违反出口管制时,他们对此并不感到高兴。 >
美国国务院缺乏幽默感,导致伯恩斯坦诉美国一案长达近十年之久的法庭之战,涉及22CFR§§120-130和15 CFR§§730-744中的规定是否禁止出口加密软件的构成违反美国宪法第一修正案的事先约束。最终,美国联邦政府在一个恼人的研究生的支持下走到了一个角落,放宽了规定,此案被驳回。
如今,具有相同想法的更新版本-使用哈希函数ChaCha以及受一次性便笺簿先进技术(在某些圈子中也称为“ xor”)启发的方法来进行加密消息-以TLS中的ChaCha / Poly1305密码套件的形式保护互联网上每天可能数PB数据的机密性。 Rumba20和VSH显示,ChaCha不能抗碰撞-也不足以防止与均匀随机性之间的区别,这是例如需要一次性填充来获得任何安全性所需要的。
聚苯乙烯如果您确实使用了哈希函数,例如生成位$ H(k \ mathbin \ | 0)$,$ H(k \ mathbin \ | 1)$等的序列,并希望使用该位序列选择$ 0 \的整数$ x $ leq x
评论
$ \ begingroup $
的确如此。人们通常希望获得密码散列函数的属性是随机预言的不可区分性,该预言涵盖了许多基础。
$ \ endgroup $
–user2552
19年5月22日在19:28
#2 楼
不会,但是每位的高抗碰撞性会产生影响。非均匀性->熵较小->抗碰撞性减弱。
由于密钥大小是重要因素:大多数加密哈希函数具有统一的输出给定熵输入。使用哈希(或加密)例程从单个熵块中生成随机数流是一种已建立的惯例。列出了推荐的基元和陷阱等。
来自维基百科:
“在某些情况下,计数器的加密安全散列也可以充当良好的CSPRNG。在这种情况下,在这种情况下,该计数器的初始值必须是随机的且是秘密的。但是,对于以这种方式使用这些算法的研究很少,至少有一些作者对此种使用方法提出警告。“
评论
$ \ begingroup $
您如何得出这些含义?当今最流行的密码-AES-GCM和ChaCha / Poly1305-使用计数器的“哈希函数”,这在一定程度上受到启发,部分原因是美国对密码学的出口管制作为一种弹药并未涵盖哈希函数Snefru。但是AES和ChaCha都不提供抗碰撞性。相反,为防碰撞而设计的Rumba20和VSH不能提供耐原像或均匀性。 GHASH具有均匀性和低碰撞概率,但是没有抗碰撞性。 “哈希函数”意味着很多东西;问题是关于特定属性。
$ \ endgroup $
–吱吱作响的s骨
19年5月21日在15:47
#3 楼
仅用我的2美分,您不一定需要(繁重的)哈希函数来生成序列或一系列伪随机数。一种实用的低级方法来生成统一的在特定范围内的值分布可以使用简单的接受/拒绝方法,并结合伪随机数生成:
如果我们想要$ k $不同的输出值,则我们的范围将是$ [0,k-1] $
使用哑元0 / 1-生成器,例如Math.random for js,精炼的量子随机输入源,或简单地翻转a硬币$ r $次,用于生成$ r $位的伪随机序列,其中:
$ r = roundup(\ log_ {2}(k))$
结果值$ n $在区间$ [0,2 ^ {r} -1] $
中如果$(n
,否则,请舍弃该数字并重新生成一个新的伪随机序列/数字。
显然,我们将使用更多的随机输入来自我们的数据e,当$ k << 2 ^ {r} $时,由于我们期望有更多的拒绝,但是在这种情况下使用模数不是一个好的解决方案,因此不会给我们均匀的分布。
最好的情况是$ k $是$ 2 $的幂:
$ k = 2 ^ {i} $,对于一般的自然$ i $
,我们恰好消耗了$ 1 $位的输入数据以产生$ 1 $位的输出
不浪费时间
最糟糕的拒绝情况发生在以下情况:
$ k =(2 ^ {r-1} +1)$
$(k- 1)= 2 ^ {r-1} $
$ r = 1 + \ log_ {2}(k-1)$
我们将消耗〜$ 2 $位的输入数据来产生$ 1 $位的输出
我们将在生成过程中花费更多的时间
例如,如果需要,在选定的时间间隔$ [0,k-1 ] $:
$ r = 10 $位以生成至少$ k $个不同的值,然后:
当$ k =(2 ^ {10 -1} + 1)= 513 $
我们希望平均牺牲约50%的伪随机输入数据,并在出现输出值时丢弃所有输出值$> 513 $。
总共$(2 ^ {10}- 513)= 511 $值
评论
为什么不能使用流密码?那会更有效:流密码比哈希函数更快。它们还会产生与真正随机数据无法区别的输出。如果您有十亿种可能性并正在生成一百万个值,那么如果这些值在前一百万个插槽中,那是否均匀分布?即使下一个生成的值发生碰撞的可能性不太可能使用先前使用的值之一,我也会认为发生碰撞的风险较低,但视差不一致。
不是答案(@Squeamish Ossifrage已经回答了您的标题问题),而是要解决您的第一段问题:是的,可以使用具体的加密哈希函数来生成随机数据流(在适当播种后可以用于加密目的,因此应符合您的“看似随机”的要求)。例如,请参阅NIST建议中的Hash_DRBG。但是,寻找一个好的实现方案-不要重新发明轮子!
这似乎是一个X–Y问题:如果您需要产生均匀分布的随机数,请不要使用哈希函数,而应使用(CS)PRNG,也可以结合使用均匀分布推导函数。
如果您不关心密码属性,那么可以看一下Halton序列。这对于数值采样算法(不是超高维算法)非常有用,因为它是伪随机数序列,可以非常均匀地覆盖采样空间。