Solidityのsha関数が同じ入力に異なる値を返す時に確認すること

こんにちは、アカネヤ(@ToshioAkaneya)です。

先日、Solidityでイーサリアムのスマートコントラクトを開発をしていた時に不可解なことが起こりました。

Solidityではsha3(keccak256)、sha256といったハッシュ関数がサポートされています。

ハッシュ関数は一方向性関数で、同じ入力に対しては同じ出力をして、異なる入力に対しては異なる出力をするという性質を持っています。

ですので、次の3つのsha256関数の呼び出しは全て同じハッシュ値を返すことを想定してました。

sha256();

sha256(0);

sha256(uint(0));

しかし、実行してみると…

> sha256();
0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

> sha256(0);
0x6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d

> sha256(uint(0));
0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925

全て値が異なります!

どういうことかと調べていると、次の記事を見つけました。

SHA-256のアルゴリズム

この記事と、さらにもう1ページ先のパディング処理について読んでみて下さい。

この記事のおかげで謎が解けました。

パディング処理によって、値だけではなくて入力サイズも関係していたんですね。

試しに、次のプログラムを実行させてみました。

> sha256(uint64(0)) == sha256(uint32(0),uint32(0));
true

> sha256(0) == sha256(uint8(0));
true

> sha256(uint(0)) == sha256(uint128(0),uint128(0));
true

同じ入力サイズで、さらにビットが全て0の入力に対しては同じ値が返っていることが確認できました!

ちなみに、Solidityで単に0と書いた時には型はuint8になるようです。

また、uintはuint256の省略ですので、3番目の結果も納得がいきます。

皆さんもsha関数で悩んでいるときは、入力サイズが同じかどうかを確認してみて下さい。

【追記】プログラミングスクールのレビューサイトを開発しました。

この度、プログラミングスクールのレビューサイトの「スクールレポート」を開発しました。

プログラミングスクールの人気は年々高まっているものの、高額な受講料を請求しておきながら質の低い教育を提供する悪質なスクールも見受けられるようになってきました。

今回開発した「スクールレポート」では受講生の方のみレビューを投稿することが出来ます。

プログラミングスクール業界がより健全なものになることを願っています。

スポンサーリンク