先だってNISTにより選定された SHA-3(Keccak)を「アタッシェケース」への実装の検討と、テストをしています。
ソースコードは以下にあり、
http://keccak.noekeon.org/files.html
今日時点での最新は、
Reference and optimized code in C
Version 3.2
となっているようです。
そこから必要なファイルを C++Builder 2010 のプロジェクトに追加して、正しい値を返すかテストしました。結論から言うと、うまくインプリメントできました。
こんな感じです。
その成果は、プロジェクトファイル一式としてGitHubにアップロードしておきます。
https://github.com/hibara/KeccakTest
ライセンスはGPLv3ライセンスとします。ご自由にどうぞ。
ソースはダウンロードして、C++Builder 2010 以降で読み込んでビルドすれば動くと思います。
とはいえ、ちょっとはまったので、補足としてここでメモしておきます。
おそらく一番シンプルに実装するには、以下のNIST用Interfaceのヘッダから使うのが良いでしょう。「Sources」フォルダーの中にある、
KeccakNISTInterface.h
です。
これをインクルードすると、SHA-1やMD5でやっていた流れでハッシュ値を出すことができますし、ソースを流用できます。
ただ、中身を見ると以下のように関数名がシンプルすぎて、C++Builder上では名前の衝突が起きます。
[cpp]
HashReturn Init(hashState *state, int hashbitlen);
HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen);
HashReturn Final(hashState *state, BitSequence *hashval);
HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval);
[/cpp]
ですので、僕の場合は、
[cpp]
#ifdef __cplusplus
extern "C" { // ←これも忘れずに
#endif
HashReturn KeccakInit(hashState *state, int hashbitlen);
HashReturn KeccakUpdate(hashState *state, const BitSequence *data, DataLength databitlen);
HashReturn KeccakFinal(hashState *state, BitSequence *hashval);
HashReturn KeccakHash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval);
#ifdef __cplusplus
}
#endif
[/cpp]
などと、関数名のリネームしています。
次に、出力できるbitオプションは以下の通りです。
これらの指定は、Initのときに引数として与えます。
なお、ソース冒頭の BitSequence result[64]; は最大の512bitを格納できるよう、多めにとってあるので、ここは32バイトでもかまいません。
ここでの例は、256bitで指定されていますが、GitHubに上げているものは変数指定となっています。
[cpp]
// Keccak result
BitSequence result[64]; //256bitなら32バイトでO.K.
// result hex string
char hashval[1024];
for (int i = 0; i < 1024; i++){
hashval[i] = NULL;
}
// Keccak return value
HashReturn ret;
// Keccak hash state structure
hashState st;
if ( (ret = KeccakInit(&st, 256)) != 0 ){
KeccakUpdate(&st, Edit1->Text.t_str(), Edit1->Text.Length()*8); // ←ビット! KeccakFinal(&st, result);
//文字列として出力する
BinToHex( result, hashval, 256);
return((String)hashval));
}
[/cpp]
このソースでの注意点は、Update関数のサイズ指定が“ビット”であること。ここを「バイト」にしていて小一時間ほど悩みました。まあ、元のソースコードにあるコメントアウトをよく読めってことなんですが・・・
ちなみに、ファイルの場合は、ほとんどSHA-1などの処理と変わりません。Updateにどんどん読み込んだバッファを詰め込んで、終わったらFinalで結果を出力する、という流れです。こちらはGitHubのコードを参照ください。
引き続きテストを続けます。
もしソース上で何かあれば、GitHub上からでもかまいませんので、ご一報くださると幸いです。
このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください。
日々の開発作業で気づいたこと共有を。同じところで躓いている人が、 検索で辿り着けたら良いな、というスタンスで記事を書くので不定期更新になります。
コメントする