Skip to main content

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

  1. QuantumKeyPair::generate_classical() creates an Ed25519 signing key (32 bytes) + verifying key (32 bytes) via ed25519-dalek
  2. Address derived: SHA256(public_key) -> 32 bytes -> base58 with Vx0 prefix
  3. EVM-compatible address: last 20 bytes of the 32-byte address -> 0x hex

Key Files

FilePurpose
core/quantum/src/keypair.rsQuantumKeyPair -- Ed25519 + Dilithium3 generation, signing, verification
core/types/src/address.rsVexidusAddress -- SHA256-based Vx0/Vx1 encoding
rpc/src/server/vex_impl.rsvex_generateKeypair RPC implementation

Dual Key Types

TypePubkey SizeSignature SizeStatus
Ed25519 (V0)32 bytes64 bytesActive -- used for all signing
Dilithium3 (V1)1,952 bytes3,293 bytesImplemented, not wired in -- post-quantum ready

Both are in QuantumKeyPair enum:

  • Classical { signing_key, verifying_key } -- Ed25519
  • PostQuantum { keypair } -- Dilithium3 via pqc_dilithium

Signature Verification

Current Pipeline

  1. Bundle signing: Client signs Blake3(bundle_data) with Ed25519 secret key
  2. Verification in core/state/src/machine.rs (execute_bundle()):
    • Checks account.active_keys for keys with SIGN_TX permission
    • Tries each key: Ed25519 (64-byte sig) or Dilithium3 (3293-byte sig)
    • Falls back to AccountType.public_key for backward compat
    • Pubkey revelation: First signed send from a receive-only account must include sender_pubkey on the bundle. Node verifies SHA256(pubkey)[0..20] matches address, registers key in active_keys.
    • Testnet bypass: Warns but allows unsigned bundles (empty signature). Mainnet will reject.

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

  1. User loses all keys
  2. Guardians initiate: M-of-N guardians submit InitiateRecovery with a new public key
  3. Timelock starts: Stored in account.recovery_config.pending_recovery
  4. Owner can cancel: If they regain access during timelock, submit CancelRecovery
  5. After timelock: Anyone submits FinalizeRecovery -- replaces all account keys with the recovery key

Operations

OperationWho SignsWhat Happens
SetRecoveryAccount ownerConfigures guardians, threshold, timelock
InitiateRecoveryGuardianStarts recovery with new pubkey, records guardian approval
CancelRecoveryAccount ownerCancels pending recovery
FinalizeRecoveryAnyoneAfter 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)

OperationPurpose
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 SubtleCrypto API 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

BehaviorTestnetMainnet
Chain ID16180321618033
Unsigned bundlesAccepted (with warning)Rejected
vex_generateKeypairAvailableDisabled

Never reuse testnet keys on mainnet. Generate fresh keypairs for production.