// ObsidianDragon Wallet - ImGui Edition // Copyright 2024-2026 The Hush Developers // Released under the GPLv3 #pragma once #include #include #include namespace dragonx { namespace util { /** * @brief PIN-encrypted passphrase vault * * Stores the wallet passphrase encrypted with a PIN-derived key using * libsodium's Argon2id (key derivation) + XSalsa20-Poly1305 (AEAD). * * File format (vault.dat): * [1 byte] version (0x01) * [16 bytes] Argon2id salt * [24 bytes] XSalsa20 nonce * [N bytes] ciphertext (passphrase + 16-byte Poly1305 tag) * * The PIN is 4-8 digits. Argon2id uses moderate ops/mem limits * to resist brute-force on the small PIN space while keeping * unlock time under ~1 second. */ class SecureVault { public: SecureVault(); ~SecureVault(); /** * @brief Check if a vault file exists on disk */ bool hasVault() const; /** * @brief Encrypt passphrase with PIN and save to vault.dat * @param pin The user's PIN (4-8 digits) * @param passphrase The wallet passphrase to protect * @return true on success */ bool store(const std::string& pin, const std::string& passphrase); /** * @brief Decrypt passphrase from vault using PIN * @param pin The user's PIN * @param[out] passphrase The recovered passphrase * @return true if PIN was correct and decryption succeeded */ bool retrieve(const std::string& pin, std::string& passphrase) const; /** * @brief Change the PIN (re-encrypt with new PIN) * @param oldPin Current PIN * @param newPin New PIN * @return true if old PIN was valid and re-encryption succeeded */ bool changePin(const std::string& oldPin, const std::string& newPin); /** * @brief Remove the vault file * @return true if deleted or didn't exist */ bool removeVault(); /** * @brief Validate PIN format (4-8 digits) */ static bool isValidPin(const std::string& pin); /** * @brief Securely zero memory */ static void secureZero(void* ptr, size_t len); /** * @brief Get the vault file path */ static std::string getVaultPath(); private: // Derive a 32-byte key from PIN + salt using Argon2id bool deriveKey(const std::string& pin, const uint8_t* salt, size_t saltLen, uint8_t* key, size_t keyLen) const; }; } // namespace util } // namespace dragonx