Skip to main content

git_simple_encrypt/crypt/
mod.rs

1//! The core of this program. Encrypt/decrypt, compress/decompress files.
2//!
3//! # Module Structure
4//!
5//! | Module | Contents |
6//! |---|---|
7//! | [`header`] | Constants (`MAGIC`, `VERSION`, `SALT_LEN`, …) and [`FileHeader`] |
8//! | [`key`] | Key derivation (Argon2, key splitting, nonce derivation) + key cache |
9//! | [`stream`] | Streaming `Read → Write` encrypt/decrypt primitives |
10//! | [`file`] | File-to-file encrypt/decrypt with atomic writes & metadata preservation |
11//! | [`batch`] | Parallel batch operations with shared key cache |
12//! | [`repo`] | Repository-level encrypt/decrypt with salt cache integration |
13//!
14//! See the module-level docs of each submodule for details.
15//!
16//! # Nonce Derivation (Content-Based with File ID)
17//!
18//! Per-chunk nonces are derived from the file's random `File_ID` and the
19//! chunk's own plaintext content using keyed Blake3:
20//!
21//! 1. A random 16-byte `File_ID` is generated once per file and stored in the header. This ensures
22//!    that even if two different files have identical plaintext at chunk 0, they produce different
23//!    nonces and ciphertexts.
24//! 2. The Argon2-derived master key is split via `blake3::derive_key` into `Key_ENC` (for
25//!    XChaCha20-Poly1305 encryption) and `Key_MAC` (for nonce generation).
26//! 3. For each chunk `i`: `Nonce_i = Blake3_keyed(Key_MAC, File_ID || M_i || chunk_idx_le)[0..24]`
27//! 4. The 24-byte nonce is stored in plaintext at the head of each encrypted chunk.
28//!
29//! Different plaintext always produces a different nonce (within the same
30//! file). The `File_ID` ensures cross-file uniqueness. The chunk index prevents
31//! reordering attacks on identical 64 KB blocks.
32//!
33//! # Authenticated Additional Data (AAD)
34//!
35//! Each chunk's AAD binds the ciphertext to the full file header so that any
36//! tampering with header fields (version, compression flag, salt, `file_id`,
37//! reserved) is detected via Poly1305 authentication failure:
38//!
39//! ```text
40//! AAD = HEADER (64B) || chunk_idx (8B LE) || is_last_chunk (1B)   // 73 bytes
41//! ```
42//!
43//! Each encrypted chunk layout: `[NONCE (24B)] [CIPHERTEXT] [TAG (16B)]`
44
45mod batch;
46mod file;
47mod header;
48mod key;
49mod repo;
50mod stream;
51
52pub use batch::BatchSummary;
53pub use file::{
54    decrypt_file, decrypt_file_to, decrypt_file_with_cache, encrypt_file, encrypt_file_to,
55};
56pub use header::{
57    FILE_ID_LEN, FileHeader, HEADER_LEN, MAGIC, NONCE_LEN, SALT_LEN, VERSION, is_encrypted_version,
58};
59pub use key::derive_key;
60pub use repo::{cache_key, decrypt_repo, encrypt_repo};
61pub use stream::{decrypt_into, encrypt_into};
62
63#[cfg(test)]
64mod tests;