Skip to content

Commit

Permalink
fix: use correct chunk size for chacha20
Browse files Browse the repository at this point in the history
  • Loading branch information
mikesposito committed Dec 1, 2023
1 parent e8d22f8 commit 2583b56
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 60 deletions.
5 changes: 0 additions & 5 deletions benches/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ criterion = "0.5"
secured-enclave = { path = "../enclave/" }
secured-cipher = { path = "../cipher/" }

[[bench]]
name = "enclave"
path = "src/enclave.rs"
harness = false

[[bench]]
name = "chacha20"
path = "src/chacha20.rs"
Expand Down
26 changes: 20 additions & 6 deletions benches/src/chacha20.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use criterion::{
criterion_group, criterion_main, BenchmarkId, Criterion, PlotConfiguration, Throughput,
};
use secured_cipher::chacha20::{ChaChaStream, KEY_SIZE, NONCE_SIZE};

const KB: usize = 1024;

fn bench(c: &mut Criterion) {
let mut group = c.benchmark_group("ChaChaStream");

for size in &[KB, 2 * KB, 4 * KB, 8 * KB, 16 * KB] {
let plot_config = PlotConfiguration::default().summary_scale(criterion::AxisScale::Logarithmic);
group.plot_config(plot_config);

for size in &[
KB,
2 * KB,
4 * KB,
8 * KB,
16 * KB,
32 * KB,
64 * KB,
128 * KB,
256 * KB,
] {
let key = [0u8; KEY_SIZE];
let iv = [1u8; NONCE_SIZE];

group.throughput(Throughput::Bytes(*size as u64));

group.bench_with_input(BenchmarkId::new("new", size), size, |b, &_size| {
b.iter(|| ChaChaStream::new(key, iv));
});
// group.bench_with_input(BenchmarkId::new("new", size), size, |b, &_size| {
// b.iter(|| ChaChaStream::new(key, iv));
// });

let mut stream = ChaChaStream::new(key, iv);
group.bench_with_input(BenchmarkId::new("process", size), size, |b, &_size| {
Expand Down
26 changes: 0 additions & 26 deletions benches/src/enclave.rs

This file was deleted.

21 changes: 21 additions & 0 deletions cipher/src/chacha20/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,27 @@ pub fn seek_keystream(state: &[u32; 16], n: u64) -> [u32; 16] {
keystream
}

/// XORs two 512-bit state arrays.
/// This function modifies the first array in place.
///
/// # Arguments
/// * `a` - A mutable reference to the first state array.
/// * `b` - A reference to the second state array.
///
/// # Panics
/// Panics if the two arrays are not of equal length.
pub fn xor(left: &mut [u32], right: &[u32]) {
assert_eq!(
left.len(),
right.len(),
"State arrays must be of equal length"
);
left
.iter_mut()
.zip(right.iter())
.for_each(|(left, right)| *left ^= *right);
}

/// Safely increments the 2-word block counter of the ChaCha20 state.
///
/// This function increments the lower 32 bits of the counter and, if there is an overflow,
Expand Down
45 changes: 22 additions & 23 deletions cipher/src/chacha20/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{Bytes, Slice};
use rayon::prelude::*;

use super::core::{
chacha20_rounds, safe_2words_counter_increment, seek_keystream, to_u32_slice, u32_to_u8_vec,
chacha20_rounds, safe_2words_counter_increment, seek_keystream, to_u32_slice, u32_to_u8_vec, xor,
CONSTANTS, STATE_WORDS,
};

Expand Down Expand Up @@ -52,7 +52,8 @@ impl ChaChaStream {

// The block counter occupies the next two words (13th and 14th positions) in the state.
// In ChaCha20, this counter is used to make each block unique.
// Here, it's initialized from the first half of the 8-byte IV (initialization vector).
// We skip those they are set to zero already.
// Here, we use the last 8-byte space of the block for the IV (initialization vector).
let iv_chunks = iv.chunks_exact(4);
for (val, chunk) in state[14..16].iter_mut().zip(iv_chunks) {
*val = u32::from_le_bytes(chunk.try_into().unwrap());
Expand Down Expand Up @@ -119,20 +120,20 @@ impl ChaChaStream {
// Wrap the state in an Arc to allow for parallel processing
let arc_state = Arc::new(self.state);

// Process each 64-byte block in parallel
out.par_chunks_mut(64).enumerate().for_each(|(i, chunk)| {
let chunk_keystream = seek_keystream(&arc_state, i as u64);

for (k, out_elem) in chunk.iter_mut().enumerate() {
if k >= chunk_keystream.len() {
// If the chunk is smaller than 64 bytes, the keystream will be shorter than 64 bytes.
break;
}

// XOR the output with the keystream
*out_elem ^= chunk_keystream[k];
}
});
// Process each chunk of 8 blocks in parallel
out
.par_chunks_mut(128)
.enumerate()
.for_each(|(i, blocks_chunk)| {
blocks_chunk
.chunks_mut(STATE_WORDS)
.enumerate()
.for_each(|(j, block)| {
// Cipher each 64-byte block in the chunk
let chunk_keystream = seek_keystream(&arc_state, (i + j) as u64);
xor(block, &chunk_keystream);
});
});

// Clear the keystream
self.clear_stream();
Expand Down Expand Up @@ -164,13 +165,11 @@ mod tests {
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
];
const CIPHERTEXT: [u8; 100] = [
0x92, 0x96, 0x40, 0xC6, 0x6F, 0x7A, 0xA6, 0x3E, 0x40, 0x5E, 0x1B, 0x1D, 0x94, 0xA4, 0x8D, 0x69,
0xC7, 0x16, 0xBE, 0xDF, 0x8D, 0xD2, 0xE6, 0xDA, 0xDE, 0xF7, 0xD5, 0xE7, 0x15, 0x18, 0x51, 0x5D,
0x40, 0x67, 0x67, 0x60, 0x8A, 0x00, 0x82, 0xE1, 0x37, 0x97, 0x41, 0x61, 0xFA, 0xAC, 0xD1, 0x14,
0x09, 0xC5, 0x00, 0x32, 0xB1, 0xD0, 0xF1, 0xBD, 0x69, 0x7C, 0x3F, 0x93, 0x27, 0xDA, 0xDD, 0xF1,
0x63, 0x75, 0x72, 0x61, 0x20, 0x63, 0x68, 0x65, 0x20, 0x6C, 0x61, 0x20, 0x64, 0x69, 0x72, 0x69,
0x74, 0x74, 0x61, 0x20, 0x76, 0x69, 0x61, 0x20, 0x65, 0x72, 0x61, 0x20, 0x73, 0x6D, 0x61, 0x72,
0x72, 0x69, 0x74, 0x61,
146, 150, 64, 198, 111, 122, 166, 62, 64, 94, 27, 29, 148, 164, 141, 105, 199, 22, 190, 223,
141, 210, 230, 218, 222, 247, 213, 231, 21, 24, 81, 93, 64, 103, 103, 96, 138, 0, 130, 225, 55,
151, 65, 97, 250, 172, 209, 20, 9, 197, 0, 50, 177, 208, 241, 189, 105, 124, 63, 147, 39, 218,
221, 241, 191, 134, 94, 135, 34, 124, 180, 33, 15, 18, 30, 88, 156, 237, 156, 97, 222, 15, 182,
145, 219, 223, 238, 218, 213, 234, 199, 179, 20, 20, 16, 89, 91, 122, 114, 33,
];
const IV: [u8; 8] = [0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8];

Expand Down

0 comments on commit 2583b56

Please sign in to comment.