How Encryption Works
PrivStack uses zero-knowledge encryption. Your data is encrypted on your device before it goes anywhere, and we never have access to your keys or your content.
How Your Data Stays Protected
Your master password creates a master key on your device. That master key protects a separate lock for every note, task, and file you create.
Your Password
└── Creates a Master Key (on your device only)
├── Protects Note 1 (separate lock)
├── Protects Task 1 (separate lock)
├── Protects Password entry (extra vault lock)
└── Protects File N (separate lock)
Why does each item get its own lock?
- Change your password without re-encrypting all your data
- Share a document by sharing just that document’s key — your master key stays secret
- If one key is compromised, nothing else is affected
Master Password (plaintext only during unlock)
│
▼
Argon2id (memory-hard KDF)
│
└─► Master Key (never stored, re-derived on unlock)
│
├─► Wraps Entity Key 1 → Note 1 (ChaCha20-Poly1305)
├─► Wraps Entity Key 2 → Task 1 (ChaCha20-Poly1305)
├─► Wraps Entity Key 3 → Password (vault-locked)
└─► Wraps Entity Key N → File N (ChaCha20-Poly1305)
Why two tiers?
- Password changes re-wrap the key envelope without re-encrypting all your data
- Sharing a document means sharing just that document’s key, without exposing your master key
- Compromising one entity key doesn’t compromise any other entities
- Forward secrecy per entity — each has independent cryptographic material
Key Derivation
Argon2id parameters (OWASP 2023 recommended):
- Memory: 19 MiB
- Time iterations: 2
- Parallelism: 1
- Salt: Random (stored locally)
These parameters are tuned for under 1 second derivation on modern hardware. The master key is never stored — it is re-derived from your password every time you unlock the app.
Data Encryption
Each entity gets its own random 256-bit key:
Entity (note, task, event, password, file, etc.)
│
▼
Random Entity Key (256-bit, OS CSPRNG)
│
├─► Encrypts content (ChaCha20-Poly1305, 96-bit random nonce)
│
└─► Entity Key is wrapped with Master Key (ChaCha20-Poly1305)
Memory Safety
All key material implements the Zeroize trait in Rust. Encryption keys, derived keys, and intermediate values are automatically zeroed from memory when they go out of scope. This reduces the window for memory-based attacks.
Encryption Algorithms
| Purpose | Algorithm | Details |
|---|---|---|
| Content encryption | ChaCha20-Poly1305 | 256-bit keys, 96-bit nonces, authenticated |
| Key derivation | Argon2id | 19 MiB memory, 2 iterations (OWASP 2023) |
| Key wrapping | ChaCha20-Poly1305 | Per-document key encryption |
| Transport | QUIC + Noise Protocol | libp2p peer authentication |
| Peer discovery | SHA-256 | Sync code hashing for DHT namespace isolation |
| Integrity | BLAKE3 | Fast, secure integrity checks |
| Random generation | OS CSPRNG | All nonces and keys |
Why ChaCha20-Poly1305?
- Fast: Excellent performance without hardware acceleration (important for mobile)
- Secure: No known vulnerabilities, used by TLS 1.3 and WireGuard
- Authenticated: Built-in Poly1305 tag detects any tampering
- Cross-platform: Consistent performance on all architectures
What’s Encrypted
All content stored by any plugin is encrypted — titles, body content, metadata, and attachments. The only unencrypted data is what’s needed for the app to function (e.g., which plugins are active, sync connection settings).
Plugins don’t implement their own encryption. The core platform handles it transparently, so every plugin — first-party and third-party — gets the same protection automatically.
Vault-Locked Data
Sensitive plugins (Password Vault, Encrypted Files) use an additional vault lock:
- Separate unlock required to access vault contents
- Automatic lockout after configurable inactivity
- Re-authentication overlay when accessing sensitive data
- Independent from the main app unlock
Sharing & Access Control
When sharing an item with another PrivStack user:
- Only that item’s key is shared (not your master key)
- Access levels (Viewer / Editor / Admin / Owner) control what they can do
- Revoking access stops future sync of that item immediately
- ACL changes propagate as CRDT events — encrypted and conflict-free
What We Can’t See
- Your notes, tasks, or calendar events
- Your passwords or login codes
- Your files or documents
- Your actual password
- Your encryption keys
- What you do in the app — we have zero tracking
- Who you share with or what permissions you set
- Your master password (never transmitted, only used during unlock)
- Your encryption keys (derived locally, zeroed from memory after use)
- Your data (encrypted before sync or cloud upload)
- Your usage patterns (no telemetry at all — we track nothing)
- Your sharing permissions (ACLs propagated as encrypted CRDT events)
Password Security
If you forget your password:
- We cannot reset it
- We cannot recover your data
- This is by design — zero-knowledge means zero access
Back up your password securely.