Keccak-f1600 置换加速:CANN Crypto 如何批量处理 1600 位状态
【免费下载链接】cryptocrypto SIG 是密码学兴趣小组,围绕昇腾 NPU 打造高性能密码软件库,提供丰富的密码算子与算法实现项目地址: https://gitcode.com/cann/crypto
CANN crypto 是面向昇腾 NPU 的开源密码软件库,其中的 KeccakF1600Tensor 算子专门解决 Keccak-f1600 置换的批量加速问题:一次调用即可在 NPU 上对多达 8192 个 1600 位状态同时执行 24 轮置换,为 SHA-3、SHAKE 等哈希算法提供高速的底层原语。
为什么需要 Keccak-f1600 批量算子?
Keccak-f[1600] 是 SHA-3 与 SHAKE 家族哈希算法的核心置换函数:它把 1600 位状态(5×5 网格、共 25 条 64 位 lane)反复打乱 24 轮,每轮包含 θ、ρ、π、χ、ι 五个子步骤。
CPU 上一次只能处理一个状态,而 NPU 的优势在于大规模并行。CANN Crypto 的 keccak/ 模块把"批量置换"封装成标准 ACLNN 算子 aclnnKeccakF1600Tensor,让上万个状态像张量一样喂给向量单元同时计算。
💡 注意:该算子只做置换本身,不含消息吸收、填充(padding)和输出挤出,需要完整哈希语义时可组合使用或参考 shake/ 等上层实现。
算子长什么样:[50, B]张量约定
算子把"多个状态"压进一张二维 UINT32 张量,输入输出形状均为[50, B]:
| 维度 | 含义 |
|---|---|
| 第 1 维(50 行) | 25 条 64 位 lane,每条拆成低 32 位、高 32 位各占一行,lane = u + 5v |
| 第 2 维(B 列) | 批内 B 个状态,沿行方向连续存放 |
这种"一行一个 32 位半字"的排布是关键技巧之一:Ascend 向量单元天然以 32 位字为处理粒度,把 64 位 lane 拆成两半后,每条 lane 的低位、高位都能被向量指令整组处理,无需跨字进位拼接。完整数据布局说明见 README,接口细节见 docs/aclnnKeccakF1600Tensor.md。
NPU 上的批量加速技巧
分块并行:256 个状态一个 tile
Kernel 按 tile 切分批量数据,每个 tile 固定 256 个状态(常量TILE,见 keccak_f1600_u32_vector.h)。所有 AI Core 按blockIdx起始、blockNum步长认领 tile,循环直到整批处理完毕——分块逻辑见 keccak_f1600_tensor.h 的Process。
主机侧的 Tiling 函数 会算出 tile 总数,并与芯片 AIV 核数取小,决定实际并行的 block 数;B 最大 8192,对应最多 32 个 tile。
向量单元逐 lane 并行
每一轮置换的 25 条 lane 都被展开成 50 个 32 位"slot",在向量单元(V 核)上用Xor、And、Or、ShiftLeft/ShiftRight等整组指令对 B 个状态一次性完成,例如 64 位循环左移被拆成"低字左移 + 高字右移 31 位再或合"的向量操作(RotlLaneTo,keccak_f1600_u32_vector.h)。
所有中间量都驻留在本地统一缓冲区中(共 126 个 slot:状态 50 + B/C/D 临时区 + 旋转暂存区),避免反复访问片外内存,这是批量场景下吞吐量的主要来源。
24 轮置换的五步拆解
Round函数(keccak_f1600_u32_vector.h)严格按密码标准实现每轮的五个子步骤:
- θ(列奇偶):按列异或出 C 值,高低 32 位各自独立累加
- ρ+π(旋转+置换):25 条 lane 的旋转量与目标位置在编译期静态展开为 25 条直接调用,省掉运行时的旋转表索引
- χ(非线性):采用等价式
B[x] ^ B[x+2] ^ (B[x+1] & B[x+2]),复用 θ 阶段用过的 C、D 槽位 - ι(轮常量):仅对第一个 lane 异或 24 个固定 64 位常量
RC[round]
每轮结束状态原地更新,24 轮后整批状态即完成置换(Permute24)。
如何调用:两步式 ACLNN 流程
调用遵循标准两段式:先 aclnnKeccakF1600TensorGetWorkspaceSize 查询工作空间并生成 executor,再调aclnnKeccakF1600Tensor把计算提交到 ACL 流。约束要点:
1 ≤ B ≤ 8192,输入输出形状一致且互不重叠,不支持原地计算- 设备验证使用 CANN 9.1.0,支持 Atlas A2(
ascend910b)与 A3(ascend910_93) - 同步完成前不得释放张量与工作空间
完整可运行示例见 test_aclnn_keccak_f1600_tensor.cpp,配套的 acl_example.h 封装了流、缓冲区与张量管理,几十行即可完成一次批量置换并校验全零初态的结果(首 lane 应为0xf1258f7940e1dde7)。
验证:从纯 C 参考到设备实测
算子正确性由多层测试保障,详见 tests/README.md:
| 层级 | 内容 |
|---|---|
| golden.py | Python 独立置换实现 + 全零初态已知答案 |
| sha3_ref.c | 纯 C 参考实现,仅参与测试 |
| test_permutation.cpp | 928 个状态比对生产置换头与参考算术模型 |
| test_aclnn_keccak.cpp | ACLNN 设备结果与纯 C 参考逐字节对比,覆盖 batch = 64/256/1024/4096/8192 |
相关文件导航 📂
- 接口文档:aclnnKeccakF1600Tensor.md
- 算子定义 / 形状推导 / Tiling:op_host/
- Kernel 与向量化置换:keccak_f1600_tensor.cpp、keccak_f1600_u32_vector.h
- 示例与测试:examples/、tests/
一句话总结:CANN Crypto 通过"[50, B]张量布局 + 256 状态分块 + 32 位半字向量指令"三板斧,把原本串行的 1600 位置换变成了 NPU 上可以整批并行的高吞吐原语,是构建高性能 SHA-3 / SHAKE 管线的理想底座。
【免费下载链接】cryptocrypto SIG 是密码学兴趣小组,围绕昇腾 NPU 打造高性能密码软件库,提供丰富的密码算子与算法实现项目地址: https://gitcode.com/cann/crypto
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考