Vexidus Keypair and Recovery Reference
Keypair Generation (Server-Side)
RPC Method: vex_generateKeypair
Generates an Ed25519 keypair via core/quantum/src/keypair.rs:
curl -X POST https://testnet.vexidus.io -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"vex_generateKeypair","params":[],"id":1}'
Returns:
{
"address": "Vx0...",
"public_key": "<64 hex chars>",
"secret_key": "<64 hex chars>",
"key_type": "Ed25519"
}
How It Works
QuantumKeyPair::generate_classical()creates an Ed25519 signing key (32 bytes) + verifying key (32 bytes) viaed25519-dalek- Address derived:
SHA256(public_key)-> 32 bytes -> base58 withVx0prefix - EVM-compatible address: last 20 bytes of the 32-byte address ->
0xhex
Key Files
| File | Purpose |
|---|---|
core/quantum/src/keypair.rs | QuantumKeyPair -- Ed25519 + Dilithium3 generation, signing, verification |
core/types/src/address.rs | VexidusAddress -- SHA256-based Vx0/Vx1 encoding |
rpc/src/server/vex_impl.rs | vex_generateKeypair RPC implementation |
Dual Key Types
| Type | Pubkey Size | Signature Size | Status |
|---|---|---|---|
| Ed25519 (V0) | 32 bytes | 64 bytes | Active -- used for all signing |
| Dilithium3 (V1) | 1,952 bytes | 3,293 bytes | Implemented, not wired in -- post-quantum ready |
Both are in QuantumKeyPair enum:
Classical { signing_key, verifying_key }-- Ed25519PostQuantum { keypair }-- Dilithium3 viapqc_dilithium
Signature Verification
Current Pipeline
- Bundle signing: Client signs
Blake3(bundle_data)with Ed25519 secret key - Verification in
core/state/src/machine.rs(execute_bundle()):- Checks
account.active_keysfor keys withSIGN_TXpermission - Tries each key: Ed25519 (64-byte sig) or Dilithium3 (3293-byte sig)
- Falls back to
AccountType.public_keyfor backward compat - Pubkey revelation: First signed send from a receive-only account must include
sender_pubkeyon the bundle. Node verifiesSHA256(pubkey)[0..20]matches address, registers key inactive_keys. - Testnet bypass: Warns but allows unsigned bundles (empty signature). Mainnet will reject.
- Checks
Pre-Signed Bundle Submission
curl -X POST https://testnet.vexidus.io -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"vex_submitBundle","params":["<borsh_hex>"],"id":1}'
Guardian Recovery (VSA v2)
Status: Fully Implemented
All operations are live in core/state/src/machine.rs and core/types/src/transaction.rs.
Setup
Operation::SetRecovery {
guardians: Vec<Address>, // Up to 10 Vx0 addresses
threshold: u8, // M-of-N required
timelock_secs: u64, // Delay before finalization (recommended: 48-72 hours)
}
Recovery Flow
- User loses all keys
- Guardians initiate: M-of-N guardians submit
InitiateRecoverywith a new public key - Timelock starts: Stored in
account.recovery_config.pending_recovery - Owner can cancel: If they regain access during timelock, submit
CancelRecovery - After timelock: Anyone submits
FinalizeRecovery-- replaces all account keys with the recovery key
Operations
| Operation | Who Signs | What Happens |
|---|---|---|
SetRecovery | Account owner | Configures guardians, threshold, timelock |
InitiateRecovery | Guardian | Starts recovery with new pubkey, records guardian approval |
CancelRecovery | Account owner | Cancels pending recovery |
FinalizeRecovery | Anyone | After timelock, replaces keys. Requires threshold guardian approvals. |
State
RecoveryConfig {
guardians: Vec<Address>,
threshold: u8,
timelock_secs: u64,
pending_recovery: Option<PendingRecovery>,
}
PendingRecovery {
new_pubkey: Vec<u8>,
new_key_type: KeyType, // Ed25519 or Dilithium3
initiated_at: u64, // Block timestamp
guardian_approvals: Vec<Address>,
}
Key Management (Also Live)
| Operation | Purpose |
|---|---|
AddKey { pubkey, key_type, role } | Add Ed25519 or Dilithium3 key to account |
RemoveKey { pubkey_hash } | Remove a key (must keep at least one) |
RotateKey { old_hash, new_pubkey, new_type } | Atomic swap of one key for another |
Quantum Migration Path
- Phase 1 (Now): Ed25519 only. Wallet SDK compatible (Phantom, MetaMask via bridge).
- Phase 2 (~2028): Users add Dilithium3 key alongside Ed25519 via
AddKey. Either key signs. Address unchanged. - Phase 3 (~2032+): High-value ops require Dilithium3. V0-only accounts get warnings.
The infrastructure is ready -- QuantumKeyPair::generate_post_quantum() works, verification handles both sig sizes. Just not called in production yet.
Security Best Practices
Key Storage
- Store wallet keys with
chmod 600 - Never log or print secret keys in production
- Store backups encrypted on offline media
- For web wallets, use the browser's
SubtleCryptoAPI to encrypt keys at rest
Nonce Management
- Nonces are sequential: transaction with nonce=5 only executes after nonce=4
- Always fetch the current nonce immediately before signing
- If a transaction fails, the nonce is not consumed -- retry with the same nonce
Testnet vs Mainnet
| Behavior | Testnet | Mainnet |
|---|---|---|
| Chain ID | 1618032 | 1618033 |
| Unsigned bundles | Accepted (with warning) | Rejected |
vex_generateKeypair | Available | Disabled |
Never reuse testnet keys on mainnet. Generate fresh keypairs for production.