なぜか連載形式になってしまったSHA3実装日記です。
といっても、実装が長引いたとかそういうことではなく、ちょっと話題が長くなりそうなので分けただけです。
SHA3がいつの間にか決まっていた
今年の前半には決まるとか言っていたはずなのですが、実際に決まったのは10月の頭だったというのが・・・。
決定してしまえば実装することは決めていたのでいろいろと資料を読みあさって実装に踏み切りました。
アルゴリズムはKeccakと呼ばれる物で、実装にまつわる資料はこのあたりからダウンロードできます。
勉強してみたい方は読んでみると良いと思います。
Wikipediaの方はというと、英語版の方はかなり詳しく書いてありますが、日本語版は「決まった」くらいしか書いてありませんし、
ハッシュにまつわるページにもまだ「決定した」と書いてないページもあって、いろいろと大変だな、と思います。
もちろん、実装例をコピーしたのではいろいろと問題が出る可能性があるので
実装の資料から自前で実装をし直してライブラリに組み込みました。
初めの方は書いてある記号の意味やらなにやら全く意味が分からなかったので一度ノートに定義を書き取ってどういう意味か考えながら進む、と言う作業を行いました。
そのおかげでどういう動きをしているか、と言うのは十分に理解できましたので素直に実装する分にはそれほど苦労はありませんでした。
基本的にアルゴリズムをそのままコードに起こしているので細かい間違いはありましたが、すぐに分かるものがほとんどでした。
動きがちょっと遅い・・・。
本体のページにはちゃんと最適化したコードが置いてあるわけですが、見ても即座に理解できるほどきれいには書いてありません。
で、私の場合は分かるように作成したのですが、どうにも遅い。実装手順書に書いてある速度最適化の指示を見ながらいろいろと実装をいじりましたが、それでもあまり早くありません。
自分の中ではリファレンスのような扱いなので、見やすいコードとそれなりの速度があればあまり気にはしませんが。
それでも少しは速度が速くなるように組み替えています。コンパイラの最適化に負けてしまった部分がかなりあるのでループなどは放置ですが。
なぜかコードを公開してみる
どうせなので私の作成したサンプルコードを公開します。コードはこちらから。
処理そのものは実装手順書にある手順をコードにした物なので見づらいと言うことはあまりないと思います。更新処理なども書いてある通りの組み方しかしていませんので。
一応cryptlibにあるハッシュ計算処理であるMD5Init、MD5Load、MD5Finalのように動くことを前提に組んであります。
名前も似せてSHA3Init、SHA3Load、SHA3Finalで構成されています。初期化関数だけ引数が微妙に違いますが、これはビット数の差を吸収するためにこういう実装になっています。
使う分には本体だけで使用できるので簡単です。
なお、Keccakのページにあるコードには、互換性は弱いですが、KeccakNISTInterface.hというファイルにInit、Update、Final、Hashという4つの関数で計算できるようになっていますので
普通はそちらを使う方がいいと思います。使うためには名前空間的に衝突の可能性が大きいので変更の必要がありますが。