SHAの仕様と実装比較(SHA-512編)

前々回はSHA-1前回はSHA-256の仕様と実装について比較したので、今回はSHA-512について比較してみようと思います。

今回の比較に使用するソースコードは、前回同様、GitHubにあるopensslのソースコードを使用しました。その中の、crypto/sha/sha512.cです。

念のため、FIPS 180-4のリンクも置いておきます。

SHAの共通点やWordの操作については、SHA-1編を参照してください。

SHA-512の仕様と実装の比較

1.ブロックサイズやWordサイズ

SHA-512のブロックサイズは1024bits、Wordサイズは64bitsです。
各ブロックは16個の64bitに分けられて処理されます。

2.ハッシュの初期値

FIPS 180-4で記述されているSHA-512の初期値は以下です。
SHA-512_initial_value

crypto/sha/sha512.cに設定されている値と一致します。

 81 int SHA512_Init(SHA512_CTX *c)
 82 {
 83     c->h[0] = U64(0x6a09e667f3bcc908);
 84     c->h[1] = U64(0xbb67ae8584caa73b);
 85     c->h[2] = U64(0x3c6ef372fe94f82b);
 86     c->h[3] = U64(0xa54ff53a5f1d36f1);
 87     c->h[4] = U64(0x510e527fade682d1);
 88     c->h[5] = U64(0x9b05688c2b3e6c1f);
 89     c->h[6] = U64(0x1f83d9abfb41bd6b);
 90     c->h[7] = U64(0x5be0cd19137e2179);
 91
 92     c->Nl = 0;
 93     c->Nh = 0;
 94     c->num = 0;
 95     c->md_len = SHA512_DIGEST_LENGTH;
 96     return 1;
 97 }

3.定数

FIPS 180-4で記述されているSHA-512の定数は以下です。
SHA-512_constants

80個の64bitの定数を使用します。これらはSHA-384、SHA-512/224、SHA-512/256でも同じ値を使用するようです。

crypto/sha/sha512.cでも同じ値が設定されています。

279 static const SHA_LONG64 K512[80] = {
280     U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd),
281     U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc),
282     U64(0x3956c25bf348b538), U64(0x59f111f1b605d019),
283     U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118),
284     U64(0xd807aa98a3030242), U64(0x12835b0145706fbe),
285     U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2),
286     U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1),
287     U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694),
288     U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3),
289     U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65),
290     U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483),
291     U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5),
292     U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210),
293     U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4),
294     U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725),
295     U64(0x06ca6351e003826f), U64(0x142929670a0e6e70),
296     U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926),
297     U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df),
298     U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8),
299     U64(0x81c2c92e47edaee6), U64(0x92722c851482353b),
300     U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001),
301     U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30),
302     U64(0xd192e819d6ef5218), U64(0xd69906245565a910),
303     U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8),
304     U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53),
305     U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8),
306     U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb),
307     U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3),
308     U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60),
309     U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec),
310     U64(0x90befffa23631e28), U64(0xa4506cebde82bde9),
311     U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b),
312     U64(0xca273eceea26619c), U64(0xd186b8c721c0c207),
313     U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178),
314     U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6),
315     U64(0x113f9804bef90dae), U64(0x1b710b35131c471b),
316     U64(0x28db77f523047d84), U64(0x32caab7b40c72493),
317     U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c),
318     U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a),
319     U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817)
320 };

4.関数

FIPS 180-4で記述されているSHA-512の関数は以下です。
SHA-512_functions

SHA-256と非常によく似ていますが、SHA-512のWordサイズが64bitだという点には注意が必要です。

crypto/sha/sha512.cでは以下のように定義されています。

404 # ifndef ROTR
405 #  define ROTR(x,s)       (((x)>>s) | (x)<<(64-s))
406 # endif
407 # define Sigma0(x)       (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
408 # define Sigma1(x)       (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
409 # define sigma0(x)       (ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
410 # define sigma1(x)       (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
411 # define Ch(x,y,z)       (((x) & (y)) ^ ((~(x)) & (z)))
412 # define Maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))

SHA-512の場合は、ROTRに渡す値がFIPS 180-4に記述されている通りに実装されていることが分かります。

5.メッセージスケジュールの生成

FIPS 180-4で記述されているSHA-512のメッセージスケジュールの生成方法は以下です。
SHA-512_message_schedule

σ関数の中身やラウンド数が違いますが、形自体はSHA-256の時とよく似ています。

crypto/sha/sha512.cでは以下のように定義されています。

497         for (i = 0; i < 16; i++) {
498 #  ifdef B_ENDIAN
499             T1 = X[i] = W[i];
500 #  else
501             T1 = X[i] = PULL64(W[i]);
502 #  endif
...(中略)...
515         for (; i < 80; i++) {
516             s0 = X[(i + 1) & 0x0f];
517             s0 = sigma0(s0);
518             s1 = X[(i + 14) & 0x0f];
519             s1 = sigma1(s1);
520
521             T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf];

SHA-256の時の同じように、iが16まではそのままの値を使用し、16から80までは0xfとマスクを取った位置にある要素からWtを算出しています。その際に使用する要素は、0xfを法として合同な位置にある要素である点には注意が必要です。

6.ハッシュ値の計算

FIPS 180-4に記述されている方法は、以下です。
SHA-512_computing

crypto/sha/sha512.cの該当部分は以下です。

497         for (i = 0; i < 16; i++) {
498 #  ifdef B_ENDIAN
499             T1 = X[i] = W[i];
500 #  else
501             T1 = X[i] = PULL64(W[i]);
502 #  endif
503             T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i];
504             T2 = Sigma0(a) + Maj(a, b, c);
505             h = g;
506             g = f;
507             f = e;
508             e = d + T1;
509             d = c;
510             c = b;
511             b = a;
512             a = T1 + T2;
513         }
514
515         for (; i < 80; i++) {
516             s0 = X[(i + 1) & 0x0f];
517             s0 = sigma0(s0);
518             s1 = X[(i + 14) & 0x0f];
519             s1 = sigma1(s1);
520
521             T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf];
522             T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i];
523             T2 = Sigma0(a) + Maj(a, b, c);
524             h = g;
525             g = f;
526             f = e;
527             e = d + T1;
528             d = c;
529             c = b;
530             b = a;
531             a = T1 + T2;
532         }

こちらもSHA-256の時と同じように、iが16まで処理と16から80までの処理では、メッセージスケジュールを生成している部分だけが異なりますが、その他は全て同じです。
SHA-512も、FIPS 180-4のアルゴリズムがそのままの形で実装されています。
SHA-256同様、変数のdからe、hからaに移る時に値が変っていくイメージです。

最後に64bitの8つの変数の値を並べることで、512bitのメッセージダイジェストが得られます。

以上がSHA-512の仕様とその実装の比較でした。

これまでSHA-1、SHA-256、SHA-512の仕様と実装を比較してきて、今まではブラックボックスでしかなかったSHAを詳しく把握することができました。
これらの一連の記事がどなたかの理解の役に立てば幸いです。
 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*