From 9ee394e42ec423cb96175075ebae901837a91e94 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 7 May 2024 10:49:26 -0300 Subject: [PATCH] deduplicate `quarter_round` in xchacha, use soft backend version --- chacha20/src/backends/soft.rs | 21 +-------------------- chacha20/src/lib.rs | 28 ++++++++++++++++++++++++++++ chacha20/src/xchacha.rs | 24 +++--------------------- 3 files changed, 32 insertions(+), 41 deletions(-) diff --git a/chacha20/src/backends/soft.rs b/chacha20/src/backends/soft.rs index 7c570b99..9cd4234f 100644 --- a/chacha20/src/backends/soft.rs +++ b/chacha20/src/backends/soft.rs @@ -1,7 +1,7 @@ //! Portable implementation which does not rely on architecture-specific //! intrinsics. -use crate::{ChaChaCore, Rounds, Variant, STATE_WORDS}; +use crate::{quarter_round, ChaChaCore, Rounds, Variant, STATE_WORDS}; #[cfg(feature = "cipher")] use crate::chacha::Block; @@ -74,22 +74,3 @@ fn run_rounds(state: &[u32; STATE_WORDS]) -> [u32; STATE_WORDS] { } res } - -/// The ChaCha20 quarter round function -fn quarter_round(a: usize, b: usize, c: usize, d: usize, state: &mut [u32; STATE_WORDS]) { - state[a] = state[a].wrapping_add(state[b]); - state[d] ^= state[a]; - state[d] = state[d].rotate_left(16); - - state[c] = state[c].wrapping_add(state[d]); - state[b] ^= state[c]; - state[b] = state[b].rotate_left(12); - - state[a] = state[a].wrapping_add(state[b]); - state[d] ^= state[a]; - state[d] = state[d].rotate_left(8); - - state[c] = state[c].wrapping_add(state[d]); - state[b] ^= state[c]; - state[b] = state[b].rotate_left(7); -} diff --git a/chacha20/src/lib.rs b/chacha20/src/lib.rs index 9b89f8e7..7f4f4e9c 100644 --- a/chacha20/src/lib.rs +++ b/chacha20/src/lib.rs @@ -343,3 +343,31 @@ impl Drop for ChaChaCore { #[cfg(feature = "zeroize")] #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] impl ZeroizeOnDrop for ChaChaCore {} + +/// The ChaCha20 quarter round function +/// +/// We located this function in the root of the crate as we want it to be available +/// for the soft backend and for xchacha. +pub(crate) fn quarter_round( + a: usize, + b: usize, + c: usize, + d: usize, + state: &mut [u32; STATE_WORDS], +) { + state[a] = state[a].wrapping_add(state[b]); + state[d] ^= state[a]; + state[d] = state[d].rotate_left(16); + + state[c] = state[c].wrapping_add(state[d]); + state[b] ^= state[c]; + state[b] = state[b].rotate_left(12); + + state[a] = state[a].wrapping_add(state[b]); + state[d] ^= state[a]; + state[d] = state[d].rotate_left(8); + + state[c] = state[c].wrapping_add(state[d]); + state[b] ^= state[c]; + state[b] = state[b].rotate_left(7); +} diff --git a/chacha20/src/xchacha.rs b/chacha20/src/xchacha.rs index 02d5fdba..ab0a1ff6 100644 --- a/chacha20/src/xchacha.rs +++ b/chacha20/src/xchacha.rs @@ -7,7 +7,9 @@ use cipher::{ StreamCipherSeekCore, StreamClosure, }; -use crate::{variants::Ietf, ChaChaCore, Rounds, CONSTANTS, R12, R20, R8, STATE_WORDS}; +use crate::{ + quarter_round, variants::Ietf, ChaChaCore, Rounds, CONSTANTS, R12, R20, R8, STATE_WORDS, +}; #[cfg(feature = "zeroize")] use zeroize::ZeroizeOnDrop; @@ -151,26 +153,6 @@ pub fn hchacha(key: &Key, input: &Array) -> Array { output } -/// The ChaCha20 quarter round function -// for simplicity this function is copied from the software backend -fn quarter_round(a: usize, b: usize, c: usize, d: usize, state: &mut [u32; STATE_WORDS]) { - state[a] = state[a].wrapping_add(state[b]); - state[d] ^= state[a]; - state[d] = state[d].rotate_left(16); - - state[c] = state[c].wrapping_add(state[d]); - state[b] ^= state[c]; - state[b] = state[b].rotate_left(12); - - state[a] = state[a].wrapping_add(state[b]); - state[d] ^= state[a]; - state[d] = state[d].rotate_left(8); - - state[c] = state[c].wrapping_add(state[d]); - state[b] ^= state[c]; - state[b] = state[b].rotate_left(7); -} - #[cfg(test)] mod hchacha20_tests { use super::*;