Skip to content

Commit 4b54fd0

Browse files
author
bloom
committed
chacha: handle situations where all the keystream has not been consumed
1 parent 2ad834a commit 4b54fd0

File tree

8 files changed

+173
-239
lines changed

8 files changed

+173
-239
lines changed

Cargo.lock

Lines changed: 13 additions & 114 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ fmt:
55

66
.PHONY: check
77
check:
8-
RUSTFLAGS="-C target-feature=-avx2,-simd128" cargo check 2>/dev/null
8+
RUSTFLAGS="-C target-feature=-avx2,-simd128" cargo check
99
cargo check
1010

1111
# check for all supported targets and target features

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ chacha12-blake3 = "0.9"
4747
use chacha12_blake3::ChaCha12Blake3;
4848

4949
fn main() {
50-
let key: [u8; 32] = rand::random();
51-
let nonce: [u8; 32] = rand::random();
50+
// DON'T USE A ALL-ZERO KEY, THIS CODE IS FOR DEMONSTRATION ONLY
51+
let key = [0u8; 32];
52+
let nonce = [0u8; 32];
5253
// or with an u64 counter to encrypt up to 2^64 messages:
5354
// let mut nonce = [0u8; 32];
5455
// nonce[..8].copy_from_slice(&counter.to_le_bytes());

chacha12/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ edition = "2024"
55
description = "Pure-Rust, SIMD-accelerated ChaCha20 / ChaCha12 / ChaCha8 for any platform"
66
repository = "https://github.com/bloom42/chacha12-blake3"
77
license = "MIT"
8-
keywords = ["cryptography", "chacha20", "blake3", "encryption", "chacha12", "simd"]
9-
categories = ["cryptography"]
8+
keywords = ["cryptography", "chacha20", "blake3", "encryption", "chacha12", "simd", "wasm", "chacha", "webassembly"]
9+
categories = ["cryptography", "wasm"]
1010

1111
[dependencies]
1212

chacha12/src/chacha_avx2.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,14 @@ struct AlignedU32x8([u32; SIMD_LANES]);
2020
// [ block1 (32-bits) || block2 (32-bits) || block3 (32-bits) || block4 (32-bits) || block5 (32-bits) ... ]
2121
// then we perform the normal ChaCha operations on these vectors, meaning that we compute
2222
// 8 ChaCha blocks in parallel for every operation on these vectors.
23-
pub fn chacha_avx2<const ROUNDS: usize>(state: [u32; 16], mut counter: u64, input: &mut [u8]) -> u64 {
23+
pub fn chacha_avx2<const ROUNDS: usize>(
24+
state: [u32; 16],
25+
mut counter: u64,
26+
input: &mut [u8],
27+
last_keystream_block: &mut [u8; 64],
28+
) -> u64 {
29+
let mut keystream = [0u8; SIMD_LANES * 64];
30+
2431
let mut initial_state: [__m256i; 16] = unsafe {
2532
[
2633
// constant
@@ -64,7 +71,6 @@ pub fn chacha_avx2<const ROUNDS: usize>(state: [u32; 16], mut counter: u64, inpu
6471
}
6572

6673
// compute 8 64-byte ChaCha blocks in parallel
67-
let mut keystream = [0u8; SIMD_LANES * 64];
6874
chacha20_avx2_8blocks::<ROUNDS>(initial_state, &mut keystream);
6975

7076
// XOR plaintext with keystream
@@ -76,6 +82,10 @@ pub fn chacha_avx2<const ROUNDS: usize>(state: [u32; 16], mut counter: u64, inpu
7682
counter = counter.wrapping_add((input_blocks.len() as u64).div_ceil(64));
7783
}
7884

85+
let last_keystream_block_index = ((input.len() - 1) / 64) % SIMD_LANES;
86+
let last_keystream_block_offset = last_keystream_block_index * 64;
87+
last_keystream_block.copy_from_slice(&keystream[last_keystream_block_offset..last_keystream_block_offset + 64]);
88+
7989
return counter;
8090
}
8191

@@ -84,6 +94,8 @@ pub fn chacha_avx2<const ROUNDS: usize>(state: [u32; 16], mut counter: u64, inpu
8494
/// [ block1 (64 bytes) || block2 (64 bytes) || block3 (64 bytes) || block4 (64 bytes) ... ]
8595
#[inline(always)]
8696
fn chacha20_avx2_8blocks<const ROUNDS: usize>(initial_state: [__m256i; 16], keystream: &mut [u8; SIMD_LANES * 64]) {
97+
let keystream_ptr = keystream.as_mut_ptr();
98+
8799
unsafe {
88100
let mut working_state = initial_state;
89101

@@ -130,7 +142,6 @@ fn chacha20_avx2_8blocks<const ROUNDS: usize>(initial_state: [__m256i; 16], keys
130142
// the second iteration writes block1[4..8], block2[4..8], block3[4..8], block4[4..8], block5[4..8] ...
131143
// the third iteration writes block1[4..8], block2[8..12], block3[8..12], block4[8..12], block5[8..12] ...
132144
// and so on, for the 16 32-bit words of the ChaCha state
133-
let keystream_ptr = keystream.as_mut_ptr();
134145
for word_index in 0..STATE_WORDS {
135146
// first we add the working state to the initial state to get the keystream
136147
working_state[word_index] = _mm256_add_epi32(working_state[word_index], initial_state[word_index]);

0 commit comments

Comments
 (0)