SHA-256の実装 in Python


SHA-256 を計算してみようと思いました。 https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf にアルゴリズムについての説明があったので、これを頼りに実装しました。

環境

  • Python 3.10

用語

先に、 SHA-256 の計算の中で使われる用語を確認しておきましょう。

hex digit

16 bit の数値で、 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e を指します。 hex digit は 0 または 1 からなる 4文字(4 bit)の文字列で表すことができます。 0010, 1001 は hex digit です。

word, w-bit string
hex digit をいくつか並べたものです。 “abcdef”, “014d23e” などは word です。 SHAの計算で使用する word は、 ビッグエンディアンを使用します。 SHA-256 での ワードサイズ は 32 bit です。

実装手順

上のドキュメントを上から順に実装していくとわかりやすいとは思いますが、足りないものを順次追加するときに、前に実装した関数に戻る必要がありますので、ここではできるだけ整理した形で記述します。 速度や効率の点は重視せず、組み込み関数もできるだけ使わないようにしたので、改善できる部分は結構あります。 下のステップで実装すると sha-256 を生成する関数を実装できます。 (コードは載せていますが、コード自体の説明はあまりしていません。)

  1. 数値計算関数の実装
  2. 変換関数の実装
  3. ビット演算の実装
  4. SHA-256の計算

コード全体は Gist にもあります。

SHA-256 のパラメータ

実装時に使用したSHA-256のパラメータをまとめておきます。

項目 ビットサイズ バイトサイズ
ブロック 512 64
ワード 32 4
ハッシュ値 256 32