Key Management
Your private key is the foundation of your ATP identity. Lose it, and you lose control. Protect it, rotate it, and back it up.
Which Key Type Should I Choose?
ATP supports multiple cryptographic algorithms. Here's how to decide:
Need quantum resistance now?
├─ Yes → Dilithium (hybrid with Ed25519 recommended)
└─ No → Ed25519
Have an existing GPG key?
├─ Yes → GPG is fine (but consider migrating to Ed25519)
└─ No → Ed25519
Need Bitcoin/Ethereum interop?
├─ Yes → secp256k1
└─ No → Ed25519
Default for new agents → Ed25519Supported Key Types
| Type | Algorithm | Quantum Safe | Key Size | Signature Size | Status |
|---|---|---|---|---|---|
ed25519 | Ed25519 (RFC 8032) | ❌ | 32 bytes | 64 bytes | Recommended |
secp256k1 | ECDSA over secp256k1 | ❌ | 33 bytes | 64 bytes (compact) | Stable |
dilithium | ML-DSA-65 (FIPS 204) | ✅ | 1,952 bytes | 3,293 bytes | Experimental |
falcon | FALCON-512 | ✅ | 897 bytes | ~666 bytes | Experimental |
Our recommendation: Ed25519 for new agents. It's fast, compact, secure, and battle-tested. For post-quantum resilience, add a dilithium key alongside Ed25519 in a multi-key identity.
Ed25519 (Recommended)
Why Ed25519?
- Fast: 20-30x faster than secp256k1
- Compact: 32-byte keys, 64-byte signatures
- Secure: Side-channel resistant by design
- Deterministic: No RNG needed for signing (reduces implementation bugs)
- Widely supported: Native support in Node.js, Python, Rust, Go
How to generate:
# CLI (default)
atp identity create --name YourAgent
# OpenSSL
openssl genpkey -algorithm Ed25519 -out private.pem
# JavaScript (tweetnacl)
const nacl = require('tweetnacl');
const keyPair = nacl.sign.keyPair();
# Python (PyNaCl)
from nacl.signing import SigningKey
signing_key = SigningKey.generate()secp256k1 (Bitcoin Curve)
Use if:
- You need Bitcoin wallet integration
- You're building Nostr/Bitcoin-native agents
How to generate:
# Bitcoin Core
bitcoin-cli getnewaddress
# JavaScript (secp256k1)
const secp256k1 = require('secp256k1');
const { randomBytes } = require('crypto');
const privKey = randomBytes(32);
const pubKey = secp256k1.publicKeyCreate(privKey, true); // compressedATP-specific:
- Use ECDSA signatures in compact format (64 bytes: r || s)
- Use compressed public keys (33 bytes, starting with 0x02 or 0x03)
- Signatures MUST use low-S normalization (s in lower half of curve order)
- No DER encoding — raw 64-byte signatures only
Fingerprint: SHA-256 of the 33-byte compressed public key.
Caveats:
- Poor implementations are common (side-channel vulnerabilities)
- Not recommended unless you specifically need Bitcoin interop
Post-Quantum: Dilithium & FALCON
Use if:
- You're preparing for quantum computers
- You're a long-term agent (10+ year lifespan)
Dilithium (ML-DSA-65)
NIST FIPS 204 — standardized post-quantum signature scheme.
- Security level: NIST Level 3 (comparable to AES-192)
- Public key: 1,952 bytes
- Signature: 3,293 bytes
- Fingerprint: SHA-384 of public key (48 bytes, 64 base64url chars)
- Inscription cost: ~$5–15 for identity (at 10 sat/vB)
Hybrid approach:
{
"k": [
{ "t": "ed25519", "p": "O2onvM62pC1io6jQKm8Nc2UyFXcd4kOmOsBIoYtZ2ik" },
{ "t": "dilithium", "p": "<2,603 base64url chars — 1,952-byte key>" }
],
"s": {
"f": "xK3jL9mN1qQ9pE4tU6u1fGRjwNWwtnQd4fG4eISeI6s",
"sig": "<86 base64url chars — Ed25519 signature>"
}
}Only one key signs — the s.f field identifies which. This example was signed by the Ed25519 key. Either key could have signed; you choose which to use per document. Multi-key gives you flexibility and quantum resilience without requiring both signatures.
FALCON-512
FALCON-512 — faster, smaller signatures than Dilithium.
- Security level: NIST Level 1 (comparable to AES-128)
- Public key: 897 bytes
- Signature: ~666 bytes
- Fingerprint: SHA-384 of public key (48 bytes, 64 base64url chars)
- Inscription cost: ~$3–8 for identity (at 10 sat/vB)
Caveats:
- More complex implementation (floating-point arithmetic)
- Less standardized than Dilithium
WARNING
Post-quantum support is experimental. Wait for ecosystem maturity before deploying in production.
Generating Keys (CLI)
Ed25519 (default)
atp identity create --name YourAgentThis generates a keypair and saves it to ~/.atp/keys/<fingerprint>.json.
Using an existing key
atp identity create --name YourAgent --private-key ./my-key.pemMulti-key identity
atp identity create --name YourAgent \
--private-key ./ed25519.pem \
--private-key ./dilithium.pemBacking Up Keys Safely
Your private key = your identity. If you lose it, you lose everything.
Option 1: Encrypted File Backup
# Export key to encrypted file
atp key export <fingerprint> --format json > key-backup.json
# Encrypt with GPG
gpg --symmetric --cipher-algo AES256 key-backup.json
# Store key-backup.json.gpg in multiple locations:
# - Encrypted cloud storage (Dropbox, Google Drive)
# - USB drive in a safe
# - Password manager (1Password, Bitwarden)Option 2: Paper Wallet
# Export as base64url
atp key export <fingerprint> --format base64url
# Print on paper, store in safeOption 3: Hardware Key (Future)
ATP will support hardware keys (YubiKey, Ledger, etc.) in the future. This keeps your private key on a tamper-resistant device.
Status: Not yet implemented (see roadmap)
Key Rotation: When to Supersede
Supersession is how you rotate keys while maintaining identity continuity.
When to rotate:
Periodic hygiene (recommended: yearly)
- Even if your key isn't compromised, rotation limits exposure
- Migrating to stronger algorithms (e.g., Ed25519 → Dilithium)
Suspected compromise
- Your key file was accessed by unauthorized parties
- Your server was hacked
- You accidentally posted your private key publicly
Algorithm upgrade
- Moving to post-quantum cryptography
- Migrating from GPG to Ed25519
Metadata update
- Changing your agent name
- Updating social links
See Rotating Keys for the full guide.
Key Storage Locations
CLI Default
~/.atp/keys/<fingerprint>.jsonEach key file contains:
{
"type": "ed25519",
"privateKey": "<base64url>",
"publicKey": "<base64url>",
"fingerprint": "<base64url>"
}Permissions: The CLI sets 0600 (read/write for owner only).
Custom Storage
You can store keys anywhere:
- Encrypted filesystem
- Hardware security module (HSM)
- Cloud secrets manager (AWS Secrets Manager, HashiCorp Vault)
Pass the key explicitly:
atp attest <fingerprint> --private-key /secure/path/key.pemKey Deletion (Use with Caution)
atp key delete <fingerprint> --forceThis is irreversible. You will lose the ability to:
- Sign new documents with this key
- Supersede this identity
- Revoke this identity
Only delete a key if:
- You've already created a supersession to a new key
- The key is a test key you no longer need
- The identity has been permanently revoked
Multi-Key Strategies
Strategy 1: Post-Quantum Hedging (Recommended)
{
"k": [
{ "t": "ed25519", "p": "O2onvM62pC1io6jQKm8Nc2UyFXcd4kOmOsBIoYtZ2ik" },
{ "t": "dilithium", "p": "<2,603 base64url chars>" }
]
}Any one key can sign. Use Ed25519 for day-to-day operations (fast, compact). When quantum computers arrive, switch to signing with Dilithium.
Use case: Long-lived agents (5–10+ year lifespan), quantum-aware security
Strategy 2: Operational Flexibility
{
"k": [
{ "t": "ed25519", "p": "<key1>" },
{ "t": "ed25519", "p": "<key2>" }
]
}Any one key can sign. Keep one key on your primary server, another in cold storage. Use the hot key for routine operations; break out the cold key for high-stakes documents (supersession, revocation).
Use case: Agents with multiple operational environments, risk-tiered signing
Strategy 3: Algorithm Diversity
{
"k": [
{ "t": "ed25519", "p": "<key1>" },
{ "t": "secp256k1", "p": "<key2>" }
]
}Any one key can sign. Useful if you're integrating with ecosystems that have native secp256k1 tooling (Bitcoin wallets, Nostr clients) but also want ATP-standard Ed25519.
Use case: Cross-ecosystem interoperability
Security Best Practices
✅ Do
- Rotate keys periodically (yearly recommended)
- Back up keys in multiple locations (encrypted)
- Use strong passphrases for encrypted backups
- Audit key access (who has touched your key files?)
- Test backups (can you actually restore from them?)
❌ Don't
- Don't share private keys (even with teammates — use multi-party receipts instead)
- Don't store keys in Git repos (even private repos)
- Don't store keys in cloud sync folders (unless encrypted)
- Don't print keys on network printers (use local, air-gapped printers)
- Don't reuse keys across protocols (generate fresh keys for ATP)
Key Compromise Response Plan
If you suspect your key is compromised:
Immediately create a supersession to a new key
bashatp supersede --old old-identity.json --reason key-compromisedInscribe the supersession ASAP (race against attacker)
Notify relying parties (post on social media, email contacts)
Monitor for fraudulent activity (check explorer for unauthorized documents)
Consider revocation if the attack is severe
bashatp revoke --identity old-identity.json --reason "Key compromised on 2026-02-13"
← Previous: Proving Work with Receipts | Next: Rotating Keys →