Contact Recovery Sequence¶
Interaction Type: +
MIXED (In-Person Vouching + Remote Distribution)
When a user loses all devices, they can recover their contact relationships through social vouching. Existing contacts vouch for the user in-person, and the recovery proof is distributed remotely via relay.
Participants¶
- Alice - User who lost their device
- Alice's New Device - Fresh install, new identity
- Bob, Charlie, Betty - Alice's contacts who will vouch
- John, David - Alice's contacts who will receive recovery proof
- Relay - WebSocket relay server
Overview¶
┌────────────────────────────────────────────────────────────────────────────┐
│ RECOVERY PROCESS │
├────────────────────────────────────────────────────────────────────────────┤
│ │
│ PHASE 1: Vouching (In-Person) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Bob │ │ Charlie │ │ Betty │ │
│ │ Vouch │ │ Vouch │ │ Vouch │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ └──────────────┼──────────────┘ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Alice (new) │ Threshold: 3 vouchers │
│ └──────┬───────┘ │
│ │ │
│ PHASE 2: Distribution (Remote) │
│ ▼ │
│ ┌──────────────┐ │
│ │ Relay │ Stores proof under hash(pk_old) │
│ └──────┬───────┘ │
│ │ │
│ ┌─────────────┼─────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ John │ │ David │ │ Others │ Discover via relay query │
│ │ Accept │ │ Verify │ │ │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────────┘
Phase 1: In-Person Vouching¶
sequenceDiagram
autonumber
participant A as Alice (Lost Device)
participant AN as Alice New Device
participant BB as Bob's Device
participant B as Bob
Note over A,B: IN-PERSON: Alice meets Bob physically
%% Alice creates new identity
A->>AN: Install Vauchi on new device
AN->>AN: Create new identity (pk_new)
A->>AN: "I had identity pk_old"
AN->>AN: Store recovery claim: pk_old → pk_new
%% Generate recovery QR
A->>AN: Generate recovery QR
activate AN
AN->>AN: Create recovery claim QR
Note right of AN: QR contains:<br/>- type: recovery_claim<br/>- old_pk: pk_old<br/>- new_pk: pk_new<br/>- timestamp
AN->>A: Display recovery QR
deactivate AN
%% Bob scans and vouches
B->>BB: Scan Alice's recovery QR
activate BB
BB->>BB: Decode recovery claim
BB->>BB: Lookup pk_old in contacts
BB->>BB: Found: "Alice" with pk_old
BB->>B: "Alice claims device loss"
BB->>B: Show Alice's stored name & photo
deactivate BB
Note over BB,B: Bob verifies Alice is physically present
B->>BB: "Yes, this is Alice, I confirm"
activate BB
BB->>BB: Create voucher
Note right of BB: Voucher:<br/>- old_pk<br/>- new_pk<br/>- voucher_pk (Bob)<br/>- timestamp<br/>- Ed25519 signature
BB->>AN: Send voucher to Alice
deactivate BB
AN->>AN: Store Bob's voucher (1 of 3)
AN->>A: "Bob vouched for you (1/3)"
Note over A,B: Alice now has 1 voucher, needs 2 more
Collecting Multiple Vouchers¶
sequenceDiagram
participant AN as Alice New Device
participant CB as Charlie's Device
participant BB as Betty's Device
Note over AN,BB: IN-PERSON: Alice meets more contacts
%% Charlie vouches
rect rgb(240, 248, 255)
Note over AN,CB: Alice meets Charlie
AN->>CB: Show recovery QR
CB->>CB: Verify pk_old is contact "Alice"
CB->>AN: Send voucher
AN->>AN: Store Charlie's voucher (2 of 3)
end
%% Betty vouches
rect rgb(240, 255, 240)
Note over AN,BB: Alice meets Betty
AN->>BB: Show recovery QR
BB->>BB: Verify pk_old is contact "Alice"
BB->>AN: Send voucher
AN->>AN: Store Betty's voucher (3 of 3)
end
Note over AN: THRESHOLD MET: 3 vouchers collected
AN->>AN: Create recovery proof
Note right of AN: Recovery Proof:<br/>- old_pk<br/>- new_pk<br/>- threshold: 3<br/>- vouchers: [Bob, Charlie, Betty]
Phase 2: Remote Distribution¶
sequenceDiagram
autonumber
participant AN as Alice New Device
participant R as Relay
participant JD as John's Device
participant DD as David's Device
Note over AN,DD: REMOTE: Distribution via relay
%% Upload proof
AN->>R: Upload recovery proof
R->>R: Store under key: hash(pk_old)
R-->>AN: Stored
Note over R: Proof stored for 90 days
%% John discovers proof
JD->>R: Batch query for contact recovery proofs
Note right of JD: Query: [hash(pk1), hash(pk2), hash(pk_old), ...]
R-->>JD: Found proof for hash(pk_old)
activate JD
JD->>JD: Decode recovery proof
JD->>JD: Verify: pk_old is contact "Alice"
JD->>JD: Check vouchers for mutual contacts
alt Has Mutual Contacts (Bob, Charlie)
JD->>JD: Bob is my contact
JD->>JD: Charlie is my contact
JD->>JD: 2 mutual vouchers ≥ threshold
JD->>JD: "High confidence recovery"
else No Mutual Contacts
JD->>JD: No vouchers are my contacts
JD->>JD: "Cannot verify - meet Alice in person"
end
deactivate JD
%% David (isolated contact) case
DD->>R: Query for recovery proofs
R-->>DD: Found proof for Alice
activate DD
DD->>DD: Check vouchers: Bob, Charlie, Betty
DD->>DD: None are David's contacts
DD->>DD: "Warning: Unknown vouchers"
DD->>DD: Options: Meet in person / Verify another way / Accept anyway
deactivate DD
Data Structures¶
Recovery Claim QR¶
{
"type": "recovery_claim",
"old_pk": "Ed25519 public key (lost)",
"new_pk": "Ed25519 public key (new)",
"timestamp": "2026-01-21T10:00:00Z"
}
Voucher¶
{
"old_pk": "Alice's old public key",
"new_pk": "Alice's new public key",
"voucher_pk": "Bob's public key",
"timestamp": "2026-01-21T10:05:00Z",
"signature": "Ed25519 signature of above fields"
}
Recovery Proof¶
{
"old_pk": "Alice's old public key",
"new_pk": "Alice's new public key",
"threshold": 3,
"vouchers": [
{ /* Bob's voucher */ },
{ /* Charlie's voucher */ },
{ /* Betty's voucher */ }
],
"expires": "2026-04-21T10:00:00Z"
}
Security Properties¶
| Property | Mechanism |
|---|---|
| In-Person Vouching | Vouchers must physically verify the person |
| Threshold Security | Requires N vouchers (configurable, default 3) |
| Mutual Contact Verification | Recipients verify via contacts they trust |
| Relay Privacy | Relay stores proof under hash, learns nothing |
| Replay Prevention | Timestamps, signatures, 90-day expiry |
| Attack Detection | Conflicting claims trigger warnings |
Related Features¶
- Contact Exchange - Original key exchange
- Device Linking - Recovery not needed if devices linked
- Sync Updates - How reconnected contacts sync