
BLAKE3 v1.8.7
快速的加密哈希函数,支持PRF、MAC、KDF和XOF模式。支持经过验证的流式处理、增量更新以及基于Merkle树结构的并行哈希计算。
BLAKE3
BLAKE3 是一种密码学哈希函数,其特点如下:
- 速度极快,超过 MD5、SHA-1、SHA-2、SHA-3 和 BLAKE2。
- 安全可靠,与 MD5 和 SHA-1 不同。并且能够抵抗长度扩展攻击,与 SHA-2 不同。
- 高度可并行化,可在任意数量的线程和 SIMD 通道上运行,因为它内部采用 Merkle 树结构。
- 支持验证流式处理和增量更新,同样得益于其 Merkle 树结构。
- 可作为PRF、MAC、KDF、XOF 以及常规哈希使用。
- 单一算法,无变体,在 x86-64 以及更小架构上均表现快速。
下图 是 2019 年 Cascade Lake-SP 8275CL 服务器 CPU 上对 16 KiB 输入进行基准测试的示例。详细的基准测试结果请参阅 BLAKE3 论文。
BLAKE3 基于成熟哈希函数 BLAKE2 的优化实例以及 原始 Bao 树模式。其规范和设计原理详见 BLAKE3 论文。默认输出大小为 256 位。当前版本的 Bao 实现了基于 BLAKE3 的验证流式处理。
此仓库是 BLAKE3 的官方实现,包含:
-
blake3Rust crate,包含针对 SSE2、SSE4.1、AVX2、AVX-512、NEON 和 WASM 的优化实现,并在 x86 上实现了自动运行时 CPU 特性检测。rayon特性提供了多线程支持。 -
b3sumRust crate,提供命令行界面。默认使用多线程,在典型桌面硬件上比例如sha256sum快一个数量级。 -
C 实现,与 Rust 实现一样包含 SIMD 优化(除 WASM 外)、x86 上的 CPU 特性检测以及可选的多线程支持。详见
c/README.md。 -
Rust 参考实现,在 BLAKE3 论文 第 5.1 节中讨论。该实现比上述优化实现更小、更简单。如果你想了解 BLAKE3 的工作原理,或者正在编写不需要多线程或 SIMD 优化的移植版本,建议从这里开始。参考实现的其他语言移植版本托管在独立的仓库中(C、Python)。
-
一组测试向量,涵盖扩展输出、所有三种模式以及各种输入长度。
BLAKE3 由以下人员设计:
- @oconnor663(Jack O'Connor)
- @sneves(Samuel Neves)
- @veorq(Jean-Philippe Aumasson)
- @zookozcash(Zooko)
BLAKE3 的开发由 Electric Coin Company 赞助。
BLAKE3 也已在社区密码学规范项目(C2SP)中进行规范。
注意:BLAKE3 不是密码哈希算法,因为它设计为快速,而密码哈希不应快速。如果你对密码进行哈希存储或从密码派生密钥,建议使用 Argon2。
用法
b3sum 工具
b3sum 命令行工具用于打印文件或标准输入的 BLAKE3 哈希值。预构建的二进制文件适用于 Linux、Windows 和 macOS(需要解决未识别开发者问题),可在发布页面获取。如果你已安装 Rust 和 Cargo,也可以通过以下命令自行构建 b3sum:
cargo install b3sum
如果 rustup 没有为你配置 PATH,你可能需要手动查找安装的二进制文件,例如在 ~/.cargo/bin 目录下。你可以通过创建一个大文件并计算其哈希值来测试 BLAKE3 在你的机器上的速度,例如:
# 创建一个 1 GB 的文件。
head -c 1000000000 /dev/zero > /tmp/bigfile
# 使用 SHA-256 计算哈希。
time openssl sha256 /tmp/bigfile
# 使用 BLAKE3 计算哈希。
time b3sum /tmp/bigfile
blake3 crate 
要在 Rust 代码中使用 BLAKE3,请将 blake3 crate 添加为依赖项到你的 Cargo.toml。以下是一个对输入字节进行哈希的示例:
// 一次性哈希输入。
let hash1 = blake3::hash(b"foobarbaz");
// 增量式哈希输入。
let mut hasher = blake3::Hasher::new();
hasher.update(b"foo");
hasher.update(b"bar");
hasher.update(b"baz");
let hash2 = hasher.finalize();
assert_eq!(hash1, hash2);
// 扩展输出。OutputReader 也实现了 Read 和 Seek。
let mut output = [0; 1000];
let mut output_reader = hasher.finalize_xof();
output_reader.fill(&mut output);
assert_eq!(hash1, output[..32]);
// 将哈希值以十六进制格式打印。
println!("{}", hash1);
除了 hash,BLAKE3 还提供另外两种模式:keyed_hash 和 derive_key。keyed_hash 模式接受一个 256 位的密钥:
// 一次性进行 MAC 计算。
let example_key = [42u8; 32];
let mac1 = blake3::keyed_hash(&example_key, b"example input");
// 增量式 MAC 计算。
let mut hasher = blake3::Hasher::new_keyed(&example_key);
hasher.update(b"example input");
let mac2 = hasher.finalize();
assert_eq!(mac1, mac2);
derive_key 模式接受一个上下文字符串和密钥材料(不是密码)。上下文字符串应为硬编码、全局唯一且与应用相关的。推荐的上下文字符串格式为 "[application] [commit timestamp] [purpose]":
// 为不同目的派生多个子密钥。
const EMAIL_CONTEXT: &str = "BLAKE3 example 2020-01-07 17:10:44 email key";
const API_CONTEXT: &str = "BLAKE3 example 2020-01-07 17:11:21 API key";
let input_key_material = b"usually at least 32 random bytes, not a password";
let email_key = blake3::derive_key(EMAIL_CONTEXT, input_key_material);
let api_key = blake3::derive_key(API_CONTEXT, input_key_material);
assert_ne!(email_key, api_key);
C 实现
详见 c/README.md。
其他实现
现有的实现数量众多,我们难以全部跟踪,但一些亮点包括:优化的 Go 实现、用于 Node.js 和浏览器的 Wasm 绑定、Python 的二进制 wheel、.NET 绑定 以及 纯 Java 实现。
贡献
请参阅 CONTRIBUTING.md。
许可
本项目以 CC0 1.0 发布到公共领域。或者,你也可以选择以下任意许可证:
采用与部署
- Bazel
- Cargo
- Ccache
- Chia
- Clickhouse
- Farcaster
- IPFS
- Iroh
- LLVM
- Nix
- Nym
- OpenZFS
- Redox
- Solana
- Tekken 8
- Wasmer
其他
- @veorq 和 @oconnor663 接受了 Cryptography FM 的采访。
- @oconnor663 接受了 Saito 的采访。