diff --git a/chacha20/src/backends/soft.rs b/chacha20/src/backends/soft.rs index 8fab325..767a22b 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::{Block, ChaChaCore, Unsigned, STATE_WORDS}; +use crate::{quarter_round, Block, ChaChaCore, Unsigned, STATE_WORDS}; use cipher::{ consts::{U1, U64}, BlockSizeUser, ParBlocksSizeUser, StreamBackend, @@ -52,28 +52,3 @@ fn run_rounds(state: &[u32; STATE_WORDS]) -> [u32; STATE_WORDS] { } res } - -/// The ChaCha20 quarter round function -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/lib.rs b/chacha20/src/lib.rs index c5bc22a..ef1f8c1 100644 --- a/chacha20/src/lib.rs +++ b/chacha20/src/lib.rs @@ -315,3 +315,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 d15ca26..5d5a1fb 100644 --- a/chacha20/src/xchacha.rs +++ b/chacha20/src/xchacha.rs @@ -1,6 +1,6 @@ //! XChaCha is an extended nonce variant of ChaCha -use super::{ChaChaCore, Key, Nonce, CONSTANTS, STATE_WORDS}; +use super::{quarter_round, ChaChaCore, Key, Nonce, CONSTANTS, STATE_WORDS}; use cipher::{ consts::{U10, U16, U24, U32, U4, U6, U64}, generic_array::{typenum::Unsigned, GenericArray}, @@ -8,8 +8,6 @@ use cipher::{ StreamCipherSeekCore, StreamClosure, }; -use crate::backends::soft::quarter_round; - #[cfg(feature = "zeroize")] use cipher::zeroize::ZeroizeOnDrop;