RGP
Relatively Good Privacy
Ciphersuite
- Blake2s256 for hashing
- Ed25519 for signatures
- X25519 for shared secrets
- XChaCha20 for content keys
- XChaCha20Poly1305 for content
Modes
There are currently three supported modes: Dh (Diffie-Hellman), Hmac, and Session. All modes provide the ability to sign content and verify the sender. Deniability is preserved by signing the plaintext and encrypting the signature alongside the plaintext.
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 (similar to the way PGP session keys work).
let = generate_fingerprint;
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 for recipient
if let Dh = extract_mode_mut ;
How it works:
- 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 public key and sender private key
- Encrypt content key with shared secret
Format:
- nonce = 24 bytes
- keys count
- int size = 2 bits
- count
- numbers 0-63 = 6 bits
- numbers >63 = 1-8 bytes (big endian int)
- encrypted copies of content key = pub_keys.len() * 32 bytes
- encrypted content = content.len()
- signature = 64 bytes (encrypted along with the content to preserve deniability)
- Poly1305 MAC = 16 bytes
- mode = 1 byte (set to 2 for
Dh)
HMAC
Hmac mode provides backward secrecy, and can enable forward secrecy when both the HMAC key and value are kept secret, and only the content key is compromised.
let = generate_fingerprint;
let hash_key = ; // use an actual key
let hash_value = ; // use an actual key
let content = vec!;
// encrypt message keyed hash result
let = encrypt
.unwrap;
if let Hmac = extract_mode_mut ;
How it works:
- Generate nonce
- Hmac the content key
- Sign plaintext to generate content signature
- Encrypt plaintext and content signature with the hashed content key
Format:
- nonce = 24 bytes
- iteration
- int size = 2 bits
- iteration
- numbers 0-63 = 6 bits
- numbers >63 = 1-8 bytes (big endian int)
- encrypted content = content.len()
- signature = 64 bytes (encrypted along with the content to preserve deniability)
- Poly1305 MAC = 16 bytes
- mode = 1 byte (set to 1 for
Hmac)
Session
Session provides no forward or backward secrecy, and uses the provided key "as is" without any modification.
let = generate_fingerprint;
let session_key = ; // use an actual key
let content = vec!;
// encrypt message with a session key
let = encrypt
.unwrap;
if let Session = extract_mode_mut
How it works:
- Generate nonce
- Sign plaintext to generate content signature
- Encrypt plaintext and content signature with the provided content key, as is
Format:
- nonce = 24 bytes
- encrypted content = content.len()
- signature = 64 bytes (encrypted along with the content to preserve deniability)
- Poly1305 MAC = 16 bytes
- mode = 1 byte (set to 0 for
Hmac)
Performance
To check performance on your machine, run cargo bench. You can also view the latest benches in the GitHub CI workflow under job/Benchmark.
All benchmarks for multi-recipient payloads are for 20,000 recipients, and all benchmarks encrypt/sign/decrypt 8mb.
License
Security
THIS CODE HAS NOT BEEN AUDITED OR REVIEWED. USE AT YOUR OWN RISK.