このあいだ、Advent Calendar に UUID の衝突確率の話を書きました。
もちろんこれは、昔に書いた以下のエントリをちょっとだけ修正しただけで、早速バレたりしていた。
とはいえ、UUID の衝突には続く話がありまして、それが誕生日攻撃というものです。
誕生日攻撃とは
誕生日攻撃とは何かというと、いわゆるハッシュ関数の衝突を引き起こすための攻撃です。その方法はすごくシンプルで、ランダムな値を生成しまくってハッシュ関数にかけ続ける、というものになります。 そんなの衝突を発生させるまでに一体何年かかるのか、という気もしますが、それが発生するのは直感に反し、意外な高確率になります。
例えば、 人のクラスで誕生日が全く同じ人がいる確率は 70 % と意外な高さになります。 この直感に反する確率の高さ (wikipedia:誕生日のパラドックスと言われます) こそが、誕生日攻撃の依拠するものです。
一体何回攻撃を繰り返したら衝突するのか。その期待値は。
Qiita にも書いたとおり、「UUID に 少なくとも 1 回は衝突が発生する確率」が になるような UUID の生成回数は
でした。これは、UUID version 4 においてランダムなビット数が 122 個あることに起因しています。もう少し一般化すると、これが bit なのであれば その回数は になります。 さらに一般化すると、値域が であり一様に分布するハッシュ関数があったとき、その衝突確率が になるために必要な試行回数も同じ式で表されるということです。
それではちょっと考え方を変えて、衝突を発生させるために必要な試行回数の期待値は何回くらいになるでしょうか?というのがこのエントリの主題です。
最初に結論を述べておくと、値域が の大きさである一様分布する関数があったとき、期待値 は
の範囲で抑えられます。
は通常大きい値ですから、 の値は に収束することを意味します。 値域が bit のハッシュ関数であれば、 ですから、その値は になります。
それでですね、なんでこの値になるのかっていうのを、丁寧に説明していこうと思っていたんです。ホントに。 で、数式をスゲー書いていたんですが、途中でスゲー面倒くさくなりました。なんでオレはクリスマス近くになってこんなことを書いているんだろうみたいな。 そもそもなんでこの値になるのか、っていうのは論文を読めば書いてあるし、ぼくがクリスマス近くになって、論文と同じ数式ばっかし書く意味なんてないし。
というわけですから、気になる人は以下の論文の証明あたりを読めば良いと思います。 Theorem 2. がターゲットだ。
以下は途中まで書いた証明ですが、詳しくは論文を読んでくれ。
期待値の定義から
まず、ここで求める期待値を とします。 は確率変数で、ここでは試行回数を表現します。 期待値の定義から なわけですが、これをもう少し進めると、以下のような引き算で表されます。
ここで第一項について のときを考えると
ですし、第二項については のとき なので、
となります。これらを代入すると、
となります。
k 回の試行でも衝突が発生しない確率の上界
いま、 回の試行でも衝突が発生しない確率を と定義すると、Qiita に書いた議論から
となることが分かります。ここで両辺の対数を取ると
となります。さらに、のテイラー展開は になるので、これを代入すると、
右辺を展開すると、 となるので、
、つまり は という上界で抑えられることが分かります。
期待値の上界
これまでの議論から、
となります。このあたりでもう疲れた。気になる人は論文読もう。
というわけで
みなさんメリークリスマス!!!!!!!!!!