keccak: replace asm/simd features with --cfg keccak_backend (#106)

Replaces these non-additive "features" with a 1-of-n backend selection
enabled by using `cfg` instead.

- `asm` => `--cfg keccak_backend="armv8_asm"`
- `simd` => `--cfg keccak_backend="simd"`

Closes #85
This commit is contained in:
Tony Arcieri 2026-02-13 16:04:57 -07:00 committed by GitHub
parent a1be08a742
commit 9dc0b8d950
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 28 additions and 31 deletions

View File

@ -50,7 +50,6 @@ jobs:
uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
with:
working-directory: ${{ github.workflow }}
stable-cmd: cargo hack test --release --feature-powerset --skip simd # `simd` requires nightly
test:
needs: set-msrv
@ -79,25 +78,27 @@ jobs:
with:
toolchain: ${{ matrix.rust }}
targets: ${{ matrix.target }}
- run: cargo check --features asm --target ${{ matrix.target }}
- run: cargo test --no-default-features --target ${{ matrix.target }}
- run: cargo check --target ${{ matrix.target }}
- run: cargo test --target ${{ matrix.target }}
- run: cargo test --features asm --target ${{ matrix.target }}
- run: cargo test --features asm --release --target ${{ matrix.target }}
- run: cargo test --release --target ${{ matrix.target }}
- env:
RUSTFLAGS: '-Dwarnings --cfg keccak_backend="armv8_asm"'
run: cargo test --release --target ${{ matrix.target }}
- env:
RUSTFLAGS: '-Dwarnings --cfg keccak_backend="soft-compact"'
run: cargo test --release --target ${{ matrix.target }}
test-simd:
runs-on: ubuntu-latest
env:
RUSTFLAGS: '-Dwarnings --cfg keccak_backend="simd"'
steps:
- uses: actions/checkout@v4
- uses: RustCrypto/actions/cargo-cache@master
- uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
- run: cargo check --features simd
- run: cargo test --features simd
- run: cargo test
test-miri:
runs-on: ubuntu-latest
@ -113,15 +114,15 @@ jobs:
- uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
- name: Install Miri
run: |
rustup component add miri
cargo miri setup
- name: Test with Miri
run: |
cargo miri test --target ${{ matrix.target }} --no-default-features
cargo miri test --target ${{ matrix.target }}
cargo miri test --target ${{ matrix.target }} --features simd
components: miri
- run: cargo miri setup
- run: cargo miri test --target ${{ matrix.target }}
- env:
RUSTFLAGS: '-Dwarnings --cfg keccak_backend="armv8_asm"'
run: cargo miri test --release --target ${{ matrix.target }}
- env:
RUSTFLAGS: '-Dwarnings --cfg keccak_backend="simd"'
run: cargo miri test --release --target ${{ matrix.target }}
- env:
RUSTFLAGS: '-Dwarnings --cfg keccak_backend="soft-compact"'
run: cargo miri test --release --target ${{ matrix.target }}
@ -152,9 +153,9 @@ jobs:
tar -C /tmp -xzf /tmp/binaries.tar.gz
mv /tmp/cross ~/.cargo/bin
shell: bash
- name: cross test
- env:
RUSTFLAGS: '-C target-feature=+sha3 --cfg keccak_backend="armv8_asm"'
run: |
cd keccak
# Cross doesn't enable `sha3` by default, but QEMU supports it.
export RUSTFLAGS="-C target-feature=+sha3"
cross test --target aarch64-unknown-linux-gnu --no-default-features

View File

@ -16,10 +16,6 @@ readme = "README.md"
edition = "2024"
rust-version = "1.85"
[features]
asm = [] # Use optimized assembly when available (currently only ARMv8)
simd = [] # Use core::simd (nightly-only)
[target.'cfg(target_arch = "aarch64")'.dependencies]
cpufeatures = "0.3"
@ -34,7 +30,7 @@ unused_qualifications = "warn"
[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = ['cfg(keccak_backend, values("soft-compact"))']
check-cfg = ['cfg(keccak_backend, values("armv8_asm", "simd", "soft-compact"))']
[lints.clippy]
borrow_as_ptr = "warn"

View File

@ -1,6 +1,6 @@
#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(feature = "simd", feature(portable_simd))]
#![cfg_attr(keccak_backend = "simd", feature(portable_simd))]
#![doc = include_str!("../README.md")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
@ -51,10 +51,10 @@ use core::{
#[rustfmt::skip]
mod unroll;
#[cfg(all(target_arch = "aarch64", feature = "asm"))]
#[cfg(all(target_arch = "aarch64", keccak_backend = "armv8_asm"))]
mod armv8;
#[cfg(all(target_arch = "aarch64", feature = "asm"))]
#[cfg(all(target_arch = "aarch64", keccak_backend = "armv8_asm"))]
cpufeatures::new!(armv8_sha3_intrinsics, "sha3");
const PLEN: usize = 25;
@ -166,11 +166,11 @@ impl_keccak!(p200, f200, u8);
impl_keccak!(p400, f400, u16);
impl_keccak!(p800, f800, u32);
#[cfg(not(all(target_arch = "aarch64", feature = "asm")))]
#[cfg(not(all(target_arch = "aarch64", keccak_backend = "armv8_asm")))]
impl_keccak!(p1600, f1600, u64);
/// `Keccak-p[1600, rc]` permutation.
#[cfg(all(target_arch = "aarch64", feature = "asm"))]
#[cfg(all(target_arch = "aarch64", keccak_backend = "armv8_asm"))]
pub fn p1600(state: &mut [u64; PLEN], round_count: usize) {
if armv8_sha3_intrinsics::get() {
// SAFETY: we just performed runtime CPU feature detection above
@ -181,7 +181,7 @@ pub fn p1600(state: &mut [u64; PLEN], round_count: usize) {
}
/// `Keccak-f[1600]` permutation.
#[cfg(all(target_arch = "aarch64", feature = "asm"))]
#[cfg(all(target_arch = "aarch64", keccak_backend = "armv8_asm"))]
pub fn f1600(state: &mut [u64; PLEN]) {
if armv8_sha3_intrinsics::get() {
// SAFETY: we just performed runtime CPU feature detection above
@ -191,7 +191,7 @@ pub fn f1600(state: &mut [u64; PLEN]) {
}
}
#[cfg(feature = "simd")]
#[cfg(keccak_backend = "simd")]
/// SIMD implementations for Keccak-f1600 sponge function
pub mod simd {
use crate::{LaneSize, PLEN, keccak_p};
@ -413,7 +413,7 @@ mod tests {
keccak_f::<u64>(state_first, state_second);
}
#[cfg(feature = "simd")]
#[cfg(keccak_backend = "simd")]
mod simd {
use super::keccak_f;
use core::simd::{u64x2, u64x4, u64x8};