Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions keccak/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### 0.2.2 (UNRELEASED)
### Changed
- Improved performance of software backend on some targets ([#129])

[#129]: https://github.com/RustCrypto/sponges/pull/129

## 0.2.1 (2026-08-05)
### Fixed
- Warning on softfloat AArch64 targets by not enabling `aarch64_sha3` backend on them ([#126])
Expand Down
15 changes: 11 additions & 4 deletions keccak/src/backends/simd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ use core::simd::u64x4 as u64xN;
use core::simd::u64x8 as u64xN;

impl LaneSize for u64xN {
const KECCAK_F_ROUND_COUNT: usize = crate::consts::F1600_ROUNDS;
const RC: &[Self] = &{
use crate::consts::{F1600_ROUNDS, RC};

fn truncate_rc(rc: u64) -> Self {
Self::splat(rc)
}
let mut res = [Self::splat(0); F1600_ROUNDS];
let mut i = 0;
#[allow(clippy::cast_possible_truncation, trivial_numeric_casts)]
while i < res.len() {
res[i] = Self::splat(RC[i]);
i += 1;
}
res
};

fn rotate_left(self, n: u32) -> Self {
self << Self::splat(n.into()) | self >> Self::splat((64 - n).into())
Expand Down
41 changes: 24 additions & 17 deletions keccak/src/backends/soft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ pub trait LaneSize:
+ BitXorAssign
+ BitXor<Output = Self>
+ Not<Output = Self>
+ 'static
{
/// Number of rounds of the Keccak-f permutation.
const KECCAK_F_ROUND_COUNT: usize;

/// Truncate function.
fn truncate_rc(rc: u64) -> Self;
/// Round constants
const RC: &[Self];

/// Rotate left function.
#[must_use]
Expand All @@ -30,12 +28,16 @@ pub trait LaneSize:
macro_rules! impl_lanesize {
($type:ty, $round:expr) => {
impl LaneSize for $type {
const KECCAK_F_ROUND_COUNT: usize = $round;

#[allow(clippy::cast_possible_truncation, trivial_numeric_casts)]
fn truncate_rc(rc: u64) -> Self {
rc as Self
}
const RC: &[Self] = &{
let mut res = [0; $round];
let mut i = 0;
#[allow(clippy::cast_possible_truncation, trivial_numeric_casts)]
while i < res.len() {
res[i] = RC[i] as Self;
i += 1;
}
res
};

fn rotate_left(self, n: u32) -> Self {
self.rotate_left(n)
Expand All @@ -53,6 +55,7 @@ impl_lanesize!(u64, F1600_ROUNDS);
macro_rules! unroll5 {
($var: ident, $body: block) => {
#[cfg(not(keccak_backend_soft = "compact"))]
#[allow(non_upper_case_globals)]
{
{ const $var: usize = 0; $body; }
{ const $var: usize = 1; $body; }
Expand All @@ -71,6 +74,7 @@ macro_rules! unroll5 {
macro_rules! unroll24 {
($var: ident, $body: block) => {
#[cfg(not(keccak_backend_soft = "compact"))]
#[allow(non_upper_case_globals)]
{
{ const $var: usize = 0; $body; }
{ const $var: usize = 1; $body; }
Expand Down Expand Up @@ -108,14 +112,14 @@ macro_rules! unroll24 {
///
/// # Panics
/// If the `ROUNDS` is greater than `L::KECCAK_F_ROUND_COUNT`.
#[allow(non_upper_case_globals, unused_assignments)]
pub(crate) fn keccak_p<L: LaneSize, const ROUNDS: usize>(state: &mut [L; PLEN]) {
const { assert!(ROUNDS <= L::RC.len()) };

// https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=25
// "the rounds of KECCAK-p[b, nr] match the last rounds of KECCAK-f[b]"
let round_consts = RC[..L::KECCAK_F_ROUND_COUNT]
let round_consts = L::RC
.last_chunk::<ROUNDS>()
.expect("Number of rounds greater than `KECCAK_F_ROUND_COUNT` is not supported!")
.map(L::truncate_rc);
.expect("Number of rounds is checked above");

// Not unrolling this loop results in a much smaller function, plus
// it positively influences performance due to the smaller load on I-cache
Expand All @@ -142,7 +146,10 @@ pub(crate) fn keccak_p<L: LaneSize, const ROUNDS: usize>(state: &mut [L; PLEN])
unroll24!(x, {
array[0] = state[PI[x]];
state[PI[x]] = last.rotate_left(RHO[x]);
last = array[0];
#[allow(unused_assignments)]
{
last = array[0];
}
});

// Chi
Expand All @@ -159,7 +166,7 @@ pub(crate) fn keccak_p<L: LaneSize, const ROUNDS: usize>(state: &mut [L; PLEN])
});

// Iota
state[0] ^= rc;
state[0] ^= *rc;
}
}

Expand Down
Loading