今回の投稿は前回のダブルハッシュの続きです。
前回は SHA-256 を2回行うダブルハッシュについて、2回目に衝突があるとその程度によっては問題なんじゃないの?ということで衝突があるのかどうなのかをやってみるというよっぽどの暇人じゃないとできないような無謀な内容でした。
単純に算出されたすべてのハッシュ値を記憶しておいて衝突がないかどうかやってたわけで、非常に効率悪いやり方でしたのでもう少し効率良さそうなやり方に変えてみました。暇人というところは違いないわけですが。
前回は0から順番にハッシュ値を計算していましたが、今回は算出されたハッシュ値を次回の入力値とするように変更しました。
で、仮に同じ値が出力されるような衝突があるとすると、
こんな風にグルグルができるはずということで、全部の出力を憶えておくんではなくて、たまに憶えておけばグルグルになったときに発見できるだろうという都合のいい考えでやってみました。
byte[] value = new byte[32];
List sha256 = new List();
Task task = null;
ulong count = 0;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (task == null)
{
task = Task.Run(() =>
{
SHA256 crypto = new SHA256CryptoServiceProvider();
while (true)
{
// 前回の出力を入力に使う
value = crypto.ComputeHash(value);
string hash = BitConverter.ToString(value);
if (sha256.Contains(hash))
{
MessageBox.Show("あった!" + BitConverter.ToString(value));
}
else
{
// 1億回に一回 値を記録する。
if ((count++ % 100000000) == 0)
sha256.Add(hash);
}
}
});
}
else
{
label1.Text = count.ToString("X");
}
}
1億回計算したら値を憶えておくようにしました。
この状態で3連休ほったらかしにしておいた結果...
どーん
回数としては743億回ぐらいの計算を行ったようですがまだ見つかってないですね。
これって全体のどのくらいの量なんだろうか、バイト数で多めに見て5バイトまで完了。ということは SHA-256 は32バイトなのでえーっと、256の(32-5=)27乗分の1くらい終わってるということかー、それってどんくらい?関数電卓で計算すると
1.0531229166855718669791802768367e+65
おー、10の65乗分の1、パーセントにすると10の63乗分の1パーセントということですねー...
なんて無駄なことをやってるんでしょうか...orz