e2eel
A Rust library for end-to-end encryption key management.
e2eel is a key management library designed to power end-to-end encrypted services. It models encryption keys as nodes in a graph, where edges represent key wrappings (i.e., one key encrypted by another). To access a target key, the library traverses the graph from a known starting key, transitively decrypting each wrapping key along the path.
How It Works
Keys and their relationships are stored as a directed graph (which may be cyclic). Each node in the graph represents an encryption key, and each edge represents a wrapping: the target key encrypted by the source key.
A key can have multiple wrappings from different parent keys. This enables multiple access paths to the same key — for example:
- A file's encryption key may be wrapped with the user's own master key (for self-access).
- The same file key may also be wrapped separately with another user's key (to share access with them).
When you request a key, e2eel finds the shortest path from your starting key to the target, then traverses and decrypts each wrapping along that path.
kek (root, derived from password)
└──▶ master
├──▶ recovery
└──▶ file_key ◀── shared_with_user_b (via user B's key wrapping)
Features
- Graph-based key hierarchy — keys and wrappings form a graph (potentially cyclic) with multiple paths between nodes
- Transitive key decryption — automatically resolves and decrypts intermediate keys to reach a target
- Multiple key wrappings — a single key can be wrapped by several different parent keys, enabling shared access and recovery scenarios
- Crypto-primitive agnostic — bring your own crypto provider; multiple algorithms supported out of the box
- Persistence integration — built-in JSON storage with a trait-based interface for custom backends
Supported Encryption Algorithms
AES-256-GCM
- Feature flag:
aes256-gcm(enabled by default) - Key size: 256 bits (32 bytes)
- Performance: Hardware accelerated on most modern CPUs
XSalsa20-Poly1305
- Feature flag:
xsalsa20-poly1305 - Key size: 256 bits (32 bytes)
- Performance: Fast software implementation, well-suited for embedded/mobile
Out of Scope
Password-Based Key Derivation (PBKDF)
e2eel does not handle key derivation from passwords or other low-entropy secrets (e.g., Argon2id, PBKDF2, scrypt). The library expects to receive a fully derived encryption key as the entry point for graph traversal. Integrating a PBKDF to produce that initial key is the responsibility of the consuming application. This may change in the future.
Encrypting Application Data
e2eel only handles the encryption and decryption of keys. It does not provide primitives for encrypting your application's actual content or files. The intended usage is:
- Use e2eel to retrieve a decrypted content encryption key.
- Use your own implementation (or a general-purpose crypto library) to encrypt/decrypt the actual data with that key.
Examples
Set up a new key graph with AES-256-GCM
use ;
Set up a new key graph with XSalsa20-Poly1305
use ;
Retrieve a key by traversing the graph
use ;
Share access to a key with another user
use ;
Cargo Features
The following features are enabled by default:
| Feature | Description |
|---|---|
json |
JSON-based key graph persistence via JsonStorage |
aes256-gcm |
AES-256-GCM crypto provider |
To opt out of defaults and select features explicitly:
[]
# Default features (json + aes256-gcm) — no configuration needed
= { = "0.1" }
# Only AES-256-GCM, without JSON storage
= { = "0.1", = false, = ["aes256-gcm"] }
# XSalsa20-Poly1305 in addition to the defaults
= { = "0.1", = ["xsalsa20-poly1305"] }
# All supported algorithms
= { = "0.1", = ["aes256-gcm", "xsalsa20-poly1305"] }
Development Status
This is a personal project for learning Rust while contributing to the open-source community. The goal is to grow it into a production-ready library over time. Feedback and contributions are welcome.
See ROADMAP.md for planned features.