PythonでSHA256をフルスクラッチした
どうも金ないニカチュウと申します。 Pythonでimportを用いずにSHA256のハッシュを計算するプログラムを書きました。
hashlib
PythonでSHA256のハッシュを計算するには偉大な hashlib
ライブラリを用いるのが簡単。
|
|
まあこんなライブラリで楽するのは良くないですね。
私の学校の教員も言っていました。
楽しちゃダメだから
— 某高専某教員
フルスクラッチ
以下に紹介するプログラムを用いて何が起きても責任は負いません
信頼性が必要ならhashlib
を用いてください
SHA256の仕様は以下のPDFに記載されている。 https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
まずはH, Kを用意する。
|
|
次に使う関数を定義する。
|
|
右ローテートや右シフトなどは普通だが、加算や左シフトを行う場合気を付ける点がある。
Pythonの整数型は精度が無限(何桁でも保持できる)ので、32ビットで表せる範囲を超えてしまう可能性があるため、0xFFFFFFFF
(0b1
が32ビット分)でマスクして範囲を超えないようにしている。
メッセージブロックを生成
まずは、データの次に入力直後の0x80
、末尾8バイトにデータのビット数を入れ、総バイト数が64バイトの倍数になるように調整する関数を作る。
|
|
次に64バイトごとの配列に分割する関数を作る。
|
|
このようにしてメッセージブロックを生成する。
|
|
メッセージスケジュールを生成
次はメッセージブロックからメッセージスケジュールを生成する。
まずはバイト列を4バイト(32ビット)ごとint配列に変換する関数を実装する。
|
|
また、以下からのコードはメッセージブロックごとに行う。
|
|
メッセージスケジュールは、本来32bit*64=256バイトとなる。
メッセージブロックをint配列に変換しても、64バイト分しかないため、残りを計算する。
|
|
これでメッセージスケジュールが生成できた。
ローテーション処理
次にローテーション処理を行う。
|
|
中間ハッシュ値の更新
|
|
ここまでの操作を全メッセージブロックに対して行う。
ハッシュ値の出力
|
|
実行すると、以下のようにハッシュを取得できた。
f3bb10e2172099a8a6425ef9c77ccfe5101e440c713e3b8e2362c0d748342af0