rust/core/docs/crypto.md
Pure Rust cryptographic utilities, wire-compatible with JS/Dart clients.
use ente_core::crypto;
crypto::init().unwrap(); // Optional (no-op for pure Rust)
| Task | Module | Example |
|---|---|---|
| Encrypt keys/tokens | secretbox | secretbox::encrypt(data, &key) |
| Encrypt metadata | blob | blob::encrypt(data, &key) |
| Encrypt files | stream | stream::encrypt_file(&mut src, &mut dst, None) |
| Anonymous encrypt | sealed | sealed::seal(data, &public_key) |
| Password → Key | argon | argon::derive_sensitive_key("password") |
| Master → Subkey | kdf | kdf::derive_login_key(&master_key) |
| Hash data/files | hash | hash::hash_reader(&mut file, None) |
| Generate keys | keys | keys::generate_key() |
let derived = argon::derive_sensitive_key("password")?;
let encrypted = secretbox::encrypt(&user_data, &derived.key)?;
// Store: encrypted.encrypted_data, encrypted.nonce, derived.salt
let mut src = File::open("photo.jpg")?;
let mut dst = File::create("photo.enc")?;
let (key, header) = stream::encrypt_file(&mut src, &mut dst, None)?;
// Store key and header for decryption
MD5 is computed over the encrypted output (header excluded).
let mut src = File::open("photo.jpg")?;
let mut dst = File::create("photo.enc")?;
let (key, header, md5) = stream::encrypt_file_with_md5(&mut src, &mut dst, None)?;
let md5_b64 = crypto::encode_b64(&md5);
let sealed = sealed::seal(&secret_data, &recipient_public_key)?;
// Only recipient can open with their secret key
let opened = sealed::open(&sealed, &recipient_pk, &recipient_sk)?;
let kek = argon::derive_key("password", &salt, mem_limit, ops_limit)?;
let login_key = kdf::derive_login_key(&kek)?;
| Dart | Rust |
|---|---|
encryptSync() / decryptSync() | secretbox::encrypt() / decrypt_box() |
encryptChaCha() / decryptChaCha() | blob::encrypt() / decrypt() |
encryptFile() / decryptFile() | stream::encrypt_file() / decrypt_file() |
encryptFileWithMD5() | stream::encrypt_file_with_md5() |
sealSync() / openSealSync() | sealed::seal() / open() |
deriveSensitiveKey() | argon::derive_sensitive_key_with_salt_adaptive(password.as_bytes(), &salt) |
deriveInteractiveKey() | argon::derive_interactive_key_with_salt(password, &salt) (derive_interactive_key generates salt) |
cryptoPwHash() | argon::derive_key(password, &salt, mem_limit, ops_limit) |
pwhashMemLimitInteractive / pwhashMemLimitSensitive / pwhashOpsLimitInteractive / pwhashOpsLimitSensitive | argon::MEMLIMIT_INTERACTIVE, argon::MEMLIMIT_SENSITIVE, argon::OPSLIMIT_INTERACTIVE, argon::OPSLIMIT_SENSITIVE |
deriveLoginKey() | kdf::derive_login_key() |
getHash() | hash::hash_reader() |
generateKey() | keys::generate_key() |
strToBin() | str_to_bin(input) |
base642bin() / bin2base64() | base642bin(input) / bin2base64(input, url_safe) (url_safe=false for standard, true for URL-safe) |
| Constant | Value | Where |
|---|---|---|
ENCRYPTION_CHUNK_SIZE | 4 MB | stream |
KEY_BYTES | 32 | all modules |
NONCE_BYTES | 24 | secretbox |
HEADER_BYTES | 24 | stream/blob |
SALT_BYTES | 16 | argon/keys |
MEMLIMIT_INTERACTIVE | 64 MB | argon |
MEMLIMIT_SENSITIVE | 1 GB | argon |
OPSLIMIT_INTERACTIVE | 2 | argon |
OPSLIMIT_SENSITIVE | 4 | argon |
SEAL_OVERHEAD | 48 | sealed |
MAC (16) || ciphertextciphertext (plaintext + 17 bytes with tag embedded)ephemeral_pk (32) || MAC (16) || ciphertext