96 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # HeroDB AGE Cryptography
 | |
| 
 | |
| HeroDB provides AGE-based asymmetric encryption and digital signatures over the Redis protocol using X25519 for encryption and Ed25519 for signatures. Keys can be used in stateless (ephemeral) or key-managed (persistent, named) modes.
 | |
| 
 | |
| In key-managed mode, HeroDB uses a unified keypair concept: a single Ed25519 signing key is deterministically derived into X25519 keys for encryption, allowing one keypair to handle both encryption and signatures transparently.
 | |
| 
 | |
| ## Cryptographic Algorithms
 | |
| 
 | |
| ### X25519 (Encryption)
 | |
| - Elliptic-curve Diffie-Hellman key exchange for symmetric key derivation.
 | |
| - Used for encrypting/decrypting messages.
 | |
| 
 | |
| ### Ed25519 (Signatures)
 | |
| - EdDSA digital signatures for message authentication.
 | |
| - Used for signing/verifying messages.
 | |
| 
 | |
| ### Key Derivation
 | |
| Ed25519 signing keys are deterministically converted to X25519 keys for encryption. This enables a single keypair to support both operations without additional keys. Derivation uses the Ed25519 secret scalar clamped for X25519.
 | |
| 
 | |
| In named keypairs, Ed25519 keys are stored, and X25519 keys are derived on-demand and cached.
 | |
| 
 | |
| ## Stateless Mode (Ephemeral Keys)
 | |
| No server-side storage; keys are provided with each command.
 | |
| 
 | |
| Available commands:
 | |
| - `AGE GENENC`: Generate ephemeral X25519 keypair. Returns `[recipient, identity]`.
 | |
| - `AGE GENSIGN`: Generate ephemeral Ed25519 keypair. Returns `[verify_pub, sign_secret]`.
 | |
| - `AGE ENCRYPT <recipient> <message>`: Encrypt message. Returns base64 ciphertext.
 | |
| - `AGE DECRYPT <identity> <ciphertext_b64>`: Decrypt ciphertext. Returns plaintext.
 | |
| - `AGE SIGN <sign_secret> <message>`: Sign message. Returns base64 signature.
 | |
| - `AGE VERIFY <verify_pub> <message> <signature_b64>`: Verify signature. Returns 1 (valid) or 0 (invalid).
 | |
| 
 | |
| Example:
 | |
| ```bash
 | |
| redis-cli AGE GENENC
 | |
| # → 1) "age1qz..."  # recipient (X25519 public)
 | |
| #    2) "AGE-SECRET-KEY-1..."  # identity (X25519 secret)
 | |
| 
 | |
| redis-cli AGE ENCRYPT "age1qz..." "hello"
 | |
| # → base64_ciphertext
 | |
| 
 | |
| redis-cli AGE DECRYPT "AGE-SECRET-KEY-1..." base64_ciphertext
 | |
| # → "hello"
 | |
| ```
 | |
| 
 | |
| ## Key-Managed Mode (Persistent Named Keys)
 | |
| Keys are stored server-side under names. Supports unified keypairs for both encryption and signatures.
 | |
| 
 | |
| Available commands:
 | |
| - `AGE KEYGEN <name>`: Generate and store unified keypair. Returns `[recipient, identity]` in age format.
 | |
| - `AGE SIGNKEYGEN <name>`: Generate and store Ed25519 signing keypair. Returns `[verify_pub, sign_secret]`.
 | |
| - `AGE ENCRYPTNAME <name> <message>`: Encrypt with named key. Returns base64 ciphertext.
 | |
| - `AGE DECRYPTNAME <name> <ciphertext_b64>`: Decrypt with named key. Returns plaintext.
 | |
| - `AGE SIGNNAME <name> <message>`: Sign with named key. Returns base64 signature.
 | |
| - `AGE VERIFYNAME <name> <message> <signature_b64>`: Verify with named key. Returns 1 or 0.
 | |
| - `AGE LIST`: List all stored key names. Returns sorted array of names.
 | |
| 
 | |
| ### AGE LIST Output
 | |
| Returns a flat, deduplicated, sorted array of key names (strings). Each name corresponds to a stored keypair, which may include encryption keys (X25519), signing keys (Ed25519), or both.
 | |
| 
 | |
| Output format: `["name1", "name2", ...]`
 | |
| 
 | |
| Example:
 | |
| ```bash
 | |
| redis-cli AGE LIST
 | |
| # →  1) "<named_keypair_1>"
 | |
| #    2) "<named_keypair_2>"
 | |
| ```
 | |
| 
 | |
| For unified keypairs (from `AGE KEYGEN`), the name handles both encryption (derived X25519) and signatures (stored Ed25519) transparently.
 | |
| 
 | |
| Example with named keys:
 | |
| ```bash
 | |
| redis-cli AGE KEYGEN app1
 | |
| # →  1) "age1..."  # recipient
 | |
| #    2) "AGE-SECRET-KEY-1..."  # identity
 | |
| 
 | |
| redis-cli AGE ENCRYPTNAME app1 "secret message"
 | |
| # → base64_ciphertext
 | |
| 
 | |
| redis-cli AGE DECRYPTNAME app1 base64_ciphertext
 | |
| # → "secret message"
 | |
| 
 | |
| redis-cli AGE SIGNNAME app1 "message"
 | |
| # → base64_signature
 | |
| 
 | |
| redis-cli AGE VERIFYNAME app1 "message" base64_signature
 | |
| # → 1
 | |
| ```
 | |
| 
 | |
| ## Choosing a Mode
 | |
| - **Stateless**: For ad-hoc operations without persistence; client manages keys.
 | |
| - **Key-managed**: For centralized key lifecycle; server stores keys for convenience and discoverability.
 | |
| 
 | |
| Implementation: [herodb/src/age.rs](herodb/src/age.rs) <br> 
 | |
| Tests: [herodb/tests/usage_suite.rs](herodb/tests/usage_suite.rs) |