SHA-256 って何をしているの?

皆さん、こんにちは。技術開発グループのn-ozawanです。
霜降り肉を見ると「うわぁ!美味しそう」から「うわぁ…胃がもたれそう」になりました。

本題です。
データが改ざんされたかどうかを確認する方法としてハッシュ関数があります。前回、ハッシュ関数の概要についてお話ししましたので、今回はハッシュ関数のアルゴリズムの1つである「SHA-256」が、どのようにして任意のデータからハッシュ値を算出しているのかをお話しします。

SHA-256

全体フロー

ハッシュ関数のインプットとなるデータのことを「メッセージ」と呼びます。SHA-256の全体の流れは以下の通りとなります。

  1. 512ビットで割り切れるように、メッセージにパディングします。
  2. パディングしたメッセージを512ビットで分割します。
  3. 分割した512ビットごとに、64個の32ビットのワード(W0 ~ W63)を生成します。
  4. 64個のワード(W0 ~ W63)を元にブロック処理を行います。
  5. 全てのブロック処理を行い、その結果がハッシュ値になります。

上記の図で黄色くしている個所は後ほど詳しく見ていきます。

パディング

SHA-256ではメッセージを512ビットに分割して処理していきます。メッセージの長さは任意なので、必ずしも512ビットで分割することは出来ません。なので、メッセージが512ビットで分割できるようにパディング(詰め物)をしてあげる必要があります。

  1. メッセージの最後に1(ビット)を付与します。(下図A)
  2. 512ビットで割り切れるビット長から64ビット分を残して、0を詰めます。(下図B)
  3. 残しといた64ビット分に、メッセージの長さを付与します。(下図C)

W0 ~ W63 の算出

分割された512ビットのデータから、64個の32ビットのワードを算出します。512ビットを単純に32ビットで分割すると16個までしか算出されません。なので17個以降は特別な計算により算出することになります。

繰り返しになりますが、W0 ~ W15 までは単純に512ビットのデータを32ビットで分割したものになります。W16 以降は以下の計算式により求めます。

Wt = σ1(Wt-2) + Wt-7 + σ0(Wt-15) + Wt-16

逃げ出したくなる計算式ですね。1つずつ見ていきましょう。
式中のtというのは、ラウンド数になります。この場合、tは16 ~ 63のいずれかになります。例えば、W16 を求めたい場合は以下のようになります。

W16 = σ1(W14) + W9 + σ0(W1) + W0

σ0σ1は関数です。インプットとなる値(上の式ではW14もしくはW1)を、右回転もしくは右シフトして、それぞれをxorした結果を出力します。右回転というのは、循環右シフトのことです。

ブロック処理

W0 ~ W63 を算出したら、続いてはブロック処理を行います。ハッシュ値の長さは常に固定で、SHA-256 であればハッシュ値の長さは256ビットになります。ブロック処理は任意長のメッセージを固定長にする処理になります。

ブロック処理では、いずれハッシュ値となる256ビットを8個の32ビットのワードに分割し、それらを内部状態として保持します。内部状態はAバッファからHバッファの8個で構成されおり、初期状態として特定の固定値が指定されています。(内部状態の初期値は前述の全体フローの図に記載しています)

内部状態のA~Hに対して、先ほど算出したW0 ~ W63 のそれぞれでステップ処理を64回繰り返し行います。最後に64回繰り返し行った結果と、ステップ処理をする以前の状態を加算します。加算した結果が新しい内部状態となり、次の512ビットの処理に引き継がれます。

ステップ処理

ブロック処理で行われているステップ処理は以下の図ようになります。

基本的にはAバッファをBバッファへ、BバッファをCバッファへ、などのようにバッファごとシフトします。しかし、AバッファとDバッファに関しては、特別な処理が挟みます。

AバッファとEバッファに対して、Σ0Σ1 の処理が行われます。Σ0Σ1 は関数です。σ0σ1 と同じように、与えられた値に対して右回転を行い、それぞれをxorした結果を返します。

図中にある「ステップ依存の定数Kt」ですが、これはSHA-256の仕様で決められている定数を使います。

ハッシュ値を求める

すべてのブロック処理を行い、内部状態の8個のA~Hを結合した結果がハッシュ値となります。

おわりに

SHA-256で何をやっているのかをお話ししました。ハッシュ値を求めたいときは、ライブラリが標準で用意されているか、公開されていると思いますので、自作せずにそちらを使うようにしましょう。

SHA-1およびSHA-2を定めている PUB 180-4 を見れば、何をやっているのかは分かるのですが、これらの定数や処理が、なぜ衝突耐性を担保出来るのか分かりませんね。数学に強い人なら分かるのでしょうか。

ではまた。

採用情報

「チームアイオス」入団者募集

〜就活で悩むアナタに来て欲しい〜