Z Wallet is a fully client-side, non-custodial cryptocurrency wallet designed for the secure storage and transfer of USDT (Tether) on the TRON (TRC20) blockchain. The system operates entirely within the user's browser — no private key material, mnemonic phrases, or sensitive data is ever transmitted to any external server at any time.
The wallet employs a layered cryptographic architecture: AES-256-GCM for authenticated symmetric encryption of wallet data at rest; PBKDF2-SHA256 with 600,000 iterations for memory-hard key derivation; HMAC-SHA256 for domain-separated password verification without exposing the encryption key; the W3C SubtleCrypto API as the underlying cryptographic engine — providing hardware-accelerated, non-extractable key objects and OS-level entropy; and a constant-time comparison function to eliminate timing side-channels on authentication.
Private keys are never stored. Instead, a BIP-39 compliant mnemonic seed phrase is encrypted and stored locally. The wallet address is derived deterministically from the seed on every unlock — it is never persisted to disk — eliminating the need to store sensitive material beyond the single encrypted vault blob.
Z Wallet supports four interface languages: English, Kurdish (Sorani), Arabic, and Persian (Farsi) — with full RTL layout support for right-to-left scripts. The application is a single self-contained HTML file with zero external runtime dependencies, making it auditable, portable, and censorship-resistant.
The cryptocurrency ecosystem has seen explosive adoption of USDT on the TRON network, which offers sub-cent transaction fees and near-instant settlement. By 2024, TRON carried more USDT volume than any other blockchain — over $50 billion in daily transfer volume. Yet the majority of users rely on custodial wallets: exchanges and web services that hold private keys on behalf of users.
This creates systemic risk. Exchange hacks (Mt. Gox: $450M; FTX: $8B; Binance 2019: $40M), regulatory seizures, and platform insolvency have collectively caused hundreds of billions of dollars in user losses. The fundamental problem is one of key sovereignty: when a third party holds your private key, they hold your assets.
Existing browser-based wallets often introduce security anti-patterns: storing keys in plaintext localStorage, using weak or absent encryption, transmitting key material to remote services for "cloud backup," or relying on unaudited third-party JavaScript libraries that introduce supply-chain risk. Z Wallet is architected from first principles to eliminate each of these attack surfaces.
| Problem | Custodial Wallets | Z Wallet |
|---|---|---|
| Key control | Third party holds keys | User holds encrypted seed only |
| Server dependency | Always online required | Fully offline capable |
| Data exposure | KYC, IP, transaction history | Zero server transmission |
| Seizure risk | Funds can be frozen | Censorship resistant by design |
| Encryption at rest | Varies — often none | AES-256-GCM mandatory |
| Brute-force protection | Server-side rate limit | PBKDF2 600k + exponential lockout |
| XSS protection | Varies | sanitize() on all user input |
| Clipboard security | None | Auto-cleared after 60 seconds |
Z Wallet follows a single-page application (SPA) architecture with zero external runtime dependencies. All cryptographic operations use the browser's native W3C Web Crypto API (SubtleCrypto interface), which provides hardware-accelerated algorithm implementations with non-extractable CryptoKey objects — keys that exist in the browser's secure key store and cannot be read by JavaScript code.
Layered Architecture:
Storage Layer — Vault Schema (localStorage):
| Field | Type | Content | Security Note |
|---|---|---|---|
ver | Integer | Schema version (2) | For migration — not sensitive |
encrypted | Base64 | AES-256-GCM ciphertext | Phrase + name · 1B ver + 32B salt + 12B IV + CT |
verifier | Base64 | HMAC-SHA256 signature | Fast password check · separate key |
verSalt | Base64 | 32-byte random salt | Separate from encryption salt |
name | String | Wallet display name | Non-sensitive plaintext |
created | Integer | Unix timestamp | Non-sensitive |
SHA-256(domain_prefix + normalized_phrase). This reduces the vault's attack surface: even a complete vault leak reveals no blockchain identity.Binary Layout of Encrypted Blob:
| Bytes | Length | Content |
|---|---|---|
| 0 | 1 byte | Version tag (0x02) |
| 1–32 | 32 bytes | PBKDF2 salt (256-bit, random) |
| 33–44 | 12 bytes | AES-GCM IV (96-bit, random) |
| 45–N | variable | AES-GCM ciphertext + 16-byte auth tag |
The cryptographic stack is composed of four independent, composable layers — each addressing a distinct security property:
Layer 1 — Key Derivation: PBKDF2-SHA256 (RFC 8018 / NIST SP 800-132)
User passwords are never used directly as encryption keys. PBKDF2 transforms the password into a 256-bit AES key using a 256-bit cryptographically random salt and 600,000 iterations. The 2023 NIST SP 800-132 recommendation for interactive authentication is 600,000 iterations of SHA-256. This iteration count means that an attacker with a GPU cluster performing 10 billion PBKDF2 operations per second would require approximately 17 hours to exhaust a 6-character password space — and years for a strong 12-character password.
Layer 2 — Authenticated Encryption: AES-256-GCM (FIPS 197 / NIST SP 800-38D)
AES in Galois/Counter Mode provides both confidentiality (no plaintext revealed) and authenticity (any modification to ciphertext is detected). The 128-bit GCM authentication tag ensures integrity. A 96-bit IV is generated freshly for every encryption operation — IV reuse with the same key is the primary failure mode of GCM, so fresh random IVs are mandatory. Additional Authenticated Data (AAD) — composed of the version byte and salt — binds the ciphertext to its metadata, preventing version-downgrade splicing attacks.
Layer 3 — HMAC Verifier: HMAC-SHA256 (RFC 2104 / FIPS 198)
A HMAC-SHA256 signature is derived using a separate PBKDF2 key (iteration count offset by +1 for cryptographic domain separation). This verifier is used for fast password verification before full decryption, preventing unnecessary KDF computation and providing a semantically distinct authentication signal from the encryption layer.
Layer 4 — Timing Safety: Constant-Time Comparison
All cryptographic equality comparisons use a byte-by-byte XOR accumulation function that processes all bytes regardless of early mismatch position. This eliminates timing side-channels that would otherwise allow an attacker to measure password correctness one character at a time.
| Algorithm | Standard | Purpose | Parameters |
|---|---|---|---|
| PBKDF2-SHA256 | RFC 8018 / NIST SP 800-132 | Key derivation | 600k iter, 256-bit salt, 256-bit output |
| AES-256-GCM | FIPS 197 / NIST SP 800-38D | Encryption at rest | 256-bit key, 96-bit IV, 128-bit auth tag |
| HMAC-SHA256 | RFC 2104 / FIPS 198 | Password verifier | 256-bit key separation |
| SHA-256 | FIPS 180-4 | Address derivation, hashing | 256-bit output |
| CSPRNG | W3C Web Crypto API | Salt, IV, mnemonic entropy | OS entropy (/dev/urandom) |
Z Wallet implements a deterministic key model. The root of trust is the mnemonic seed phrase — a sequence of 12 words drawn from the BIP-39 English wordlist (2,048 words). The phrase is generated using crypto.getRandomValues(), the browser's CSPRNG interface backed by OS entropy.
Entropy Analysis:
Word Selection Implementation: Each of the 12 words is selected by generating a 32-bit uniformly random integer via crypto.getRandomValues(new Uint32Array(12)) and computing word = BIP39_WORDLIST[value mod 2048]. The modulo bias for a 2,048-word list with 32-bit integers is negligible: 2³²/2,048 = 2,097,152 exact multiples with zero remainder.
Verification Protocol: After generation, the user is asked to confirm two randomly chosen words from the phrase before the wallet is created. This prevents accidental creation of wallets where the user did not actually record the phrase.
Import Validation: When importing, Z Wallet validates every word against the full BIP-39 list. Invalid words are identified individually, preventing import of corrupted phrases that would silently derive a different address than intended.
Recovery Flow:
Z Wallet employs a defense-in-depth model — no single mitigation is considered sufficient. Multiple independent controls are layered so that defeating one does not compromise the system. The following table enumerates the complete threat model:
| Threat | Attack Vector | Mitigation | Residual Risk |
|---|---|---|---|
| Brute-force password | Offline dict attack on vault | PBKDF2 600k iter; 30s→480s exponential lockout after 5 failures | Low — requires strong password |
| Timing attack | Measure verifier compare time | Constant-time timingSafeEqual() — all bytes always processed | Negligible |
| Ciphertext tampering | Modify blob in localStorage | AES-GCM 128-bit auth tag; any byte change → decryption failure | None — tamper-evident |
| Version downgrade | Swap vault version field | Version byte bound in AAD; splicing from different version fails GCM auth | None |
| XSS injection | Script via memo / address field | sanitize() on all input; textContent not innerHTML throughout | Low |
| Session key leak | Read wallet from JS memory | Wallet in closure only; no global key variable; auto-locks in 5 min idle | Low |
| Clipboard sniffing | Extension reads clipboard | Clipboard programmatically cleared after 60 seconds | Low |
| Physical / idle access | Access unlocked device | 5-min idle auto-lock; 30-min absolute session timeout; activity tracking | Medium — physical security is user responsibility |
| Supply chain attack | Malicious NPM / CDN library | Zero external runtime dependencies; all code inline; Web Crypto API only | Low |
| Vault metadata leak | Address in localStorage → identity | Address not stored; rederived on unlock only | None |
| Weak mnemonic entropy | Math.random() prediction | CSPRNG via crypto.getRandomValues() backed by OS entropy | None |
| Corrupt phrase import | Wrong address silently derived | All 12 words validated against BIP-39 list before acceptance | Low |
| Weak password accepted | Short / dictionary password | Min 10 chars; strength scorer rejects score < 2; strength meter shown | Low |
Z Wallet implements a local transaction ledger stored separately from the encrypted vault in localStorage. This ledger contains only transaction metadata — no cryptographic key material is ever present.
TRC20 Address Validation: All recipient addresses are validated using the TRC20 Base58Check format before any transaction can proceed. Validation rules: (1) must begin with the character T; (2) must be exactly 34 characters in length; (3) must use only Base58 characters (excluding ambiguous characters 0, O, I, l); (4) checked via regex /^T[1-9A-HJ-NP-Za-km-z]{33}$/.
Amount Validation Rules:
| Rule | Implementation | Rationale |
|---|---|---|
| Non-negative, non-zero | parseFloat(val) > 0 | Prevents zero-value transactions |
| Sufficient balance | amount ≤ available_balance | Prevents overdraft |
| No scientific notation | Regex blocks e character | Prevents 1e5 = 100,000 exploits |
| Max 6 decimal places | Decimal count check | USDT precision standard |
| Finite number | isFinite(n) | Blocks Infinity / NaN inputs |
| Confirmation step | Preview modal before commit | Irreversibility — human review required |
Transaction Record Schema:
| Field | Type | Description |
|---|---|---|
id | String | "ZW" + base36 timestamp — locally unique |
type | "send" | "receive" | Transaction direction |
addr | String (TRC20) | Counterparty address — validated |
amount | Number | USDT amount (max 6 decimal precision) |
memo | String | Optional note (max 100 chars, sanitized via sanitize()) |
date | ISO 8601 | Browser-local timestamp |
status | "completed" | "pending" | Settlement state |
Z Wallet is designed with privacy by default and privacy by design principles as defined in ISO/IEC 29101. The application transmits no data to any server during normal wallet operations. No telemetry, no analytics, no remote logging — the application is behaviorally equivalent to a local native application.
Data Minimization: Only the minimum data required for wallet function is stored locally. The vault contains only the encrypted seed phrase and wallet name. The transaction ledger contains only the data shown to the user in the history view. No IP addresses, browser fingerprints, device identifiers, or behavioral data are collected or retained.
Local-Only Storage: All data resides in browser localStorage — scoped to the page origin, inaccessible to other origins, and never transmitted over any network. The application works entirely offline after initial load.
| Data Category | Stored? | Location | Encrypted? |
|---|---|---|---|
| Mnemonic seed phrase | Yes | localStorage (vault) | AES-256-GCM ✓ |
| Wallet name | Yes | localStorage (vault) | Plaintext (non-sensitive) |
| TRC20 address | No | Memory only (session) | N/A — not persisted |
| Password | No | Never stored anywhere | N/A |
| Transaction history | Yes | localStorage (tx ledger) | Unencrypted — user visible |
| IP / device info | No | Not collected | N/A |
| Analytics / telemetry | No | Not collected | N/A |
Z Wallet v2.0 has been designed and self-reviewed against the following security standards and compliance frameworks. An independent third-party security audit is scheduled for v2.1 prior to public production release.
Implemented Controls by Standard:
| Standard | Requirement | Z Wallet Implementation |
|---|---|---|
| NIST SP 800-132 (2023) | PBKDF2 ≥ 600,000 iterations (SHA-256) for interactive logins | ✓ 600,000 iterations enforced |
| NIST SP 800-38D | AES-GCM: 96-bit IV, 128-bit authentication tag | ✓ 96-bit IV (random), 128-bit tag |
| FIPS 197 | AES with 256-bit key length | ✓ AES-256 |
| RFC 8018 (PKCS #5) | PBKDF2 specification with SHA-256 PRF | ✓ PBKDF2-SHA256 |
| RFC 2104 | HMAC with SHA-256 for message authentication | ✓ HMAC-SHA256 verifier |
| BIP-39 | 12-word mnemonic from 2048-word wordlist | ✓ Full BIP-39 English list |
| W3C Web Crypto API | SubtleCrypto for all crypto operations | ✓ Exclusive use of SubtleCrypto |
| OWASP A03 (Injection) | Sanitize all user input | ✓ sanitize() on all user-supplied data |
| OWASP A07 (Auth Failures) | Protect against brute-force | ✓ Exponential lockout + PBKDF2 cost |
| OWASP A02 (Crypto Failures) | Strong algorithms, no deprecated methods | ✓ No MD5/SHA1/DES/RC4/ECB used |
In-Application Audit Log: Z Wallet maintains an in-memory (non-persistent) audit log of security-sensitive events: password changes, phrase reveals, wallet recovery, and send operations. This log is available in the Settings → Security panel during the active session and is cleared on lock or page close.
A core tension in cryptographic system design is the conflict between security cost and user experience. Higher PBKDF2 iteration counts make brute-force harder — but also make every legitimate unlock slower. Z Wallet resolves this with a two-phase authentication protocol:
Phase 1 — Fast HMAC Verification: Before performing the computationally expensive full AES-GCM decryption, the application computes a HMAC-SHA256 verifier using the same PBKDF2-derived key family. An incorrect password fails at this stage in the same time as a correct one (constant-time), providing an early rejection signal without leaking timing information.
Phase 2 — Full Decryption (on correct password): Full AES-256-GCM decryption of the vault is performed only after the HMAC verifier passes. The decrypted payload is held in memory for the session duration.
Measured Performance (2024 mid-range hardware):
| Operation | Time (approx.) | Notes |
|---|---|---|
| Wallet creation (PBKDF2 + AES-GCM) | ~400–800ms | One-time operation |
| Unlock (HMAC verify + PBKDF2 + decrypt) | ~400–900ms | Two KDF computations |
| Wrong password rejection | ~400ms | Same timing as correct — no timing leak |
| Send transaction | <10ms | Local ledger only — no network call |
| QR code generation | <5ms | Canvas-based, no library |
UX Design Principles:
The interface is designed around three principles: (1) Clarity — every security-relevant action (send, phrase reveal) requires a confirmation step; (2) Feedback — password strength is shown in real-time, lockout countdowns are displayed; (3) Accessibility — full RTL layout support for Arabic, Kurdish, and Persian users; minimum touch target size of 42px; high-contrast color system with a minimum 4.5:1 contrast ratio.
Z Wallet v2.0 introduces full internationalization (i18n) support for four languages, selected to serve the primary user communities in the Middle East, Central Asia, and globally:
| Language | Code | Script | Direction | Region |
|---|---|---|---|---|
| English | en | Latin | LTR | Global |
| Kurdish (Sorani) | ku | Arabic-based Kurdish | RTL | Iraq, Iran, Syria, Turkey |
| Arabic | ar | Arabic | RTL | 22 countries, 400M speakers |
| Persian (Farsi) | fa | Perso-Arabic | RTL | Iran, Afghanistan, Tajikistan |
Technical Implementation:
The i18n system uses a data attribute pattern: HTML elements are annotated with data-i18n="key" attributes. The setLang(code) function performs a DOM traversal, updating the textContent of all annotated elements from the active translation dictionary. RTL languages automatically set document.dir = 'rtl' and html.lang = code, triggering CSS layout mirroring for all flex/grid containers.
RTL Layout Considerations: All sidebar navigation, topbar elements, form fields, and modal dialogs use CSS logical properties and flex-direction reversals under the [dir="rtl"] selector. Font stacks for Arabic-script languages default to system fonts (Segoe UI Arabic, Arial Unicode) when Google Fonts are unavailable, ensuring correct rendering offline.
Language Persistence: The selected language is stored in localStorage under a separate key and restored on next load, providing a persistent preference across sessions.
Translation Coverage:
| UI Area | Keys Translated |
|---|---|
| Setup / Create Wallet | Wallet name, password labels, buttons, hints |
| Unlock Screen | Welcome message, password label, unlock button |
| Dashboard | Balance label, action buttons, section headings |
| Send / Receive | All labels, hints, errors, confirmation modal |
| History | Title, filters, empty state |
| Settings | All section titles, row labels, button text |
| Whitepaper | Section titles, TOC entries, callout labels |
| Navigation tooltips | All 6 nav items |
| Version | Feature Set | Status |
|---|---|---|
| v1.0 | AES-256-GCM encryption, PBKDF2 KDF, BIP-39 mnemonic, Send/Receive, Transaction history | ✓ COMPLETE |
| v2.0 | PBKDF2 600k iterations, HMAC verifier, 256-bit salt, constant-time compare, exponential lockout, 5-min auto-lock, XSS sanitizer, clipboard clear, multi-language (EN/KU/AR/FA), 15-page whitepaper | ✓ COMPLETE |
| v2.1 | Live TRC20 balance via TronGrid API, real transaction broadcast, TronScan block explorer links, third-party security audit | IN PROGRESS |
| v2.2 | BIP-44 hierarchical deterministic (HD) derivation, multiple accounts per seed, address indexing and rotation | PLANNED |
| v3.0 | TRC10/TRC20 arbitrary token support, token import by contract address, token price feeds | PLANNED |
| v3.1 | Hardware wallet support (Ledger via WebUSB/WebHID), biometric unlock (WebAuthn FIDO2), offline transaction signing | RESEARCH |
| v4.0 | WalletConnect v2 protocol, JustSwap DEX integration, TronLink compatibility layer, DeFi position tracking | RESEARCH |
Open Source Commitment: Z Wallet will be published as open-source software under the MIT License. The single-file architecture is intentionally designed for auditability: the complete application — all HTML, CSS, JavaScript, and cryptographic logic — fits in a single file that any developer can read, verify, and run locally without a build system.
Z Wallet is provided as an open-source software tool for personal use. It is not a financial institution, exchange, money services business, or custodial service. It does not hold, custody, control, or transmit user funds at any time.
Users are solely responsible for: (1) the security and integrity of their device and browser environment; (2) safeguarding their mnemonic recovery phrase — loss of the phrase means permanent, unrecoverable loss of access to all associated funds; (3) compliance with applicable laws, regulations, and tax obligations in their jurisdiction; (4) the accuracy of recipient addresses — cryptocurrency transactions on the TRON network are cryptographically irreversible once confirmed.
No Warranty: This software is provided "as is" without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non-infringement. In no event shall the authors be liable for any loss of funds, data, profits, or other damages arising from the use or inability to use this software.
Blockchain Irreversibility: Cryptocurrency transactions cannot be reversed, cancelled, or recalled after broadcast. Z Wallet implements a mandatory confirmation step before any send operation, but users remain solely responsible for verifying recipient addresses independently of any application-layer display.
| # | Reference | Identifier |
|---|---|---|
| [1] | NIST SP 800-132: Recommendation for Password-Based Key Derivation (2023) | csrc.nist.gov/publications/detail/sp/800-132 |
| [2] | NIST SP 800-38D: AES-GCM Recommendation | csrc.nist.gov/publications/detail/sp/800-38d |
| [3] | FIPS 197: Advanced Encryption Standard (AES) | csrc.nist.gov/publications/detail/fips/197 |
| [4] | RFC 8018: PKCS #5 — Password-Based Cryptography Specification v2.1 | tools.ietf.org/html/rfc8018 |
| [5] | RFC 2104: HMAC — Keyed-Hashing for Message Authentication | tools.ietf.org/html/rfc2104 |
| [6] | BIP-39: Mnemonic code for generating deterministic keys | github.com/bitcoin/bips/blob/master/bip-0039.mediawiki |
| [7] | W3C Web Cryptography API (SubtleCrypto) | w3.org/TR/WebCryptoAPI/ |
| [8] | OWASP Top Ten 2021 — Web Application Security Risks | owasp.org/www-project-top-ten/ |
| [9] | TRON TRC20 Token Standard | developers.tron.network/docs/trc20 |
| [10] | Tether (USDT) Technical Documentation | tether.to/en/transparency |
| [11] | ISO/IEC 29101: Privacy Architecture Framework | iso.org/standard/75293.html |
| [12] | FIPS 180-4: Secure Hash Standard (SHA-256) | csrc.nist.gov/publications/detail/fips/180/4 |
| [13] | FIPS 198-1: The Keyed-Hash Message Authentication Code (HMAC) | csrc.nist.gov/publications/detail/fips/198/1 |