Security — how Oath protects your keys
Oath (formerly Aperture) is open source. Every claim below links to the real code on GitHub: https://github.com/devdasx/oath-wallet
1. How the recovery phrase is created
128 or 256 bits of entropy from Apple's `SecRandomCopyBytes` (the iPhone's secure random generator). If it fails, creation stops — Oath never falls back to weak randomness.
A SHA-256 checksum (4 or 8 bits) is appended; every 11 bits become one of 2,048 BIP-39 words.
Only Apple CryptoKit and Security are used — no third-party packages. Checked against the official BIP-39 test vectors.
Code: https://github.com/devdasx/oath-wallet/blob/main/Aperture/Sources/Brand/BIP39.swift
2. How the seed is derived
PBKDF2-HMAC-SHA512, 2,048 rounds, salt "mnemonic" + optional passphrase, NFKD-normalised → 64-byte seed. Compatible with any BIP-39 wallet.
Code: https://github.com/devdasx/oath-wallet/blob/main/Aperture/Sources/Brand/BIP39Seed.swift
3. Where keys are stored
Recovery phrase, seed and private keys are encrypted with AES-GCM-256 before being written to the app's on-device database; each record is bound to its wallet (associated data).
The 256-bit master key is generated on the device with SecRandomCopyBytes.
App lock: Face ID, or a PIN stored only as a salted PBKDF2 hash with lockouts.
Never leaves the device: recovery phrase, seed, private keys, PIN. Never logged, never in UserDefaults, never sent over the network.
Code: https://github.com/devdasx/oath-wallet/blob/main/Aperture/Sources/Security/MnemonicVault.swift · https://github.com/devdasx/oath-wallet/blob/main/Aperture/Sources/Database/GRDBBlobStores.swift
4. How a transaction is sent
Authenticate — Face ID or PIN.
Refresh — live nonce, UTXOs, block data and fees fetched just before signing.
Sign — key derived and used inside one closure, off the main thread.
Broadcast — only the signed transaction is sent.
Track — pending entry checked every 3 seconds until confirmed.
Code: https://github.com/devdasx/oath-wallet/blob/main/Aperture/Sources/Wallet/Signing/SendExecutor.swift
5. Optional iCloud backup
Encrypted on the iPhone: PBKDF2-HMAC-SHA256, 600,000 rounds, random 16-byte salt → AES-GCM-256. Only ciphertext reaches iCloud; no copy of the password exists.
Code: https://github.com/devdasx/oath-wallet/blob/main/Aperture/Sources/Security/WalletBackupCrypto.swift
6. Leaked-phrase warning
Importing a phrase or key published in specs or tutorials (e.g. Hardhat, Anvil, Ganache defaults) shows a warning. Built in, no network lookup.
Code: https://github.com/devdasx/oath-wallet/blob/main/Aperture/Sources/Brand/KnownLeakedSeeds.swift
Report a vulnerability
care@oathwallet.org (subject "Security report") · https://github.com/devdasx/oath-wallet/issues
Oath will never ask for your recovery phrase, private key or passkey.