Skip to content

Commit

Permalink
reorganizes steps inner to content::encrypt to improve performance
Browse files Browse the repository at this point in the history
  • Loading branch information
seanwatters committed Feb 8, 2024
1 parent 2d86c67 commit fec3758
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

[package]
authors = ["sean watters <sean@watters.io>"]
description = "\"Reasonably Good Privacy\""
description = "Relatively Good Privacy"
categories = ["cryptography"]
edition = "2021"
homepage = "https://github.com/seanwatters/RGP"
Expand All @@ -14,7 +14,7 @@ license = "MIT"
name = "rgp"
readme = "README.md"
repository = "https://github.com/seanwatters/RGP"
version = "0.1.6"
version = "0.1.7"

[dependencies]
chacha20 = "0.9.1"
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![docs.rs](https://docs.rs/rgp/badge.svg)](https://docs.rs/rgp/)
[![dependency status](https://deps.rs/repo/github/seanwatters/RGP/status.svg)](https://deps.rs/repo/github/seanwatters/RGP)

"Reasonably Good Privacy"
Relatively Good Privacy

## Usage

Expand Down Expand Up @@ -85,24 +85,24 @@ For the 8mb example with 20,000 recipients, on my M1 MacBook Pro

| Operation | Time |
| ----------------------- | --------- |
| encrypt (multi-thread) | 101.76 ms |
| encrypt (single-thread) | 766.31 ms |
| encrypt (multi-thread) | 97.186 ms |
| encrypt (single-thread) | 764.00 ms |
| extract | 486.00 µs |
| decrypt | 44.729 ms |

Doing the equivalent operation for just 1 recipient on 8mb is

| Operation | Time |
| ----------------------- | --------- |
| encrypt (multi-thread) | 61.537 ms |
| encrypt (single-thread) | 63.758 ms |
| encrypt (multi-thread) | 61.212 ms |
| encrypt (single-thread) | 61.314 ms |
| decrypt | 44.729 ms |

When benchmarked in isolation, the signing operation (internal to the `encrypt` function) and verifying operation (internal to the `decrypt` function), take 28.469 ms and 14.209 ms, respectively.

To check performance on your machine, run `cargo bench` (or `cargo bench --no-default-features` to disable multi-threading). You can also view the latest benches in the GitHub CI [workflow](https://github.com//seanwatters/RGP/actions/workflows/ci.yml) under job/Benchmark or job/Benchmark (single threaded).

**NOTE:** the content signing/encryption logic is done in a separate thread from the per-recipient **content key** encryption, and the **content key** encryption work is done in a Rayon `par_chunks_mut` loop, so the number of threads does have an impact on performance.
**NOTE:** in multi-threaded mode the content signing/encryption logic is done in a separate thread from the per-recipient **content key** encryption, and the **content key** encryption work is done in a Rayon `par_chunks_mut` for loop. There is likely an opportunity for further parallelization in the content encryption and signing step.

## Encrypted Format

Expand Down
53 changes: 27 additions & 26 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,33 @@ pub mod content {
let nonce = ChaChaAEAD::generate_nonce(&mut rand_core::OsRng);
let content_key = ChaChaAEAD::generate_key(&mut rand_core::OsRng);

// sign/encrypt content

#[cfg(feature = "multi-thread")]
let sign_and_encrypt_handle = thread::spawn(move || {
let signature = super::signature::sign(&fingerprint, &content);
content.extend(signature);

let content_cipher = ChaChaAEAD::new(&content_key);
match content_cipher.encrypt(&nonce, content.as_ref()) {
Ok(encrypted_content) => Ok(encrypted_content),
Err(_) => Err("failed to encrypt content"),
}
});

#[cfg(not(feature = "multi-thread"))]
let encrypted_content = {
let signature = super::signature::sign(&fingerprint, &content);
content.extend(signature);

let content_cipher = ChaChaAEAD::new(&content_key);
match content_cipher.encrypt(&nonce, content.as_ref()) {
Ok(encrypted_content) => encrypted_content,
Err(_) => return Err("failed to encrypt content"),
}
};

// generate components
let e_priv_key = StaticSecret::random_from_rng(rand_core::OsRng);
let ot_pub_key = PublicKey::from(&e_priv_key);

Expand Down Expand Up @@ -157,32 +184,6 @@ pub mod content {

out.extend(&keys_header);

// sign/encrypt content

#[cfg(feature = "multi-thread")]
let sign_and_encrypt_handle = thread::spawn(move || {
let signature = super::signature::sign(&fingerprint, &content);
content.extend(signature);

let content_cipher = ChaChaAEAD::new(&content_key);
match content_cipher.encrypt(&nonce, content.as_ref()) {
Ok(encrypted_content) => Ok(encrypted_content),
Err(_) => Err("failed to encrypt content"),
}
});

#[cfg(not(feature = "multi-thread"))]
let encrypted_content = {
let signature = super::signature::sign(&fingerprint, &content);
content.extend(signature);

let content_cipher = ChaChaAEAD::new(&content_key);
match content_cipher.encrypt(&nonce, content.as_ref()) {
Ok(encrypted_content) => encrypted_content,
Err(_) => return Err("failed to encrypt content"),
}
};

let mut encrypted_keys = vec![0u8; KEY_LEN * pub_key_count];

// encrypt keys
Expand Down

0 comments on commit fec3758

Please sign in to comment.