1 unstable release
| 0.1.0 | Dec 15, 2025 |
|---|
#1435 in Cryptography
Used in enigma-protocol
18KB
227 lines
enigma-identity
A standalone, production-oriented Rust crate implementing local identity creation and X3DH bootstrap for the Enigma ecosystem.
This crate is intentionally self-contained, fully testable, and reusable in other projects. It focuses exclusively on functional block (1) of Enigma: identity and cryptographic session bootstrap.
1. Scope and Responsibilities
enigma-identity is responsible for:
- Local user identity creation (UUID + username)
- Cryptographic identity generation (Ed25519)
- Signed PreKey generation (X25519) and binding to identity
- Publication of a public X3DH bundle
- Verification of a remote X3DH bundle
- X3DH session bootstrap and shared secret derivation
This crate does not:
- manage networking
- store data persistently
- encrypt messages
- implement Double Ratchet
- perform signaling
It provides the cryptographic root of trust for all higher-level Enigma modules.
2. Architectural Overview
+------------------+ +------------------+
| LocalIdentity | | RemoteIdentity |
|------------------| |------------------|
| Ed25519 keypair | | X3DH Bundle |
| X25519 PreKey |<------>| (public only) |
| UUID / username | | |
+--------+---------+ +--------+---------+
| |
| X3DH Initiation | X3DH Response
v v
SharedSecret (32 bytes)
The resulting SharedSecret is intended to seed:
- AEAD encryption engines
- Double Ratchet root keys
- Session authentication
3. Public API Overview
Main Types
| Type | Purpose |
|---|---|
LocalIdentity |
Own identity + secret material |
LocalUser |
Stable local user reference |
X3dhBundle |
Public identity data for peers |
X3dhInitiation |
Initiator handshake message |
X3dhResponderKeys |
Responder private keys |
SharedSecret |
Derived symmetric secret |
Main Functions
| Function | Role |
|---|---|
LocalIdentity::new() |
Create a new local identity |
LocalIdentity::bundle() |
Export public X3DH bundle |
LocalIdentity::verify_bundle() |
Verify remote bundle |
x3dh_initiate() |
Initiate X3DH handshake |
x3dh_respond() |
Respond to X3DH handshake |
4. Identity Model
4.1 LocalUser
pub struct LocalUser {
pub uuid: Uuid,
pub username: String,
}
uuidis generated locally and never transmittedusernameis the human-readable identifier (future@user)
4.2 LocalIdentity
A LocalIdentity owns all private cryptographic material.
Internally it contains:
- Ed25519 signing keypair (identity)
- X25519 Signed PreKey (static, long-lived)
- Signature binding PreKey → Identity
Creation:
let id = LocalIdentity::new("alice")?;
Validation rules:
- username must be non-empty
- username max length: 64 characters
5. X3DH Bundle
5.1 Bundle Structure
pub struct X3dhBundle {
pub username: String,
pub identity_public_key: [u8; 32],
pub signed_prekey_public_key: [u8; 32],
pub signed_prekey_signature: [u8; 64],
}
This structure is fully public and intended to be:
- stored on nodes
- distributed across the network
- verified before any key agreement
5.2 Bundle Verification
Verification ensures:
- Username is valid
- Signed PreKey is correctly signed by the identity key
- Identity and PreKey are cryptographically bound
LocalIdentity::verify_bundle(&bundle)?;
If verification fails, the bundle MUST be rejected.
6. X3DH Handshake
This crate implements a reduced, deterministic X3DH suitable for bootstrapping.
6.1 Initiator Side
let (init, secret) = x3dh_initiate(&remote_bundle)?;
Steps:
- Verify remote bundle
- Generate ephemeral X25519 keypair
- Perform Diffie–Hellman with responder Signed PreKey
- Derive shared secret using HKDF-SHA256
The initiator sends:
X3dhInitiation {
initiator_ephemeral_public_key
}
6.2 Responder Side
let secret = x3dh_respond(&responder_keys, &init)?;
Steps:
- Extract initiator ephemeral public key
- Perform Diffie–Hellman using own Signed PreKey
- Derive identical shared secret via HKDF
7. SharedSecret
pub struct SharedSecret([u8; 32]);
Properties:
- 256-bit symmetric key
- Automatically zeroized on drop
- Safe to pass into AEAD / Ratchet modules
8. Cryptographic Choices
| Component | Algorithm |
|---|---|
| Identity keys | Ed25519 |
| Key agreement | X25519 |
| KDF | HKDF-SHA256 |
| Entropy source | OS RNG |
All primitives are modern, constant-time, and memory-safe.
9. Security Guarantees
This crate provides:
- Identity authenticity (Ed25519)
- PreKey authenticity (signature binding)
- Forward secrecy (ephemeral DH)
- Resistance to impersonation
- Deterministic shared secret derivation
It does not provide:
- Post-compromise security
- Message authentication
- Replay protection
Those are responsibilities of higher layers.
10. Testing Strategy
Each functional responsibility is tested independently.
Identity Tests
- identity creation
- UUID generation
- username validation
- bundle verification
- tamper detection
X3DH Tests
- shared secret equality
- invalid bundle rejection
All tests can be run with:
cargo test
11. Integration Guidelines
Typical integration flow:
-
Create
LocalIdentity -
Publish
X3dhBundleto directory/nodes -
Resolve peer bundle
-
Perform X3DH handshake
-
Feed
SharedSecretinto:- AEAD engine
- Double Ratchet root key
This crate is designed to be imported unchanged by:
- messaging apps
- P2P protocols
- secure transports
- embedded systems
12. Versioning and Stability
- API is intentionally minimal
- Breaking changes are expected only on cryptographic upgrades
- No hidden global state
13. Relationship to Enigma
This crate implements Block 1: Identity & Bootstrap of Enigma.
Subsequent blocks:
- Block 2:
enigma-ratchet - Block 3:
enigma-aead - Block 4:
enigma-transport - Block 5:
enigma-node-protocol
Each block is designed to remain independently testable and replaceable.
14. Design Philosophy
- Cryptography before networking
- Explicit state, no magic
- No global mutable state
- Every byte has a purpose
- Testable in isolation
Dependencies
~3–4.5MB
~92K SLoC