The Wallet Authentication Backend (WAB) and WabClient system implements a sophisticated multi-key authentication scheme based on a 2-of-3 threshold cryptographic system. The system creates a wallet's rootKey (actually called rootPrimaryKey in the code) by combining any 2 of 3 authentication factors through XOR operations and symmetric encryption, not through simple XOR as initially assumed.
The system uses three authentication factors:
- Presentation Key - A 256-bit key provided by external authentication (e.g., from WAB after phone/ID verification)
- Password Key - Derived from user password using PBKDF2 with 7,777 rounds and SHA-512
- Recovery Key - A randomly generated 256-bit backup key saved by the user
The system maintains two root keys:
- Root Primary Key (
rootPrimaryKey) - Used for wallet operations and key derivation - Root Privileged Key (
rootPrivilegedKey) - Used for administrative operations and encrypting sensitive data
The system is NOT a simple XOR of 2 keys. Instead, it uses a sophisticated encryption scheme where the rootPrimaryKey is encrypted using symmetric encryption with XOR-derived keys:
passwordPresentationPrimary = SymmetricEncrypt(rootPrimaryKey, XOR(presentationKey, passwordKey))
passwordRecoveryPrimary = SymmetricEncrypt(rootPrimaryKey, XOR(passwordKey, recoveryKey))
presentationRecoveryPrimary = SymmetricEncrypt(rootPrimaryKey, XOR(presentationKey, recoveryKey))
This creates three encrypted versions of the rootPrimaryKey, each protected by a different combination of 2 authentication factors.
The system supports three authentication modes:
- presentation-key-and-password (default)
- presentation-key-and-recovery-key
- recovery-key-and-password
The User Management Protocol (UMP) token stores all encrypted key combinations on-chain:
interface UMPToken {
// Primary key encrypted with different factor combinations
passwordPresentationPrimary: number[] // rootPrimaryKey encrypted with XOR(presentation, password)
passwordRecoveryPrimary: number[] // rootPrimaryKey encrypted with XOR(password, recovery)
presentationRecoveryPrimary: number[] // rootPrimaryKey encrypted with XOR(presentation, recovery)
// Privileged key encrypted combinations
passwordPrimaryPrivileged: number[] // rootPrivilegedKey encrypted with XOR(password, rootPrimary)
presentationRecoveryPrivileged: number[] // rootPrivilegedKey encrypted with XOR(presentation, recovery)
// Key hashes for lookup
presentationHash: number[] // SHA-256(presentationKey)
recoveryHash: number[] // SHA-256(recoveryKey)
// Encrypted key backups (using rootPrivilegedKey)
presentationKeyEncrypted: number[] // presentationKey encrypted with rootPrivilegedKey
passwordKeyEncrypted: number[] // passwordKey encrypted with rootPrivilegedKey
recoveryKeyEncrypted: number[] // recoveryKey encrypted with rootPrivilegedKey
// PBKDF2 salt and metadata
passwordSalt: number[] // Salt for PBKDF2 password derivation
profilesEncrypted?: number[] // Optional encrypted user profiles
currentOutpoint?: string // Blockchain location
}When a user authenticates, the system:
-
Identifies the user by looking up their UMP token using the hash of their provided key (presentation or recovery)
-
Derives the password key (if password provided):
passwordKey = PBKDF2(password, passwordSalt, 7777, 32, 'sha512')
-
Computes the XOR combination key:
// For presentation-key-and-password mode: xorKey = XOR(presentationKey, passwordKey)
-
Decrypts the root primary key:
rootPrimaryKey = SymmetricDecrypt(passwordPresentationPrimary, xorKey)
-
Sets up the privileged key manager to derive the root privileged key when needed
The WAB (Wallet Authentication Backend) handles external authentication:
- WABClient generates a temporary presentation key for authentication flows
- Authentication methods (Twilio SMS, Persona ID verification) validate the user
- WAB server returns the final presentation key upon successful authentication
- WalletAuthenticationManager uses this key with the UMP system to unlock the wallet
For new users, the system:
- Generates random
rootPrimaryKeyandrootPrivilegedKey - Generates random
recoveryKeyand saves it viarecoveryKeySaver - Derives
passwordKeyfrom user password using PBKDF2 - Creates all encrypted combinations using XOR and symmetric encryption
- Publishes the UMP token on-chain via overlay networks
- Threshold Security: Any 2 of 3 factors can recover the wallet
- Forward Security: Compromise of 1 factor doesn't compromise the wallet
- Key Rotation: Individual factors can be changed while preserving wallet access
- Distributed Storage: UMP tokens are stored on-chain, not on centralized servers
- Privacy: Only key hashes are publicly visible, not the keys themselves
Key implementation files:
wallet-toolbox/src/CWIStyleWalletManager.ts- Main UMP token and key management logicwallet-toolbox/src/WalletAuthenticationManager.ts- WAB integration layerwallet-toolbox/src/wab-client/WABClient.ts- Client for WAB authenticationwab/src/- WAB server implementation for external authentication
The system is not simply XORing 2 of 3 keys together to create the rootKey. Instead, it's a sophisticated threshold cryptographic system that encrypts the rootPrimaryKey using symmetric encryption with keys derived from XOR combinations of authentication factors. This provides better security properties and enables secure key rotation while maintaining the 2-of-3 recovery guarantee.