Skip to Content
Wallet-Based Identity

Wallet-Based Identity

How Zentalk uses cryptographic wallet addresses as the foundation for user identity.


Why Wallet-Based Identity?

Traditional messaging systems use problematic identity models. Zentalk takes a fundamentally different approach.

Problems with Username/Password

IssueRisk
Server stores credentialsDatabase breaches expose all users
Password recoveryServer can reset your identity
Centralized controlService can lock you out
Phishing attacksUsers tricked into revealing passwords
Weak passwordsMost users choose guessable passwords

The fundamental problem: Your identity exists on someone else’s server. They can impersonate you, lock you out, or hand over access to authorities.

Problems with Phone Number Identity

IssueRisk
SIM swap attacksAttacker ports your number, steals identity
Carrier cooperationGovernments can request number transfers
Privacy leakPhone number links to real-world identity
Recycled numbersPrevious owner receives your messages
Regional restrictionsNumbers tied to countries

The fundamental problem: Your phone number is controlled by your carrier, not by you.

Benefits of Cryptographic Identity

PropertyBenefit
Self-sovereignYou control your identity completely
PortableMove between devices and services
DecentralizedNo single point of failure
Cryptographically secureCannot be guessed or brute-forced
PseudonymousNo link to real-world identity required
VerifiableOthers can prove your identity mathematically

The solution: Your identity is a cryptographic key pair. Only you possess the private key. Your identity cannot be seized, reset, or transferred without your explicit action.


How Wallet Identity Works

Wallet Address Derivation

Your Zentalk identity starts with key generation:

1. Generate random seed (256 bits of entropy) 2. Derive master key using BIP-39 mnemonic 3. Generate Ed25519 keypair from master key 4. Wallet address = encode(hash(public_key))

Example address: zk1qxy7f8h9j2k3m4n5p6q7r8s9t0u1v2w3x4y5z6

The address is a compressed, human-readable representation of your public key.

Key Hierarchy

Zentalk uses a hierarchical key structure:

KeyDerivationPurpose
Master SeedRandom entropyRoot of all keys
Wallet KeyDerived from seedIdentity and authentication
Identity Key (IK)Derived from walletSigning, X3DH identity
Device KeysPer-device derivationMulti-device support

Wallet Key vs Identity Key

Are they the same key? No, but they are mathematically related.

AspectWallet KeyIdentity Key
Algorithmsecp256k1 (Ethereum compatible)Ed25519
PurposeAuthentication, on-chain operationsMessage signing, X3DH
DerivationDirect from seedDerived from wallet key
ExposureUsed for challengesPublished in key bundle

Why separate keys?

  1. Algorithm optimization: Ed25519 is faster and simpler for signatures
  2. Protocol compatibility: X3DH requires Ed25519/X25519 keys
  3. Risk isolation: Compromising one key doesn’t compromise the other
  4. Blockchain compatibility: Wallet key works with Ethereum/EVM chains

Derivation relationship:

Master Seed | +-- Wallet Key (secp256k1) | | | +-- On-chain identity registration | +-- Authentication challenges | +-- Identity Key (Ed25519) | +-- X3DH key exchange +-- Message signing +-- Key bundle signatures

Both keys prove ownership of the same identity because they derive from the same seed.


Authentication Flow

Challenge-Response Protocol

When you connect to a Zentalk server, you prove identity ownership without revealing your private key.

┌─────────────┐ ┌─────────────┐ │ Client │ │ Server │ └──────┬──────┘ └──────┬──────┘ │ │ │ 1. Request authentication │ │ ─────────────────────────────────► │ │ { wallet_address } │ │ │ │ 2. Challenge │ │ ◄───────────────────────────────── │ │ { nonce, timestamp, server_id } │ │ │ │ 3. Signed response │ │ ─────────────────────────────────► │ │ { signature, wallet_address } │ │ │ │ 4. JWT token │ │ ◄───────────────────────────────── │ │ { token, expires_at } │ │ │

Challenge Structure

The server generates a challenge containing:

{ "nonce": "a1b2c3d4e5f6...", "timestamp": 1704067200, "server_id": "node-eu-west-1", "version": 1, "action": "authenticate" }
FieldPurpose
nonceRandom value (32 bytes), prevents replay
timestampUnix timestamp, expires in 60 seconds
server_idIdentifies the requesting server
versionProtocol version for future compatibility
actionWhat the signature authorizes

Client Signature

The client signs the challenge:

message = canonical_json(challenge) signature = secp256k1_sign(wallet_private_key, sha256(message))

Why SHA-256 before signing? The message is hashed first to ensure constant-size input and prevent length extension attacks.

Replay Attack Prevention

Multiple mechanisms prevent replay attacks:

MechanismProtection
NonceEach challenge unique, cannot reuse signature
TimestampChallenge expires after 60 seconds
Server IDSignature only valid for specific server
Action fieldSignature cannot be used for different operations

Attack scenario prevented:

  1. Eve intercepts Alice’s authentication signature
  2. Eve tries to replay the signature to the server
  3. Server rejects: nonce already used OR timestamp expired

JWT Token Generation

After successful verification, the server issues a JWT:

{ "header": { "alg": "ES256", "typ": "JWT" }, "payload": { "sub": "zk1qxy7f8h9j2k3m4n5p6q7r8s9t0u1v2w3x4y5z6", "iat": 1704067200, "exp": 1704153600, "iss": "zentalk-api", "device_id": "device-abc123" } }
FieldMeaning
subWallet address (subject)
iatIssued at timestamp
expExpiration (24 hours default)
issIssuing service
device_idDevice that authenticated

Token refresh: Before expiration, clients can request a new token using the existing valid token, without re-signing.


Identity Verification

Key Fingerprints

Users verify each other’s identity using fingerprints derived from identity keys:

fingerprint = SHA-256(identity_public_key) display = format_as_blocks(fingerprint)

Display format:

37291 84756 19283 04857 29184 73829 18374 02948

Why numeric format?

  • Easier to read aloud during verification
  • Less prone to transcription errors than hex
  • Can be verified over phone call

Out-of-Band Verification

Users should verify fingerprints through a separate channel:

MethodSecurity LevelUse Case
In personHighestHigh-security contacts
Video callHighRemote but visual confirmation
Phone callMediumVoice recognition adds assurance
Trusted third partyMediumMutual contact vouches
QR code scanHighQuick in-person exchange

Verification ceremony:

  1. Alice and Bob meet in person
  2. Each opens Zentalk settings and shows fingerprint
  3. Each reads their fingerprint aloud
  4. Both confirm the displayed fingerprint matches what they hear
  5. Mark contact as “verified” in the app

Trust On First Use (TOFU)

For casual conversations, Zentalk uses TOFU:

EventBehavior
First messageAccept identity key, store fingerprint
Subsequent messagesVerify against stored fingerprint
Key change detectedWarning displayed, require acknowledgment

TOFU limitations:

  • Does not protect against MITM on first contact
  • User must verify for high-security conversations
  • Key rotation requires re-verification

Safety Numbers

Similar to Signal, Zentalk generates safety numbers for each conversation:

safety_number = SHA-256( sort(identity_key_A, identity_key_B) || "ZentalkSafetyNumber" )

Properties:

PropertyMeaning
Unique per pairDifferent for Alice-Bob vs Alice-Carol
Order independentAlice sees same number as Bob
Changes on key rotationAlerts both parties

When safety number changes:

Security alert: Your safety number with Bob has changed. This could mean: - Bob reinstalled Zentalk - Bob switched devices - Someone is intercepting your messages Verify Bob's new fingerprint before continuing.

Account Creation

What Happens When You Create an Account

┌─────────────────────────────────────────────────────────────┐ │ Account Creation Flow │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 1. Generate entropy (256 bits from secure RNG) │ │ │ │ │ ▼ │ │ 2. Create BIP-39 mnemonic (12 or 24 words) │ │ │ │ │ ▼ │ │ 3. Derive master seed from mnemonic │ │ │ │ │ ▼ │ │ 4. Generate wallet keypair (secp256k1) │ │ │ │ │ ▼ │ │ 5. Generate identity keypair (Ed25519) │ │ │ │ │ ▼ │ │ 6. Generate initial pre-keys (X25519) │ │ │ │ │ ▼ │ │ 7. Sign pre-keys with identity key │ │ │ │ │ ▼ │ │ 8. Register on network (publish public keys) │ │ │ │ │ ▼ │ │ 9. Store private keys locally (encrypted) │ │ │ └─────────────────────────────────────────────────────────────┘

Key Generation Sequence

Step-by-step breakdown:

// 1. Generate cryptographic entropy const entropy = crypto.getRandomValues(new Uint8Array(32)) // 2. Create mnemonic phrase const mnemonic = bip39.entropyToMnemonic(entropy) // "apple banana cherry dragon eagle frog garden honey igloo jacket kite lemon" // 3. Derive master seed const seed = bip39.mnemonicToSeedSync(mnemonic) // 4. Derive wallet key (secp256k1) const walletKey = deriveKey(seed, "m/44'/60'/0'/0/0") // 5. Derive identity key (Ed25519) const identityKey = deriveEd25519(seed, "m/44'/1991'/0'/0/0") // 6. Generate pre-keys const signedPreKey = generateX25519Keypair() const oneTimePreKeys = Array(100).fill().map(() => generateX25519Keypair()) // 7. Sign pre-keys const spkSignature = ed25519.sign(signedPreKey.publicKey, identityKey.privateKey)

Storage Distribution

DataLocationEncryption
Mnemonic phraseUser’s backup (paper/password manager)None (user responsibility)
Private keysLocal device (IndexedDB)AES-256-GCM + device key
Public identity keyNetwork (API servers)None (public data)
Signed pre-keyNetwork (API servers)None (public data)
One-time pre-keysNetwork (API servers)None (public data)
Wallet addressOn-chain (optional)None (public data)

On-Chain Registration (Optional)

For additional verification, identity can be registered on-chain:

// Simplified identity contract mapping(address => bytes32) public identityKeys; function registerIdentity(bytes32 identityKeyHash) external { require(identityKeys[msg.sender] == 0, "Already registered"); identityKeys[msg.sender] = identityKeyHash; emit IdentityRegistered(msg.sender, identityKeyHash); }

Benefits of on-chain registration:

BenefitDescription
Immutable recordIdentity key change history is permanent
Decentralized lookupAnyone can verify without trusting a server
TimestampedBlockchain provides proof of registration time
Censorship resistantCannot be removed by any party

Identity Portability

Moving to a New Device

Option 1: Recovery phrase

1. Install Zentalk on new device 2. Select "Restore identity" 3. Enter 12/24 word mnemonic 4. All keys are regenerated deterministically 5. Fetch message history from mesh storage

Option 2: Device linking (existing device available)

1. Open Zentalk on both devices 2. New device displays QR code 3. Existing device scans QR code 4. Encrypted key transfer via secure channel 5. New device added to device list

Exporting Identity

Users can export their identity for backup:

Export contents: - Encrypted private key bundle - Identity key (encrypted) - Wallet key (encrypted) - Device key list NOT exported: - Message history (use mesh backup) - Contact list (use mesh backup) - Session state (regenerated)

Export encryption:

1. User provides export password 2. salt = random(32 bytes) 3. key = PBKDF2(password, salt, 600000 iterations) 4. encrypted_bundle = AES-256-GCM(key, private_keys) 5. output = salt || nonce || encrypted_bundle || tag

What Can and Cannot Be Transferred

TransferableNot Transferable
Identity (mnemonic/keys)Active sessions
Contact list (from mesh)Session keys
Message history (from mesh)Ephemeral keys already used
Verified contactsDevice-specific keys
Profile dataPush notification tokens

Why sessions cannot transfer:

Double Ratchet sessions contain ephemeral keys that change with every message. Transferring would require syncing state across devices in real-time, which Zentalk handles through the multi-device protocol instead.

Multi-Device Considerations

When identity exists on multiple devices:

AspectHandling
Same identity keyAll devices share identity
Separate device keysEach device has unique sub-identity
Message syncMesh storage delivers to all devices
Key rotationCoordinated across devices
Device revocationRemove from authorized list

Privacy Properties

Wallet Address as Pseudonym

Your wallet address is a pseudonym:

PropertyPrivacy Impact
No personal dataAddress contains no name, email, phone
Unlinkable to real identityUnless you link it yourself
Multiple addresses possibleCreate separate identities for different contexts
DeterministicSame seed always produces same address

Unlinkability Between Accounts

Users can maintain multiple unlinkable identities:

Seed A → Wallet Address A → Identity A Seed B → Wallet Address B → Identity B No mathematical relationship between A and B

Use cases:

ScenarioWhy Separate Identity
Personal/ProfessionalKeep work and personal contacts separate
ActivismProtect real identity while organizing
WhistleblowingReport wrongdoing without attribution
CompartmentalizationDifferent security levels

Metadata Exposure

DataWho Can SeeMitigation
Wallet addressAnyone you messageUse different addresses
Public keysNetwork serversRequired for encryption
Online statusServersConfigurable, can be hidden
Message timingServersTraffic padding
Contact graphServers3-hop relay hides connections
IP addressServersUse Tor or VPN

What the Server Cannot Learn

DataWhy Server Cannot Access
Message contentE2EE - only recipient has key
Contact namesStored locally, encrypted
Conversation topicsCannot decrypt messages
Private keysNever leave device
Recovery phraseOnly user possesses

Comparison: Identity Models

Zentalk vs Signal vs WhatsApp

AspectZentalkSignalWhatsApp
Identity AnchorWallet addressPhone numberPhone number
RegistrationKey generation onlyPhone verificationPhone verification
Server KnowledgePublic keys onlyPhone number + keysPhone + contacts + metadata
Identity RecoveryMnemonic phrasePhone numberPhone number + backup
Account PortabilityFull (seed phrase)Limited (phone)Limited (phone + cloud)
PseudonymityNativeRequires burnerRequires burner
Multiple AccountsEasy (multiple seeds)Hard (multiple phones)Hard (multiple phones)
DecentralizedYes (mesh + optional chain)No (central servers)No (Meta servers)
SIM Swap RiskNoneHighHigh
Phone PrivacyNo phone neededPhone exposedPhone exposed
VerificationFingerprintsSafety numbersQR code
Key CustodySelf-custodySelf-custodyCloud backup (Meta access)

Identity Attack Vectors

AttackZentalkSignalWhatsApp
SIM SwapNot possibleIdentity theftIdentity theft
Server CompromiseKeys safeKeys safeMetadata exposed
Carrier RequestNot applicableAccount accessAccount access
SubpoenaEncrypted blobs onlyPhone number + metadataFull metadata + contacts
PhishingSeed phrase riskPhone/PIN riskPhone/PIN/2FA risk
Device SeizureEncrypted local dataEncrypted local dataEncrypted + cloud backup

Migration Comparison

ScenarioZentalkSignalWhatsApp
Lost phoneRecover with mnemonicRe-register with phoneRe-register + cloud restore
New phoneImport seedTransfer requires old phoneCloud backup or transfer
Number changeNot applicableComplex migrationComplex migration
Account deletionDelete local keysRequest deletionRequest deletion (data retained)

Security Recommendations

For All Users

ActionBenefit
Backup recovery phrase securelyCan recover identity if device lost
Never share recovery phrasePrevents identity theft
Verify important contactsPrevents MITM attacks
Use unique identities for sensitive contextsCompartmentalization
Enable device PIN/biometricsProtects local keys

For High-Risk Users

ActionBenefit
Use hardware wallet for seedAir-gapped key storage
Create identity on air-gapped devicePrevents key exposure
Use separate identity per contextUnlinkability
Regular key rotationLimits compromise window
Verify all contacts in personMaximum MITM protection

Stealth Addresses

Stealth addresses provide an additional layer of privacy by generating one-time addresses for each transaction or message exchange, preventing address reuse from creating linkable patterns.

What Are Stealth Addresses?

The Problem: Public Address Visibility

In traditional cryptocurrency and messaging systems, wallet addresses are publicly visible on the blockchain or network. This creates significant privacy concerns.

ProblemDescription
Transaction trackingAnyone can monitor all incoming transfers to a known address
Balance surveillanceObservers can calculate total holdings and spending patterns
Address clusteringMultiple transactions can be linked to a single entity
Social graph exposureCommunication patterns reveal relationships
Targeted attacksHigh-value addresses become targets for phishing or coercion

Example scenario:

Alice publishes her Zentalk address: zk1abc123... Bob sends a message to Alice using this address. Eve, monitoring the network, observes this. Later, Carol also messages Alice at the same address. Eve now knows: Alice communicates with both Bob and Carol. Over time, Eve builds a complete map of Alice's contacts.

The Solution: One-Time Addresses

Stealth addresses solve this by generating a unique, unlinkable address for each sender. Even though all payments/messages go to Alice, each appears to go to a completely different address.

PropertyBenefit
UnlinkabilityNo connection between stealth addresses and recipient’s main address
Sender privacyOnly the recipient knows who sent to each address
Recipient privacyObservers cannot determine the true recipient
No coordination requiredSender generates address without recipient interaction

How Stealth Addresses Work

Zentalk implements a dual-key stealth address protocol based on elliptic curve Diffie-Hellman (ECDH). This separates the ability to receive (scan) from the ability to spend (control).

Dual-Key Architecture

Key TypeNamePurposeSecurity Level
View KeyScan KeyDetect incoming messages/paymentsCan be delegated
Spend KeySpend KeyActually access/read messagesMust remain secret

Key Pair Notation

SymbolMeaning
(v, V)Recipient’s view/scan keypair (v = private, V = public)
(s, S)Recipient’s spend keypair (s = private, S = public)
(r, R)Sender’s ephemeral keypair (r = private, R = public)
GElliptic curve generator point
H()Cryptographic hash function (SHA-256)
·Elliptic curve point multiplication

Mathematical Foundation

The stealth address protocol relies on the ECDH key agreement property:

ECDH shared secret: r · V = v · R Where: r = sender's ephemeral private key V = v · G (recipient's public view key) R = r · G (sender's ephemeral public key)

This allows sender and recipient to derive the same shared secret independently:

  • Sender computes: r · V
  • Recipient computes: v · R

Both yield the same point on the elliptic curve.

Protocol Overview

┌─────────────────────────────────────────────────────────────┐ │ Stealth Address Protocol │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Recipient publishes: │ │ Meta-address = (V, S) = (v·G, s·G) │ │ │ │ Sender generates: │ │ 1. Fresh ephemeral keypair (r, R) │ │ 2. Shared secret: shared = H(r · V) │ │ 3. Stealth public key: P = S + shared · G │ │ 4. Sends message to P, attaches R │ │ │ │ Recipient scans: │ │ 1. For each R on network: shared = H(v · R) │ │ 2. Compute expected P = S + shared · G │ │ 3. If P matches, message is for recipient │ │ 4. Derive private key: p = s + shared │ │ │ └─────────────────────────────────────────────────────────────┘

Stealth Address Generation

When a sender wants to contact a recipient using a stealth address, they perform the following steps.

Prerequisites

RequirementDescription
Recipient meta-addressThe tuple (V, S) published by recipient
Secure random sourceFor generating ephemeral keypair
Elliptic curve operationsPoint multiplication and addition

Step-by-Step Generation Process

StepOperationResult
1Generate ephemeral private keyr ← random(256 bits)
2Compute ephemeral public keyR = r · G
3Compute ECDH shared pointsharedPoint = r · V
4Derive shared secret scalarsharedSecret = H(sharedPoint ‖ R)
5Compute stealth public keyP = S + sharedSecret · G
6Derive stealth addressaddress = encode(H(P))

Pseudocode: Stealth Address Generation

function generateStealthAddress(recipientMetaAddress): // Parse recipient's published meta-address V = recipientMetaAddress.viewPublicKey S = recipientMetaAddress.spendPublicKey // Generate fresh ephemeral keypair r = secureRandom(32) // 256 bits R = scalarMultiply(G, r) // Compute shared secret via ECDH sharedPoint = scalarMultiply(V, r) sharedSecret = sha256(sharedPoint || R) // Derive the stealth public key sharedSecretPoint = scalarMultiply(G, sharedSecret) P = pointAdd(S, sharedSecretPoint) // Generate final stealth address stealthAddress = encodeAddress(sha256(P)) return { stealthAddress: stealthAddress, ephemeralPublicKey: R, stealthPublicKey: P }

What Gets Transmitted

ComponentIncludedPurpose
Stealth address PYesDestination for message/payment
Ephemeral public key RYesEnables recipient to derive shared secret
Ephemeral private key rNoDiscarded after generation
Shared secretNoDerived independently by recipient

Security Properties of Generation

PropertyGuarantee
FreshnessNew ephemeral key per address ensures uniqueness
UnlinkabilityCannot link stealth addresses without view key
Forward secrecyEphemeral key discarded; past addresses remain private
Non-interactivityNo communication with recipient required

Recipient Scanning

The recipient must scan the network to detect messages or payments addressed to them via stealth addresses.

Scanning Process

For each announcement (R, P) observed on the network:

StepOperationResult
1Retrieve ephemeral public keyR from announcement
2Compute ECDH shared pointsharedPoint = v · R
3Derive shared secretsharedSecret = H(sharedPoint ‖ R)
4Compute expected stealth keyP’ = S + sharedSecret · G
5Compare with announced keyif P’ = P, message is for us
6Derive private key (if match)p = s + sharedSecret

Pseudocode: Recipient Scanning

function scanForPayments(viewPrivateKey, spendPublicKey, announcements): v = viewPrivateKey S = spendPublicKey myPayments = [] for each (R, P, payload) in announcements: // Compute shared secret using our view key sharedPoint = scalarMultiply(R, v) sharedSecret = sha256(sharedPoint || R) // Derive expected stealth public key sharedSecretPoint = scalarMultiply(G, sharedSecret) expectedP = pointAdd(S, sharedSecretPoint) // Check if this payment is for us if expectedP equals P: myPayments.append({ ephemeralKey: R, stealthKey: P, sharedSecret: sharedSecret, payload: payload }) return myPayments

Deriving the Spending Key

Once a matching stealth address is found, the recipient derives the private key:

function deriveSpendingKey(spendPrivateKey, sharedSecret): s = spendPrivateKey p = scalarAdd(s, sharedSecret) // modular addition return p // Verification: p · G should equal P

Scanning Efficiency Considerations

FactorImpactMitigation
Network volumeEach announcement requires one ECDH operationBatch processing
ECDH costPoint multiplication is computationally expensiveDedicated scanning hardware
StorageMust track all scanned announcementsBloom filters for quick rejection
LatencyScanning must be near real-time for messagesParallel processing

Performance Benchmarks

OperationTime (approx.)Notes
ECDH point multiplication0.1-0.5 msCurve25519 optimized
SHA-256 hash0.001 msNegligible
Point addition0.01 msFast operation
Full scan iteration0.2-0.6 msPer announcement

Scalability Table

Announcements/dayScan time/dayCPU overhead
1,000~0.5 secondsNegligible
100,000~50 secondsLow
1,000,000~8 minutesModerate
10,000,000~80 minutesSignificant

View Key Delegation

A powerful feature of the dual-key architecture is the ability to delegate scanning without compromising spending authority.

View Key Properties

CapabilityView KeySpend Key
Detect incoming messagesYesNo (needs view key)
Read message contentYes (with decryption)No
Send responsesNoYes
Access fundsNoYes
Prove ownershipNoYes

Delegation Use Cases

ScenarioImplementation
Auditor accessShare view key for compliance monitoring
Watch-only walletMobile device with view key only
Scanning serviceThird-party scans on your behalf
Inheritance planningBeneficiary can see activity before full access

Pseudocode: Delegated Scanning Service

// User shares only their view key with scanning service function delegatedScanning(userViewKey, userSpendPublicKey, announcements): // Service can detect payments but cannot spend matches = scanForPayments(userViewKey, userSpendPublicKey, announcements) // Service notifies user of matches for each match in matches: notifyUser(match.ephemeralKey, match.stealthKey) // User derives spending key locally (never shared) // p = s + match.sharedSecret

Security of View Key Sharing

RiskSeverityMitigation
Pattern analysisMediumTrusted scanning services only
Notification delayLowMultiple scanning services
Service compromiseMediumView key reveals timing, not funds
Privacy leakMediumRotate view keys periodically

When Stealth Addresses Are Used

Zentalk employs stealth addresses strategically to balance privacy and efficiency.

Per-Conversation vs Per-Message

ModeDescriptionUse Case
Per-conversationSingle stealth address for entire conversationLong-term contacts, efficiency priority
Per-messageFresh stealth address per messageMaximum privacy, one-time contacts
HybridNew address on significant eventsBalance of privacy and efficiency

Decision Matrix

ScenarioStealth Address ModeRationale
First contact from strangerPer-messageMaximum unlinkability
Established trusted contactPer-conversationEfficiency, lower overhead
Anonymous tip submissionPer-messageNo linkability required
Group chatPer-groupAll members share scanning
High-risk communicationPer-messageCompartmentalization

First Contact Scenarios

When Alice initiates contact with Bob for the first time:

1. Alice obtains Bob's meta-address (V_B, S_B) - From public directory - From QR code - From mutual contact 2. Alice generates stealth address for Bob - Creates ephemeral keypair (r, R) - Computes stealth address P 3. Alice sends message to stealth address P - Includes ephemeral public key R - Message encrypted with derived key 4. Bob scans and detects the message - Computes shared secret with v_B · R - Verifies P matches expected value 5. Subsequent messages - Option A: Continue using same stealth address - Option B: Generate new stealth address per message

Group Chat Considerations

AspectHandling
Stealth address per senderEach member has unique stealth address for group
Scanning overheadMultiplied by group size
Member additionNew stealth addresses distributed
Member removalRotate all stealth addresses
Anonymity within groupSender identity revealed to group only

Group Stealth Address Protocol

Group setup: For each member M_i: - All other members generate stealth address for M_i - M_i scans for N-1 stealth addresses Message to group: Sender S generates stealth addresses for all recipients Message sent to each stealth address Efficiency: O(N) stealth addresses per message O(N²) total scanning for all members

Privacy Properties

Stealth addresses provide strong privacy guarantees when properly implemented.

Unlinkability Analysis

ObserverCan DetermineCannot Determine
Network observerThat a message was sentSender or recipient identity
SenderTheir own sent messagesOther senders to same recipient
RecipientAll messages to themRelationship between their addresses
Third party with view keyIncoming message timingSpending capability

What an Observer Sees

Network observation: [R_1, P_1, encrypted_payload_1] [R_2, P_2, encrypted_payload_2] [R_3, P_3, encrypted_payload_3] Observer's knowledge: - Three messages were sent - Each to a different address - All payloads are encrypted Observer cannot determine: - If any messages share a recipient - Who the senders are - Who the recipients are - Message contents

Comparison: Regular vs Stealth Addresses

PropertyRegular AddressStealth Address
Address reuseSame address used repeatedlyUnique address per sender/message
Balance visibilityTotal visible to allOnly recipient knows full balance
Transaction linkingTrivial to linkComputationally infeasible
Sender anonymityNot providedPreserved
Recipient anonymityNot providedPreserved
Scanning requiredNoYes

Privacy Guarantees

GuaranteeDescriptionAssumption
Recipient unlinkabilityStealth addresses are indistinguishableECDH is secure
Sender unlinkabilityNo link between sender and stealth addressEphemeral key is random
Forward privacyPast addresses remain unlinkableEphemeral keys discarded
Amount privacyCombined with encryptionEncrypted payloads

Attack Resistance

AttackProtection LevelNotes
Timing analysisPartialTraffic padding helps
Volume analysisPartialDummy messages help
Intersection attackStrongRequires view key
Blockchain analysisStrongNo on-chain link
Social engineeringDepends on userView key compromise reveals timing

Limitations

While stealth addresses provide strong privacy, they come with tradeoffs.

Scanning Overhead

LimitationDescriptionImpact
Computational costEvery announcement requires ECDH operationCPU/battery drain
LatencyMust scan before detecting messagesDelayed notifications
ScalabilityCost grows linearly with network activityHigh-volume networks are expensive
Always-on requirementMust scan regularly or miss messagesNot suitable for offline devices

Storage Requirements

DataStorage NeedGrowth Rate
Scanned announcementsTrack to avoid re-scanningLinear with network
Detected stealth addressesStore for spendingLinear with received messages
Ephemeral keys (sender)Temporary during generationConstant (discarded)
Derived spending keysMust persistLinear with received messages

Storage Comparison

Wallet TypeStorage (1000 transactions)Notes
Regular~50 KBJust addresses and keys
Stealth (minimal)~100 KBAdditional ephemeral keys
Stealth (full scanning)~10 MBAnnouncement cache

Compatibility Considerations

IssueDescriptionWorkaround
Existing walletsMay not support stealth addressesWrapper/proxy protocols
Light clientsCannot scan efficientlyScanning service delegation
Hardware walletsLimited computational capacityExternal scanning device
Exchange depositsRequire deterministic addressesView key + scanning infrastructure

Protocol Complexity

AspectComplexity Added
Key managementTwo keypairs instead of one
Address generationMulti-step ECDH computation
Payment detectionActive scanning required
RecoveryMust backup both key pairs
DelegationAdditional security considerations

Tradeoff Summary

FactorWithout StealthWith Stealth
PrivacyLowHigh
EfficiencyHighMedium
SimplicityHighLow
Mobile friendlinessHighMedium
Offline capabilityHighLow
ScalabilityHighMedium

Mitigation Strategies

LimitationMitigation
Scanning costDelegated scanning services
LatencyBackground scanning + push notifications
StorageBloom filters, announcement pruning
ComplexityAbstraction in wallet software
Mobile drainServer-side scanning with view key

Last updated on