Skip to content

Commit

Permalink
chacha20: unify quarter_round in soft backend and xchacha (#349)
Browse files Browse the repository at this point in the history
Deduplicates `quarter_round` in xchacha using soft backend version
  • Loading branch information
oxarbitrage committed May 7, 2024
1 parent e1269b1 commit 6a51902
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 41 deletions.
21 changes: 1 addition & 20 deletions chacha20/src/backends/soft.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -74,22 +74,3 @@ fn run_rounds<R: 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);
}
29 changes: 29 additions & 0 deletions chacha20/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,32 @@ impl<R: Rounds, V: Variant> Drop for ChaChaCore<R, V> {
#[cfg(feature = "zeroize")]
#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
impl<R: Rounds, V: Variant> ZeroizeOnDrop for ChaChaCore<R, V> {}

/// 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.
#[allow(dead_code)]
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);
}
24 changes: 3 additions & 21 deletions chacha20/src/xchacha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -151,26 +153,6 @@ pub fn hchacha<R: Rounds>(key: &Key, input: &Array<u8, U16>) -> Array<u8, U32> {
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::*;
Expand Down

0 comments on commit 6a51902

Please sign in to comment.