SMLでSHA3を実装しました
SHA(3)はNISTが定めたセキュアなハッシュアルゴリズムの標準規格です。
今回SHA2のSML実装に続きSMLでSHA3を実装し、SHA3SMLとして公開しました。
現在のところSML/NJ 110.99で動作を確認しています。
実装状況
SHA3SMLは直接FIPS 202を確認して実装しました。
以下に対応状況を示します。
SHA3にはSHA2と同じく4つの出力ビット幅によるバリエーションが用意されており、SHA3SMLはこれらには全て対応していますが、SHAKE は未実装です*1。
SHA3-224 | SHA3-256 | SHA3-384 | SHA3-512 | SHAKE128 | SHAKE256 | |
---|---|---|---|---|---|---|
実装 | ✅ | ✅ | ✅ | ✅ |
(SHAKE というのはハッシュ関数ではないものの、他の関数と同じくFIPS202で定義されておりハッシュを一般化したような関数です。)
またNISTは、ある実装がFIPS 202に適合しているかのテスト方法をSHA3VSとして公開しています。ここでは以下のような実装の制限についても定められていますが、SHA3SMLではどれも対応済みです。
✅ 空入力のサポート
✅ バイト指向入力のサポート
✅ ビット指向入力のサポート
インストール方法
ml-makedepends
を使うと依存関係が取得出来ることに気付いたので Makefile を書きました。なので普通に make install
出来ます。
ただし PATHCONFIG ファイルはどこに置くか人によるため Makefile を複雑にするより手動に任せることにしました。
$ make install PREFIX=~/.smlnj (* ..snip.. *) ================================================================ libsha3sml has been installed to: /home/eldesh/.smlnj/lib/libsha3sml.cm Add an entry to your pathconfig (e.g. ~/.smlnj-pathconfig) such like: libsha3sml.cm /home/eldesh/.smlnj/lib/libsha3sml.cm Then you can load the library like "CM.make "$/libsha3sml.cm";". ================================================================
make install
すると上記のようにメッセージが出るので(例えば)以下のように PATHCONFIG ファイルに追記します。
$ echo "libsha3sml.cm /home/eldesh/.smlnj/lib/libsha3sml.cm" >> ~/.smlnj-pathconfig
使い方
いつも通り普通に CM.make
するだけです。
$ sml - CM.make "$/libsha3sml.cm"; (* ..snip.. *) - Sha3.toString (Sha3.hashString Sha3Kind.Sha3_256 ""); val it = "A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A" : string
念のためsha3sumコマンドで確認します。
$ echo -n "" | sha3sum -a 256 | tr [:lower:] [:upper:] A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A -
一致してますね。
テスト
NISTの提供している入出力例と適合試験 CAVP のテストベクタを全てパスすることを確認しています。
手元で実行するには make test
します。
終わりに
SHA3はSHA2に比べて非常に簡単な構造で実装し易かったです。
例えばSHA2には内部的に用いるナゾの数値テーブルがビット幅ごとに用意されているんですが、SHA3にはその類いのマジックナンバーは全くありません。
また規格の文書自体もかなり読みやすく書かれていると思います。
SMLのプロジェクトとしては、NJ向けの Makefile
が書けるようになった点が収穫でした。
これで .cm/
をコピーとかする必要が無いのでユーザとしても*2大分手間が省けます。