こんにちは!CryptoGamesというブロックチェーンゲーム企業でエンジニアをしているかるでねです!
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。
このブログ以外でも情報発信しているので、よければ他の記事も見ていってください。
https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58
今回はブロックチェーンについて学んでいる際に出てきた、「ハッシュ関数」について理解していこうと思います。
以下の本を読むときの助け人もなります。
「ハッシュ関数についてなんとなくしか知らない」
「ハッシュ関数について学んだけど理解できなかった」
こんな人の役に立てば幸いです!
前置きは早々に本題に入っていきましょう!
ハッシュ関数の特徴
まずは「ハッシュ関数」の特徴についてみていきましょう。
関数とは?
と、その前に「関数」というものがどういうものか復習してきましょう。
「関数」とは一言で言えば以下のようになります。
なんらかの入力を与えると、なんらかの出力が得られる。
ガチャとかで例えるとわかりやすいですね。
「コイン」を入れることで、ガチャから「カプセル」が出てきていますね。
ざっくりこれが「関数」です。
「関数」によっては複数の入力が必要になることもあるので、頭の片隅に置いておきましょう。
ハッシュ関数とは?
「関数」について確認できたところで、早速「ハッシュ関数」の特徴についてみていきましょう。
「ハッシュ関数」とは一言でいえば以下のようになります。
任意の長さの入力データを変換して、決まった長さの出力を生成する。
文章だけだとわかるようでわからないと思うので、図にしてみましょう。
「かるでね」という「ハッシュ関数」に通すことで、訳のわからない文字が出力されていますね。
「ハッシュ関数」から出力された値を「ハッシュ値」と言います(これ以降「ハッシュ値」を使っていきます)。
この「ハッシュ値」は、どんな入力が得られても同じ長さになります。
この部分が「ハッシュ関数」の基本の基本となるのでしっかり頭に入れておきましょう。
一方向性関数
いきなり難しそうな用語が出てきましたね...。
ただ、これからさらに難しそうな用語が出てくるのでめげずについてくください!わかりやすく解説していきます!
「一方向性関数」とは一言で言うなら以下になります。
ハッシュ関数に同じ入力を与えれば、毎回同じハッシュ値を出力する。
例えば「かるでね」と言う文字列を与えると、毎回全く同じ「ハッシュ値」を得ることができます。
図でみていきましょう。
これも重要な特徴です。
現像計算困難性
漢字漢字してますね...。
これも一言で言うと以下のようになります。
ハッシュ値から入力を求めることが事実上不可能。
図でみてきましょう。
「かるでね」という文字を「ハッシュ関数」に通して「ハッシュ値」を得ましたが、逆に「ハッシュ値」から「かるでね」という文字を求めることは事実上できません。
「事実上不可能」と言うのは、「100%できないと言う保証はないが、膨大な計算が必要だから実際無理だよね」という意味です。
どのくらいの計算を行う必要があるかというと、「ハッシュ値がnビットの時、2のn乗」の計算量が必要です。
どのくらいの数字になるとかいうと、256ビットのハッシュ値の時以下のようになります。
115792089237316195423570985008687907853269984665640564039457584007913129639936
もはや数えたくないレベルですね...。
これくらいあれば確かに「事実上不可能」と言ってもよさそうですよね。
入力が似ていても出力は全く異なる
これはそのままの意味です。
例えば「かるでね」と「かるてね」という入力があるとします。
これを「ハッシュ関数」に通してみましょう。
入力は似ていますが、「ハッシュ値」は全く似ていませんね。
このように入力する文字が1文字でも変わると、「ハッシュ値」は全く異なる値になるので推測されにくいですね。
衝突計算困難性
お決まりの漢字ですね...。
ここもお決まりの流れで一言で言っていきましょう。
同じハッシュ値を生成する2つの異なる入力を求めることが事実上不可能
ハッシュ関数では、同じ「ハッシュ値」を出力してしまう文字があります。
もしその文字がわかってしまうと安全性が脅かされます。
しかし、同じ「ハッシュ値」を生成する2つの入力値を求めることは前章と同じで「事実上不可能」です。
この性質のおかげで、「同じハッシュ値を生成する異なるファイルや修正したファイルを作ることができなくなる」ので安全性が確保されます。
第2現像計算困難性
もう漢字にも慣れてきましたね。
とあるハッシュ値から、他のハッシュ値を求めることが事実上できない。
具体例を出して理解していきましょう。
よくある暗号文として、「1文字ずらしていくと答えがわかる」というものがあります。
「きれどの」
この文字を50音で1文字ずつ上にずらしてみましょう。
「き→か」
「れ→る」
「ど→で」
「の→ね」
「かるでね」となりますね。
これは「第2現像計算困難性」を満たしていません。
なぜなら他の入力を与えた場合、何が出力されるかを予測できてしまうからです。
「あかさたな」の出力は何になるでしょう?
答えは「いきしちに」ですね。
このように予測されてしまっては暗号として良くありません。
このような「ハッシュ値」であれば全く予測できないですね。
最後に、こちらも「事実上不可能」と言う記載があるので、前章、前々章と同じく求めるために相当な計算量が必要であると言うことを認識しておきましょう。
ここまで「ハッシュ関数」の特徴についてみてきました。
次章では「ハッシュ関数」にどのようなものがあるのかをみていきます!
ハッシュ関数の種類
全部紹介するにはあまりにも数が多いのでかいつまんで紹介してきます。
気になる方は以下の本を参考にするか、自分で調べてみてください!
SHA2
「ハッシュ関数」の1つで、以下のように種類がたくさんあります。
ポイント
- SHA-224
- SHA-256
- SHA-384
- SHA-512
- SHA-512/224
- SHA-512/256
これらの違いの1つとしては「文字を切り詰めている」と言うものがあります。
詳しく解説すると複雑なので上の本か自分で調べてみてください!
ではこの中からいくつかみていきましょう。
SHA-256
ビットコインではこの「ハッシュ関数」が使用されています。
この「ハッシュ関数」を使用すると256ビットの値が返ってきます。
SHA-512
この「ハッシュ関数」を使用すると512ビットの値が返ってきます。
SHA-256との違いとしては、中で行う処理がところどころ違うと言う点です。
こちらも詳しく説明すると複雑なので上の本などに解説を任せます。
RIPEMD
MD4という「ハッシュ関数」の変形系です。
RIPEMD-160
ビットコインでは前述のSHA-256とともに使われています。
どのように使われているかというと、SHA-256の「ハッシュ値」出力が256ビットなので、160ビットに短縮にしてくれます。
SHA3
「SHA2」の後釜として採用されたものです。
「SHA2」を補完し、共存させることを目的に作成されたので、中身は全く違います。
出力を好きなように設定できるという特徴を持っています。
ハッシュ関数の用途
最後にハッシュ関数はどのようなところで使われているかをみていきましょう。
ポイント
- データが改ざんされていないか検証する。
- ハッシュ化してデータベースに保存。
- Powやアドレス生成。
1つ1つみていきましょう。
データが改ざんされていない確認
「ハッシュ関数」の特徴の1つに、「同じ値を入力すると、毎回同じハッシュ値を出力する」というものがありました。
もしデータが改ざんされていた場合、「ハッシュ関数」に通すと全く異なる「ハッシュ値」が得られます。
これによりデータが改ざんされていることがわかります。
ハッシュ化してデータベースに保存
例えばなんらかのWebサービスを利用したくてユーザー登録したとします。
その際にパスワードを入力したのですが、そのままパスワードがデータベースに登録されると危険です。
なぜならデータベースをハッキングされた場合に、パスワードがそのまま盗まれてしまうからです。
ではどうすればいいのか?
それは入力したパスワードを「ハッシュ関数」に通して、その「ハッシュ関数」から出力された「ハッシュ値」をデータベースに登録すればよいのです。
この場合であれば、たとえハッキングされてパスワードが盗まれても「現像計算困難性」という特徴から、入力値を求めることが事実上不可能となります。
だいたいのWebサービスやアプリケーションではこのような仕組みが組み込まれています。
Powやアドレス生成
これだけではなんのことかわからないですね。
この2つはビットコインなどの仮想通貨に関することです。
この2つを取り上げると長くなってしまうので今後まとめていきます。
参考
ポイント
最後に
今回は「ハッシュ関数について理解していく」というタイトルで「ハッシュ関数」を解説してきました。
正直深掘るとめちゃくちゃ難しい上に、必須の知識でもないので大部分を省いて解説しました。
もしより詳しく知りたい方は以下の本を読むか、自分で調べてみてください。
普段はPythonやブロックチェーンメインに情報発信をしています。
Twiiterでは図解でわかりやすく解説する投稿をしているのでぜひフォローしてくれると嬉しいです!
Tweets by cardene777