結論
先に結論だけ書くと、SHA3(正確にはFIPS-202とされているものに限定するのかもしれない) と Keccak は同じメッセージでも出力が違うので別物であると捉え、各ライブラリがどちらの実装であるかをよくよく確認しないといけない(具体的には、空メッセージを一度関数にかけて確認すべき)。
Keccak とは
Keccak(ケチャック)と呼ばれるハッシュ関数で、後にSHA3として採用される。スポンジ構造と呼ばれる構造を有しており、暗号化は absorb (吸収)
と squeeze (搾取)
という2つのフェーズによって行われるらしいが、詳しい仕組みはよく分かってない。
SHA3 とは
SHA3(シャースリー)は Standard Hash Algorithm 3 の略称で、 SHAシリーズ の3番目のハッシュ関数群という意味を持つ。
このSHAシリーズは FIPS (Federal Information Processing Standards) と呼ばれるアメリカの標準規格の中に定められており、これを発行しているのは NIST (National Institute of Standards Technology) と呼ばれる機関である。
このうち、SHA3はFIPS 202
で定義されており、その中にあるのが SHA3-224
SHA3-256
SHA3-384
SHA3-512
である。(また、これらに加えて SHAKE128
SHAKE256
もある)
ちなみに、SHA2は FIPS 180-4
で標準化されている。
2つの関係
KeccakはSHA3として採用された。なので、 Keccak = SHA3 かと思ってしまうが、実はそうではない。
SHA-3 (FIPS 202) は Keccak を基にして決められた標準の実装群であり、オリジナルの実装からいくつか変更が加えられている。詳しいことは分からないが、そもそもKeccakはパラメータを可変させられるよう設計されているものであり、そのパラメータをいじったのだとか。(これに関しては、あるレベルのセキュリティを求めた上で応募をかけて決めたくせに、標準化の道中で変更するとは何事だと揉めたらしい)
なので、設計レベルで言うとどちらもKeccakということになるのかな?オリジナル実装をKeccakと呼び、SHA3実装はあくまでSHA3と呼ぶべきなんだろうか。割とややこしい。
ともかく結果としては、Keccak-n (original)
と SHA3-n (FIPS 202)
とでは出力されるデータが変わる。下記はそれぞれ ""
(空のメッセージ) をハッシュ化した結果。
Keccak-n
Keccak-224("")
0x f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd
Keccak-256("")
0x c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
Keccak-384("")
0x 2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff
Keccak-512("")
0x 0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e
[https://ja.wikipedia.org/wiki/SHA-3 より引用]
SHA3-n
SHA3-224("")
0x 6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7
SHA3-256("")
0x a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a
SHA3-384("")
0x 0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004
SHA3-512("")
0x a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26
[https://ja.wikipedia.org/wiki/SHA-3 より引用]
SHAKEs
FIPS-202には、SHA3-nの他に、 SHAKE128 と SHAKE256 が定められれている(SHA KEccak)。これらは出力を可変できるハッシュ関数で、それぞれ欲しい強度によって2つを使い分ける。
SHAKE256[32byte]("")
0x 46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f
おまけ : KangarooTwelve
SHAKE同様、出力を可変できるハッシュ関数。KangarooTwelveはKeccakベースで SHA2-FIPS202 , SHAKE よりも高速に動く ことを目指して作られたらしい。同じ出力メッセージ長、同じメッセージでも、出力結果はSHAKEsと違う。
KangarooTwelve[32byte]("")
0x 1ac2d450fc3b4205d19da7bfca1b37513c0803577ac7167f06fe2ce1f0ef39e5
さいごに
地味にこういうことって誰も書いてくれないよね。
参考
[keccak team] https://keccak.team/
[wikipedia] https://ja.wikipedia.org/wiki/SHA-3
[FIPS-202] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
[オンライン暗号ツール] https://emn178.github.io/online-tools/
[KangarooTwelveの速度] https://keccak.team/2017/is_sha3_slow.html
[githubのissueより] https://github.com/status-im/nim-keccak-tiny/issues/1
[変更で揉めた件] https://www.schneier.com/blog/archives/2013/10/will_keccak_sha-3.html