BLAKE3
设计者
Jack O'Connor
Jean-Philippe Aumasson
BLAKE3 是 2020 年发布的 BLAKE 系列最新版本,由 Jack O'Connor 和 Jean-Philippe Aumasson 设计。BLAKE3 的核心创新是原生树形哈希,可以充分利用多核 CPU 实现并行计算,单线程速度达到 ~7 GB/s,多线程可线性加速。BLAKE3 是一个"多合一"的密码学原语,同时支持哈希、MAC、KDF 和可扩展输出。
设计哲学
BLAKE3 的设计遵循一个核心原则:简单就是安全。与 BLAKE2 通过减少轮数来优化性能不同,BLAKE3 采用了更激进的简化策略:
- 更少的轮数:仅 7 轮(BLAKE2b 为 12 轮),通过更宽的内部状态保证安全性
- 统一的结构:一个算法支持所有用途,无需为不同场景选择不同变体
- 原生并行:从设计之初就考虑并行性,而不是事后添加
关键突破:BLAKE3 是第一个在单线程性能上与非密码学哈希(如 xxHash、MurmurHash)相当的密码学哈希函数。这打破了"密码学哈希必然慢"的传统认知。
核心结构:简化海绵
BLAKE3 使用简化的海绵结构(simplified sponge),与 BLAKE/BLAKE2 的 HAIFA 结构不同:
BLAKE3 海绵结构:
状态 = 16 × 32 位 = 512 位内部状态
每个输入块:
状态 = 压缩函数(状态, 块)
输出:
从状态中提取 256 位
与 BLAKE2 的区别
| 特性 | BLAKE2 | BLAKE3 |
| 结构 | HAIFA | 简化海绵 |
| 轮数 | 10/12 轮 | 7 轮 |
| 内部状态 | 256/512 位 | 512 位(固定) |
| 并行支持 | 可选(bp/sp) | 原生支持 |
| 输出长度 | 1~512 位 | 256 位 + 可扩展 |
| 变体 | 6 种 | 1 种 |
压缩函数
BLAKE3 的压缩函数是 ChaCha 的进一步简化版本,保留了 ChaCha 的核心特性(高扩散性、高效实现),但减少了轮数:
BLAKE3 压缩函数:
compress(chaining_value, block, counter, flags):
# 初始化 16 个 32 位工作变量
state[0..3] = chaining_value[0..3] # 来自父节点
state[4..7] = chaining_value[4..7] # 来自父节点
state[8..11] = IV[0..3] # 初始化向量
state[12] = counter_low # 计数器低 32 位
state[13] = counter_high # 计数器高 32 位
state[14] = block_len # 块长度
state[15] = flags # 标志位
# 7 轮压缩(比 BLAKE2 少 5 轮)
for round in 0..6:
# 列混合(4 次 G 函数调用)
G(state, 0, 4, 8, 12)
G(state, 1, 5, 9, 13)
G(state, 2, 6, 10, 14)
G(state, 3, 7, 11, 15)
# 对角线混合(4 次 G 函数调用)
G(state, 0, 5, 10, 15)
G(state, 1, 6, 11, 12)
G(state, 2, 7, 8, 13)
G(state, 3, 4, 9, 14)
# 输出:前半部分异或后半部分
return state[0..7] ^ state[8..15]
G 函数
BLAKE3 的 G 函数与 BLAKE2 基本相同,但使用固定的轮常量:
G(state, a, b, c, d):
state[a] += state[b] + m[0] # m[0] 是消息字
state[d] = rot(state[d] ^ state[a], 16)
state[c] += state[d]
state[b] = rot(state[b] ^ state[c], 12)
state[a] += state[b] + m[1] # m[1] 是消息字
state[d] = rot(state[d] ^ state[a], 8)
state[c] += state[d]
state[b] = rot(state[b] ^ state[c], 7)
树形哈希
BLAKE3 的核心创新是原生树形哈希。与传统哈希函数的顺序处理不同,BLAKE3 将输入分成多个块,每个块可以独立计算,然后通过树结构合并结果:
传统哈希(顺序处理):
[块1] → [块2] → [块3] → [块4] → ... → 哈希值
(无法并行,必须等待前一个块完成)
BLAKE3 树形哈希(并行处理):
输入数据
├── [块1] → CV1 ─┐
├── [块2] → CV2 ─┤
├── [块3] → CV3 ─┼→ 合并 → ... → 哈希值
├── [块4] → CV4 ─┤
└── ...
(所有块可以并行计算!)
CV = Chaining Value(链接值)
树结构详解
BLAKE3 的树是一个二叉树,每个叶子节点是一个 1024 字节的块(chunk),每个内部节点合并两个子节点的输出:
BLAKE3 树结构:
根节点(最终输出)
/ \
左子树 右子树
/ \ / \
CV1 CV2 CV3 CV4
| | | |
块1 块2 块3 块4
每个块(chunk)的处理:
块 = 16 × 64 字节 = 1024 字节
对每个 64 字节的子块执行压缩函数
输出该块的 CV(Chaining Value)
合并节点:
CV_parent = compress(CV_left || CV_right)
并行计算
树形结构使得 BLAKE3 可以充分利用多核 CPU:
- 线程数 = 核心数:每个核心处理一个或多个块
- 线性加速:4 核 CPU 可以获得接近 4 倍的速度提升
- 内存效率:每个线程只需要处理自己的块,无需共享状态
并行计算示例(4 核 CPU):
线程 1: 处理块 1-250 → CV1-250
线程 2: 处理块 251-500 → CV251-500
线程 3: 处理块 501-750 → CV501-750
线程 4: 处理块 751-1000 → CV751-1000
↓
合并层: CV1-250 + CV251-500 + CV501-750 + CV751-1000
↓
最终哈希值
多合一设计
BLAKE3 通过标志位(flags)实现多种用途,无需为每种用途创建不同的变体:
| 用途 | 标志位 | 说明 |
| 普通哈希 | CHUNK_START | CHUNK_END | 标准哈希计算 |
| 密钥哈希(MAC) | KEYED_HASH | 使用密钥计算 MAC |
| 密钥派生(KDF) | DERIVE_KEY | 从上下文派生密钥 |
| 可扩展输出(XOF) | EXTENDABLE_OUTPUT | 生成任意长度输出 |
密钥哈希(MAC)
BLAKE3-Keyed(key, message):
# 将密钥作为第一个块的输入
第一个块 = key || 0...0
flags = KEYED_HASH
return BLAKE3(第一个块 || message, flags)
密钥派生(KDF)
BLAKE3-DeriveKey(context, key_material):
# 上下文字符串作为个性化输入
context_hash = BLAKE3(context, flags=DERIVE_KEY_CONTEXT)
# 使用上下文哈希作为密钥派生密钥
return BLAKE3-Keyed(context_hash, key_material)
可扩展输出(XOF)
BLAKE3-XOF(message, output_length):
# 生成任意长度的输出
输出 = []
counter = 0
while len(输出) < output_length:
输出 += BLAKE3(message, counter, flags=EXTENDABLE_OUTPUT)
counter += 1
return 输出[:output_length]
为何仅 7 轮就足够安全
BLAKE3 将轮数从 BLAKE2 的 12 轮减少到 7 轮,这看似激进,但有充分的安全依据:
更宽的内部状态
BLAKE3 使用 512 位内部状态(16 × 32 位),比 BLAKE2b 的 512 位相同,但 BLAKE3 的状态利用率更高:
- 每轮执行 8 次 G 函数,每次混合 4 个状态变量
- 每轮覆盖所有 16 个状态变量
- 7 轮 × 8 次 = 56 次 G 函数调用,提供了足够的扩散
安全性分析
BLAKE3 的设计者进行了详细的安全性分析:
- 差分攻击:7 轮的差分概率远低于 2^{-128},提供了足够的安全余量
- 线性攻击:线性逼近的概率同样远低于安全阈值
- 相关密钥攻击:树形结构的密钥隔离特性有效抵抗此类攻击
安全余量:BLAKE3 的最佳已知攻击仅能攻击到 2.5 轮,而 BLAKE3 有 7 轮,提供了 4.5 轮的安全余量。这与 BLAKE2 的安全余量相当。
性能对比
| 算法 | 单线程速度 | 多线程加速 | 安全性 | 用途 |
| BLAKE3 | ~7.0 GB/s | 线性加速 | 安全 | 通用哈希 |
| BLAKE2b | ~3.5 GB/s | 有限 | 安全 | 64 位平台 |
| SHA-256 | ~1.8 GB/s | 不支持 | 安全 | 标准合规 |
| SHA-3 | ~1.5 GB/s | 不支持 | 安全 | 标准合规 |
| xxHash64 | ~8.0 GB/s | 不支持 | 非密码学 | 校验和 |
应用场景
- 文件校验:大文件的完整性校验,充分利用多核 CPU
- 内容寻址:IPFS、Git 等内容寻址系统
- 数据去重:备份工具、存储系统
- 密码学协议:TLS、Signal 等协议的哈希计算
- 区块链:Merkle 树构建
实现与使用
# Rust
use blake3;
let hash = blake3::Hasher::new()
.update(b"hello world")
.finalize();
# Python
import blake3
hash = blake3.blake3(b"hello world").hexdigest()
# Go
import "github.com/zeebo/blake3"
hash := blake3.Sum256([]byte("hello world"))
# 命令行
echo -n "hello world" | b3sum
BLAKE 系列演进
| 版本 | 年份 | 核心改进 | 性能提升 |
| BLAKE | 2008 | 基于 ChaCha,HAIFA 结构 | 基准 |
| BLAKE2 | 2012 | 减少轮数,工程优化 | ~1.5x |
| BLAKE3 | 2020 | 树形哈希,7 轮,多合一 | ~2x(单线程) ~Nx(多线程) |
参考文献
- O'Connor, J., Aumasson, J.-P. (2020). "BLAKE3: one function, fast everywhere". blake3.io.
- Aumasson, J.-P., Neves, S., Wilcox-O'Hearn, Z., Winnerlein, C. (2013). "BLAKE2: simpler, smaller, fast as MD5". SAC 2013.
- Aumasson, J.-P., Henzen, L., Meier, W., Phan, R.C.-W. (2008). "SHA-3 proposal BLAKE". NIST SHA-3 Competition.
- Bernstein, D.J. (2008). "ChaCha, a variant of Salsa20". Workshop Record of SASC.