SHA-3 のコンペで最終選考まで残って Keccak に負けた BLAKE2。その後継である BLAKE3 が「爆速らしい。しかも FNV1a より数倍」と聞いたので試してみたい。
でも公式は Rust と C 言語での実装なのです。どちらも話せません ... 最近勉強している Go 言語(以下 Golang)で試してみたかったのです。
-
BLAKE3 | BLAKE3-team @ GitHub
- BLAKE3 の仕様書: BLAKE3 Specs @ GitHub
- 関連記事:
TL; DR (今北産業)
- 16 バイト長ハッシュで速い FNV1 より、64 バイト長ハッシュの BLAKE3 の方が 8 倍以上速かった。😱
- 試したライブラリ(どちらも BLAKE 非公式):
-
BLAKE3 for Go - Luke Champine バージョン
go get lukechampine.com/blake3
-
BLAKE3 for Go - Zeebo バージョン
go get github.com/zeebo/blake3
- 実測結果: Zeebo の方が Luke より平均して若干速いがほぼ同じ。
- 使いやすさ: Luke 版の方はシンプルで使いやすいが、Zeebo の方が hash.Hash のインターフェースを基準にしていたり、ドキュメントが充実しているため、他のハッシュ関数との入れ替えがしやすい。
-
BLAKE3 for Go - Luke Champine バージョン
- 本家も強度の検証が終わっていないらしい + Golang 版 BLAKE3 もベータ版なのでプロダクション・レベルではまだ使わない方がいいかもしれない。改ざん検知目的よりチェックサム目的なら十分実用的で速い。
TS; DR
サンプル・コード
Luke Champine バージョンの使い方
シンプル(小さなデータ向け)
/* import "lukechampine.com/blake3" */
input := "This is a string"
valByte := blake3.Sum256([]byte(input))
// Expect value was taken from R implementation: https://github.com/dirkschumacher/blake3
expect := "718b749f12a61257438b2ea6643555fd995001c9d9ff84764f93f82610a780f2"
actual := fmt.Sprintf("%x", valByte)
fmt.Println("expect:", expect)
fmt.Println("actual:", actual)
// Output:
// expect: 718b749f12a61257438b2ea6643555fd995001c9d9ff84764f93f82610a780f2
// actual: 718b749f12a61257438b2ea6643555fd995001c9d9ff84764f93f82610a780f2
ファイルまるごとなどメモリ消費しそうな場合
/* import "lukechampine.com/blake3" */
input := "This is a string"
h := blake3.New(256, nil)
// 本来は、ここでファイルからのデータをループで書き込む
if _, err := h.Write([]byte(input)); err != nil {
log.Fatalf("failed to write data. Err: %v", err)
}
valByte := h.Sum(nil)[:32] // 512bit で返ってくるので必要なぶん32バイト
// Expect value was taken from R implementation: https://github.com/dirkschumacher/blake3
expect := "718b749f12a61257438b2ea6643555fd995001c9d9ff84764f93f82610a780f2"
actual := fmt.Sprintf("%x", valByte)
fmt.Println("expect:", expect)
fmt.Println("actual:", actual)
// Output:
// expect: 718b749f12a61257438b2ea6643555fd995001c9d9ff84764f93f82610a780f2
// actual: 718b749f12a61257438b2ea6643555fd995001c9d9ff84764f93f82610a780f2
ベンチマーク
- アルゴリズム:
- Adler (32bit)
- BLAKE3 Luke Ver. (256bit, 512bit)
- BLAKE3 Zeebo Ver. (256bit, 512bit)
- CRC32 (32bit)
- FNV-1 (32bit)
- FNV-1a (32bit)
- MD5 (128bit)
- MMH3 (128bit)
- SHA-2 (256bit, 512bit)
- SHA-3 (256bit, 512bit)
- Whirlpool (512bit)
- 10秒間のイテレーション(処理)✖︎2回(iter が大きいほど多く処理 = time/iter が小さいほど処理が短い)
- ベンチマークのソース @ GitHub
- 最新のベンチ結果 @ GitHub