← Back to home
Security in detail

The security architecture, point by point.

The home page shows the effect; this page shows the mechanism, for the curious and for experts. Nothing is left out, including what stays beyond the reach of software alone.

A — The master key

1. Entropy generation

256 bits generated once, when the wallet is created, by the operating system's cryptographic generator (BCryptGenRandom on Windows), never a homemade one. This entropy is never displayed, never written down, never typed by the user, not even at creation time.

2. The device's local vault

The full entropy is encrypted with an OpenPGP identity specific to this device; that identity's private key, protected by your password, is stored in the system vault (Windows Credential Manager). The key derivation cost (S2K) is set to the OpenPGP format's maximum and cannot be configured or lowered through the API used. The vault is decrypted on the fly for each sensitive operation and never kept in memory between two actions.

3. Windows Hello unlock (TPM)

Optionally, a random secret is sealed in a key held by the PC's security chip (TPM 2.0), with a rule that makes the TPM itself refuse any decryption without a fresh Windows Hello check (fingerprint, face or PIN). Unlike DPAPI-style protection, another program in the session can't silently obtain it. The password remains available as a fallback.

4. 2-of-3 Shamir backup kit

Generated once at creation, independent of the local vault. The entropy is split into 3 shares (Shamir's secret sharing): any 2 rebuild everything, a single one reveals nothing. Each share is encrypted with its own OpenPGP identity and a random passphrase, stored alongside it on its medium: protection against a stolen medium therefore relies on the 2-share threshold, not on that encryption. Shares are written to folders or USB drives, read back and checked after writing; several wallets can share one drive, each in a folder under its own name.

5. Backups that stay usable

OpenPGP encryption authenticates each share: the slightest damage (a corrupted bit on a USB drive) is detected instead of yielding a wrong secret. Each kit carries a mark: mixing shares from two different kits is refused, whereas Shamir's scheme alone would silently produce a wrong secret. Share keys don't depend on the computer's clock, and a frozen kit of every past format is restored in every automated test run. Before any restore, the recovered addresses are shown for you to check; "Check my backup drives" re-reads a kit without writing anything, with a yearly reminder.

B — Derivation and signing

6. Multi-network (HD) derivation

From the same master entropy: Ethereum and Bitcoin via BIP32/secp256k1 (m/44'/60'/0'/0/i and m/44'/0'/0'/0/i), Solana via SLIP-0010/ed25519 with a fully hardened path (m/44'/501'/i'/0'), transparent Zcash via m/44'/133'/0'/0/i and shielded (Orchard) via ZIP-32, Dogecoin, Tron, XRP, Stellar (SEP-0005), NEAR, Cardano via CIP-1852 (BIP32-Ed25519), Stacks, Bittensor via sr25519 (Substrate scheme) and Monero following Ledger's scheme. The same address works on every Ethereum-compatible network. An extra profile is just one more derivation index: no change to the security model between 1 profile and 50.

7. Building and signing transactions

Built by the app for Bitcoin, Dogecoin, Ethereum-compatible networks, Solana, Tron, XRP, Stellar, NEAR, Cardano, Stacks and Bittensor, without heavy SDKs; Zcash goes through its developers' official library (librustzcash), Monero through monero-oxide. Deterministic nonces (RFC 6979) for ECDSA signatures, which prevents key extraction through nonce reuse, and "low-S" normalized signatures, checked against official vectors. Tokenized stocks (Token-2022) are refused at send time if the issuer has paused transfers or added a transfer rule the app doesn't handle.

8. Swaps checked before signing

A quote from a third-party service is never signed as is. Depending on the service: THORChain/Maya memo re-read (destination, minimum amount, affiliate); Jupiter transaction simulated and its effects checked (only the sold token leaves, the purchase lands on your address); CoW order signed (EIP-712) with every field verified; LI.FI Bitcoin transaction re-read output by output (single deposit, change back to you, capped fees). App fees are shown before the native confirmation.

C — Active protections

9. Memory wiping

Every plaintext secret (entropy, shares, passwords) is wiped from memory as soon as it's no longer used, whatever the exit path, early error return or panic included. Memory locking (the equivalent of mlock/VirtualLock) also keeps these areas from being written to disk through the swap file.

10. Anti-guessing lockout

A persisted failure counter imposes a growing delay after 5 wrong passwords, doubled with each new failure and capped at 5 minutes. An internal lock stops a script that tries several passwords in parallel from getting around that counter.

11. Checked addresses

An Ethereum address whose EIP-55 checksum doesn't match is rejected. An address one character away from a contact or an already-paid address triggers a warning (address poisoning), and an address from another network is flagged before sending, with the network to pick.

12. External link allowlist

Only the block explorers actually used by the app can be opened from the history: a real list of known domains, not just a check of the https:// scheme.

13. Automatic lock

After 10 minutes of inactivity, back to the unlock screen, and derived keys are forgotten on the Rust side.

D — Trust boundary

14. The interface is never trusted

A strict CSP keeps the interface from contacting any server directly. It never receives a secret, only public addresses, balances and transaction IDs. Its permissions are cut to the bare minimum: no direct access to the file system or the network.

15. Native confirmation before every send

Network, recipient, amount, fee and profile are shown in a Windows dialog, never an HTML window: a compromised interface can neither fake it nor make it disappear. It's followed by a 5-second delay to cancel, enforced on the Rust side, before any signature. Other sensitive actions (deleting the wallet or a profile) go through a separate confirmation window, handled on the Rust side.

E — What these protections don't cover

16. Active malware on the device during use

A keylogger capturing the password, or a read of the process memory at the exact moment of a signature, bypasses these protections without breaking anything. The TPM doesn't change that for the signature itself: it only knows the NIST curves (P-256, P-384), while Bitcoin and Ethereum use secp256k1 and Solana ed25519. This isn't a weakness specific to this project: no purely software wallet can fully protect against it. That's the point of hardware wallets (Ledger, Trezor, supported by the app), where the key never leaves a separate device with its own screen. The answer planned in the app is FROST: a signature shared between the computer and the phone, without the whole key ever existing.

What's not done yet

Code signing, and above all a security audit by an independent firm. None of the protections described here has been validated by a third party yet. The source code, on the other hand, is public: anyone can review it on GitHub.