Skip to content

Commit d34bfdd

Browse files
committed
age: Use rayon for processing STREAM chunks in parallel
1 parent cb2cafb commit d34bfdd

File tree

3 files changed

+24
-18
lines changed

3 files changed

+24
-18
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

age/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ rust-embed = "5"
7777

7878
# Performance
7979
num_cpus = "1.0"
80+
rayon = "1.5"
8081

8182
# Common CLI dependencies
8283
console = { version = "0.13", optional = true }

age/src/primitives/stream.rs

+22-18
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use chacha20poly1305::{
66
};
77
use lazy_static::lazy_static;
88
use pin_project::pin_project;
9+
use rayon::prelude::*;
910
use secrecy::{ExposeSecret, SecretVec};
1011
use std::cmp;
1112
use std::convert::TryInto;
@@ -53,9 +54,9 @@ impl Nonce {
5354
self.0 = u128::from(val) << 8;
5455
}
5556

56-
fn increment_counter(&mut self) {
57+
fn increment_counter(&mut self, by: usize) {
5758
// Increment the 11-byte counter
58-
self.0 += 1 << 8;
59+
self.0 += (by as u128) << 8;
5960
if self.0 >> (8 * 12) != 0 {
6061
panic!("We overflowed the nonce!");
6162
}
@@ -194,26 +195,29 @@ impl Stream {
194195
let num_chunks = chunks.len();
195196
let mut encrypted = vec![0; chunks_len + TAG_SIZE * num_chunks];
196197

197-
for (i, (encrypted, chunk)) in encrypted
198+
encrypted
198199
.chunks_mut(ENCRYPTED_CHUNK_SIZE)
199200
.zip(chunks)
200201
.enumerate()
201-
{
202-
if i + 1 == num_chunks {
203-
self.nonce.set_last(last).unwrap();
204-
}
202+
.par_bridge()
203+
.for_each_with(self.nonce, |nonce, (i, (encrypted, chunk))| {
204+
nonce.increment_counter(i);
205+
if i + 1 == num_chunks {
206+
nonce.set_last(last).unwrap();
207+
}
205208

206-
let (buffer, tag) = encrypted.split_at_mut(chunk.len());
207-
buffer.copy_from_slice(chunk);
208-
tag.copy_from_slice(
209-
self.aead
210-
.encrypt_in_place_detached(&self.nonce.to_bytes().into(), &[], buffer)
211-
.expect("we will never hit chacha20::MAX_BLOCKS because of the chunk size")
212-
.as_slice(),
213-
);
209+
let (buffer, tag) = encrypted.split_at_mut(chunk.len());
210+
buffer.copy_from_slice(chunk);
211+
tag.copy_from_slice(
212+
self.aead
213+
.encrypt_in_place_detached(&nonce.to_bytes().into(), &[], buffer)
214+
.expect("we will never hit chacha20::MAX_BLOCKS because of the chunk size")
215+
.as_slice(),
216+
);
217+
});
214218

215-
self.nonce.increment_counter();
216-
}
219+
self.nonce.increment_counter(num_chunks);
220+
self.nonce.set_last(last).unwrap();
217221

218222
Ok(encrypted)
219223
}
@@ -248,7 +252,7 @@ impl Stream {
248252
)
249253
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "decryption error"))?;
250254

251-
self.nonce.increment_counter();
255+
self.nonce.increment_counter(1);
252256
}
253257

254258
Ok(SecretVec::new(decrypted))

0 commit comments

Comments
 (0)