nxm-rs/keccak-batch

GitHub: nxm-rs/keccak-batch

一个支持运行时 SIMD 调度的批量 Keccak-256 Rust 库,专为大量独立输入的并行哈希工作负载提供显著加速。

Stars: 1 | Forks: 0

# keccak-batch [![crates.io](https://img.shields.io/crates/v/keccak-batch.svg)](https://crates.io/crates/keccak-batch) [![docs.rs](https://img.shields.io/docsrs/keccak-batch)](https://docs.rs/keccak-batch) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/nxm-rs/keccak-batch/actions/workflows/ci.yml) [![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL--3.0-blue.svg)](https://www.gnu.org/licenses/agpl-3.0) **支持运行时 SIMD 调度的批量 Keccak-256,专为需要对大量独立输入进行哈希的工作负载而设计。** Merkle 树、重分配采样、证明系统:适用于任何瓶颈在于大量小哈希而非单条长消息的场景。 Keccak 无法通过加速单次置换来实现向量化(包含 25 个 lane,25 个不同的旋转偏移量,且大多数 ISA 没有向量旋转指令)。它的向量化是通过同时运行多个**独立**的哈希来实现的,每个 SIMD lane 运行一个。本 crate 将此暴露为批量 API,并自动选择当前 CPU 支持的最宽 backend。 | 宽度 | backend | 目标平台 | |------:|---------|---------| | 8 | AVX-512 | 支持 `avx512f` 的 x86-64 | | 4 | AVX2 | 支持 `avx2` 的 x86-64 | | 2 | SSE2 / NEON / wasm `simd128` | x86-64, aarch64, wasm | | 1 | scalar | 所有平台 | 所有哈希均使用传统的 Keccak 填充(`0x01` 域字节),即 Ethereum / Swarm Keccak-256,**而不是** FIPS-202 SHA3(`0x06`)。 基于 [nxm-rs](https://github.com/nxm-rs) 构建。它是 [nectar](https://github.com/nxm-rs/nectar) 中 Binary Merkle Tree 背后的批量哈希原语,其中每个 chunk 地址都是基于 128 个叶子节点的 Keccak-256 Merkle root:这恰恰正是本 crate 所适用的大量小哈希场景。它独立运行,不依赖 Swarm,并且对任何需要对大量等长输入进行哈希的人都非常有用。 ## 安装 ``` [dependencies] keccak-batch = "0.1" ``` ## 用法 ``` use keccak_batch::{keccak256, keccak256_many, Keccak256}; // Single hash: same shape as alloy's Keccak256, drop-in. let h = keccak256(b"hello"); // Streaming. let mut hasher = Keccak256::new(); hasher.update(b"hel"); hasher.update(b"lo"); assert_eq!(hasher.finalize(), h); // Batched: N equal-length inputs, one digest each. let a = [0u8; 64]; let b = [1u8; 64]; let digests = keccak256_many::<2>(&[&a, &b]); ``` `keccak256_many`(及其切片形式 `keccak256_many_into`)要求批次中的每个输入长度相同;它们会以同步锁步方式进行吸收。任意数量的批次都会自动拆分分配到可用的宽度上(例如,宽度为 8 时处理 64 个叶子节点会作为八次 8 宽的置换来运行)。`degree()` 会返回当前激活的宽度。 `digest` 特性(默认开启)在 `Keccak256` 上暴露了 RustCrypto 的 `digest` trait,因此可以直接无缝接入任何基于 `digest::Digest` 的泛型实现中。 ## 性能 相对于本 crate 自身 scalar 路径的加速比(按每个批量哈希计算)。BMT 节点场景(64 字节输入,各进行一次置换)是重分配 / Merkle 叶子节点的热点路径;在 Zen 级别支持 AVX-512 的处理器上通过 `cargo run --release --example perf` 测得: | 宽度 | 64 字节输入 | 4 KiB 输入 | |------:|---------------:|-------------:| | 8 (AVX-512) | ~5.4x | ~4-5x | | 4 (AVX2) | ~3.1x | ~2.7x | | 2 (SSE2/NEON/wasm) | ~1.7x | ~1.5x | 作为与外部基准的校准(相同机器,相同测试套件):本 crate 的 scalar 路径与 `tiny-keccak` 持平,而 `keccak-asm`(alloy 的 `asm-keccak` 特性背后的汇编 backend)比这两者快约 1.3 倍。即便如此,8 宽批量处理在单次哈希上依然比 `keccak-asm` 快约 5.5 倍,因此这种批处理优势在面对最强的 scalar 基准时依然坚挺。 置换逻辑只编写了一次,针对 `Lane` 类型进行了泛型抽象;每种指令集只需要实现一个约 6 个操作的 lane backend。通过按值传递 25 lane 状态以及展开 rho/pi,可以让每个 lane 都保存在向量寄存器中(如果不这样做,SIMD 宽度的性能反而会输给 scalar)。 `KECCAK_BATCH_NO_AVX512` / `KECCAK_BATCH_NO_AVX2`(环境变量,任意值)可在运行时限制 backend,例如用于避免某些处理器上因使用 AVX-512 而导致的降频。 ## wasm 2 宽 backend 使用了 `core::arch::wasm32`,并且仅在静态启用 `simd128` 时才会进行编译: ``` RUSTFLAGS="-C target-feature=+simd128" cargo build --target wasm32-unknown-unknown ``` 如果未启用,wasm 构建将运行 scalar 路径。 ### wasm 基准测试 `perf` 示例在 `wasm32-wasip1` 目标平台上通过 `wasmtime` 运行(已配置好 `.cargo/config.toml` 中的 runner,并且 `nix develop` 提供了 wasmtime): ``` # scalar wasm cargo run --release --example perf --target wasm32-wasip1 # simd128 batch-2 wasm RUSTFLAGS="-C target-feature=+simd128" cargo run --release --example perf --target wasm32-wasip1 ``` 实测结果(wasmtime):64 字节 BMT 节点哈希在 scalar 下约为 379 ns,而使用 simd128 约为 222 ns,实现了约 1.7 倍的 batch-2 性能提升,与原生 SSE2/NEON 路径一致。如果不启用 simd128,批量 API 将回退到 scalar(没有加速效果)。 ## 测试 正确性通过以下三种方式得到保证:硬编码的已知答案向量;针对独立 Keccak-256(`tiny_keccak`)进行的、涵盖跨越速率块边界长度的 proptest;以及对主机上可用的每个 SIMD backend 与同一基准进行的交叉检查。请运行 `cargo test`。 ## 开发 `nix develop`(或 `direnv allow`)会为您配置好带有 wasm 目标的固定工具链环境。否则,请使用 Rust 1.92 工具链,并添加 `wasm32-unknown-unknown` 目标。 `cargo fmt --all` 和 `cargo clippy --all-targets --all-features -- -D warnings` 是必须的 pre-commit 步骤并作为 CI 的门禁;库代码路径中严禁使用 `unwrap`/`expect`。CI 还会运行 wasm 构建(分别针对启用和未启用 `simd128` 的情况)、在 `wasm32-wasip1` 上运行 wasm perf 示例,以及进行 `cargo-shear` 未使用依赖检查。 ## 安全 请参阅 [SECURITY.md](https://github.com/nxm-rs/.github/blob/main/SECURITY.md) 或发送邮件至 `security@nxm.rs`。 ## 许可证 AGPL-3.0-or-later。请参阅 [LICENSE](LICENSE)。 ``` ● AGPL-3.0 · pre-release · Keccak-256 (legacy 0x01) ```
标签:Keccak-256, Rust, SIMD, 可视化界面, 哈希算法, 密码学, 底层开发, 手动系统调用, 网络流量审计, 通知系统