ついにハッシュ計算処理へ
さてさて、いよいよ中枢であるハッシュ計算処理への連結を行います。 ここで用意するのは先ほどパディング処理で帳尻合わせをした入力データ(バイト配列)と、計算済みのハッシュ値です。 だいぶ前に書きましたが、初回のメッセージ処理はFIPSで決められている定数を使います。 ハッシュの初期値はFIPS 180-2 5.3.2 Setting the Initial Hash Value - SHA-256に記載されています。
さらに、メッセージブロックを取り出すための配列も用意します。 メッセージブロックは常に64Byteなので宣言時に指定しておきます。
[ Function Hash ]
' ハッシュの初期値
Dim intHash As UInt32() = {&H6A09E667UI, &HBB67AE85UI, &H3C6EF372UI, &HA54FF53AUI, _
&H510E527FUI, &H9B05688CUI, &H1F83D9ABUI, &H5BE0CD19UI}
Dim bytBlock(64) As Byte
準備はこれだけ。 あとは、順番にbytBlockへデータをコピーしてメッセージブロックを呼び出すだけです。 これは簡単にできますね。
[ Function Hash ]
For intPos As Integer = 0 To Bytes.Length - 1 Step 64
' ブロック用配列にデータをコピー
Call Array.Copy(Bytes, intPos, bytBlock, 0, bytBlock.Length)
' ブロックのハッシュを計算
Call MessageBlock(intHash, bytBlock)
Next
んまぁ、ハッシュ計算処理に配列のインデックスを教えるようにすればわざわざbytBlockにコピーすることもないのですが、あっちの関数がややこしくなるので今回はこの方法で。 ハッシュ計算処理が終われば、intHashには新しいハッシュ値が入ってきます。 すべてのメッセージブロックを処理し終えれば、見事ハッシュ値の完成です。
このままでは32bit値なので扱いが厄介ですね。 バイト配列に変換して戻り値としましょう。 ハッシュ値は配列になっているのでFor~NextでひとつずつBitConverterを呼び出していきます。 ここでもリトルエンディアンが障害となるので配列を逆転させます。
[ Function Hash ]
' ハッシュ値を格納するバイト配列
Dim bytResult(31) As Byte
For intIndex As Integer = 0 To 7
Call Array.Copy(BitConverter.GetBytes(intHash(intIndex)), 0, bytResult, intIndex << 2, 4)
' リトルエンディアンの場合は配列を回転させてビッグエンディアンにする
If BitConverter.IsLittleEndian Then
Call Array.Reverse(bytResult, intIndex << 2, 4)
End If
Next
Return bytResult