RGP
"Relatively Good Privacy"
Usage
use ;
// generate sender fingerprint and public verifier
let = generate_fingerprint;
// generate key pairs for sender and recipient
let = generate_dh_keys;
let = generate_dh_keys;
let mut pub_keys = vec!;
// 8mb
let content = vec!;
// add another 20,000 recipients
for _ in 0..20_000
// encrypt message for all recipients
let = encrypt
.unwrap;
// extract encrypted content key for first recipient
if let Dh =
extract_components_mut
;
More in the examples directory.
Modes
There are currently 4 supported top-level modes: Dh (Diffie-Hellman), Hmac, Session and Kem (Key Encapsulation Mechanism). All modes embed content signing and verification; deniability is preserved by signing the plaintext and encrypting the signature alongside the plaintext.
Ciphersuite
- Blake2s256 for HMAC
- Ed25519 for signatures
- mceliece348864f for KEM
- X25519 for Diffie-Hellman
- XChaCha20 for content keys
- XChaCha20Poly1305 for content
Diffie-Hellman
Dh mode provides forward secrecy by generating a fresh/random content key for each message and encrypting a copy of that key for each recipient with their respective shared secrets (similar to PGP session keys). This mode can be used to manage the initial key exchange/ratchet seeding for Session and Hmac modes.
Steps
- Generate one-time components
- nonce
- content key
- Sign plaintext to generate content signature
- Encrypt plaintext and content signature with content key
- Encrypt content key for all recipients
- Generate shared secret with recipient's public key and sender's private key
- Encrypt content key with shared secret
Format
- nonce = 24 bytes
- keys count
- IF 0..=127
- is single byte = 1 bit (set)
- count = 7 bits
- ELSE
- is single byte = 1 bit (unset)
- int size = 2 bits
- count = 8-64 bits
- IF 0..=127
- encrypted copies of content key = pub_keys.len() * 32 bytes
- encrypted content = content.len()
- signature = 64 bytes (encrypted along with the content)
- Poly1305 MAC = 16 bytes
- mode = 1 byte (set to 2 for
Dhor 4 forDhwith HMAC)
HMAC
Hmac mode provides backward secrecy, and can enable forward secrecy when the HMAC key is kept secret, if only the content key is compromised. Includes an iterator to make ratcheting logic easier to implement.
Steps
- Generate nonce
- Hash the provided components
- Sign plaintext to generate content signature
- Encrypt plaintext and content signature with the hashed key
Format
- nonce = 24 bytes
- iteration
- IF 0..=127
- is single byte = 1 bit (set)
- iteration = 7 bits
- ELSE
- is single byte = 1 bit (unset)
- int size = 2 bits
- iteration = 8-64 bits
- IF 0..=127
- encrypted content = content.len()
- signature = 64 bytes (encrypted along with the content)
- Poly1305 MAC = 16 bytes
- mode = 1 byte (set to 1 for
Hmac)
Session
Session by default provides no forward or backward secrecy, and uses the provided key "as is" without any modification. Session with key gen, however, does provide a weak forward secrecy as it will generate a fresh/single-use content key that is itself encrypted with the session key, thus protecting the session key if only the content key is compromised.
Steps
- Generate one-time components
- nonce
- content key (
Sessionwith key gen only)
- Sign plaintext to generate content signature
- Encrypt plaintext and content signature with the content or session key
- Encrypt content key with session key (
Sessionwith key gen only)
Format
- nonce = 24 bytes
- encrypted key = 32 bytes (
Sessionwith key gen only) - encrypted content = content.len()
- signature = 64 bytes (encrypted along with the content)
- Poly1305 MAC = 16 bytes
- mode = 1 byte (set to 0 for
Sessionor 3 forSessionwith key gen)
KEM
Kem mode is designed to facilitate public key cryptography for post-quantum encryption. It enables forward secrecy by generating a fresh/random content key for each message and encrypting a copy of that key for each recipient with their respective encapsulated keys.
This mode can be used to manage the initial key exchange/ratchet seeding for Session and Hmac as well as seed an HMAC key for usage with Dh mode.
This mode depends on the classic-mceliece-rust crate. It is recommended that the Kem with Diffie-Hellman hybrid, option be used until the underlying PQ crypto has been sufficiently validated.
Classic McEliece was chosen despite its larger key sizes because it has a much smaller ciphertext, which is included for each recipient on each message.
Steps
- Generate one-time components
- nonce
- content key
- Sign plaintext to generate content signature
- Encrypt plaintext and content signature with content key
- Encrypt content key for all recipients
- Generate ciphertext and encapsulated key with recipient's public key and sender's private key
- Encrypt content key with encapsulated key
- Append ciphertext to encrypted content key
Format
- nonce = 24 bytes
- keys count
- IF 0..=127
- is single byte = 1 bit (set)
- count = 7 bits
- ELSE
- is single byte = 1 bit (unset)
- int size = 2 bits
- count = 8-64 bits
- IF 0..=127
- encrypted copies of content key + ciphertext = pub_keys.len() * (32 bytes + 96 bytes)
- encrypted content = content.len()
- signature = 64 bytes (encrypted along with the content)
- Poly1305 MAC = 16 bytes
- mode = 1 byte (set to 5 for
Kemor 6 forKemwith Diffie-Hellman)
Performance
To check performance on your machine, run cargo bench. You can also view the latest benches in the GitHub CI workflow.
All benchmarks for multi-recipient Dh and Kem mode are for 10,000 recipients, and all benchmarks for sign+encrypt/decrypt+verify are using 5mb payloads.
Disable Multi-threading
The "multi-thread" feature is enabled by default and utilizes the Rayon crate. Multi-threading is currently only used in the encrypt function when using Dh or Kem modes to encrypt keys and content in parallel, but can be disabled by setting default-features to false.
[]
= { = "x.x.x", = false }
License
Security
THIS CODE HAS NOT BEEN AUDITED OR REVIEWED. USE AT YOUR OWN RISK.