157 lines
4.9 KiB
Markdown
157 lines
4.9 KiB
Markdown
# Superball Example: Anonymous Posting
|
|
|
|
## Scenario
|
|
Alice wants to post a message under her real identity while hiding her location from surveillance.
|
|
|
|
### Participants
|
|
- **Alice**: Original sender (pubkey: `alice123...`)
|
|
- **Superball A**: First hop (pubkey: `sball_a789...`)
|
|
- **Superball B**: Second hop (pubkey: `sball_b012...`)
|
|
- **Relay1**: `wss://relay1.com` (where Alice posts)
|
|
- **Relay2**: `wss://relay2.com` (intermediate relay)
|
|
- **Relay3**: `wss://relay3.com` (where final message appears)
|
|
|
|
## Step-by-Step Flow
|
|
|
|
### 1. Alice Creates Her Final Message That Will Be Posted
|
|
```json
|
|
{
|
|
"kind": 1,
|
|
"pubkey": "alice123...",
|
|
"content": "The government is lying about inflation statistics",
|
|
"tags": [],
|
|
"created_at": 1703000000,
|
|
"id": "alice_event_id",
|
|
"sig": "alice_signature"
|
|
}
|
|
```
|
|
|
|
### 2. Alice Encrypts Instructions for Superball B (Final Hop)
|
|
Payload for Superball B (final hop - no `p` field):
|
|
```json
|
|
{
|
|
"event": { /* Alice's signed event above */ },
|
|
"routing": {
|
|
"relays": ["wss://relay3.com", "wss://relay4.com"],
|
|
"delay": 15,
|
|
"audit": "9f8e7d6c5b4a39281726354019283746502918374650283746501928374650"
|
|
// No "p" field - this means final posting
|
|
// No "pad" field - can't modify signed event
|
|
}
|
|
}
|
|
```
|
|
|
|
Creates routing event:
|
|
```json
|
|
{
|
|
"kind": 30000,
|
|
"pubkey": "ephemeral_key_2",
|
|
"content": "<encrypted_payload_for_superball_b>",
|
|
"tags": [["p", "sball_b012..."]],
|
|
"created_at": 1703000100,
|
|
"id": "routing_for_b",
|
|
"sig": "ephemeral_signature_2"
|
|
}
|
|
```
|
|
|
|
### 3. Alice Encrypts Instructions for Superball A (First Hop)
|
|
Payload for Superball A (continuing chain):
|
|
```json
|
|
{
|
|
"event": { /* routing event for Superball B above */ },
|
|
"routing": {
|
|
"relays": ["wss://relay2.com"],
|
|
"delay": 45,
|
|
"pad": "+200",
|
|
"p": "sball_b012...", // Next Superball in chain
|
|
"audit": "1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef1234567890",
|
|
"payment": "eCash_A1B2C3..." // Optional payment
|
|
}
|
|
}
|
|
```
|
|
|
|
Alice posts this to Relay1:
|
|
```json
|
|
{
|
|
"kind": 30000,
|
|
"pubkey": "ephemeral_key_1",
|
|
"content": "<encrypted_payload_for_superball_a>",
|
|
"tags": [["p", "sball_a789..."]],
|
|
"created_at": 1703000200,
|
|
"id": "routing_for_a",
|
|
"sig": "ephemeral_signature_1"
|
|
}
|
|
```
|
|
|
|
## Execution Timeline
|
|
|
|
**T+0**: Alice posts routing event to Relay1
|
|
```
|
|
Relay1: kind 30000 event (p tag = sball_a789...)
|
|
```
|
|
|
|
**T+5**: Superball A processes
|
|
- Decrypts payload
|
|
- Sees: relay2.com, delay 45s, pad +200
|
|
- Needs to ADD padding, so creates new wrapper
|
|
- Queues for 45-second delay
|
|
|
|
**T+50**: Superball A always rewraps (consistent behavior)
|
|
```
|
|
Relay2: NEW routing event (always looks the same)
|
|
{
|
|
"kind": 30000,
|
|
"pubkey": "superball_a_ephemeral_key", // Fresh key
|
|
"content": "<newly_encrypted_payload>", // Re-encrypted
|
|
"tags": [
|
|
["p", "sball_b012..."], // Real next hop
|
|
["p", "1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef1234567890"], // Audit tag
|
|
["padding", "random_data_1..."], // Adjusted padding
|
|
["padding", "random_data_2..."], // (+200 bytes added)
|
|
["padding", "random_data_3..."]
|
|
]
|
|
}
|
|
```
|
|
|
|
Alice monitors relay2.com and sees her audit tag `1a2b3c4d5e6f...` appear at T+50 with correct +200 byte padding, confirming Superball A is honest.
|
|
|
|
**T+55**: Superball B processes
|
|
- Decrypts payload
|
|
- Sees: Alice's event + instructions (relays=[relay3.com, relay4.com], delay 15s)
|
|
- NO `p` field - this means final posting, extract and post Alice's event exactly as-is
|
|
- Cannot modify padding on signed event
|
|
- Queues for 15-second delay
|
|
|
|
**T+70**: Superball B posts Alice's final event (end of chain)
|
|
```
|
|
Relay3 AND Relay4: Alice's original signed event appears exactly as she created it
|
|
{
|
|
"kind": 1,
|
|
"pubkey": "alice123...",
|
|
"content": "The government is lying about inflation statistics",
|
|
"tags": [], // Original tags preserved
|
|
"created_at": 1703000000,
|
|
"id": "alice_event_id",
|
|
"sig": "alice_signature" // Original signature preserved
|
|
}
|
|
```
|
|
|
|
Alice's message now appears on both relay3.com and relay4.com for redundancy.
|
|
|
|
## Privacy and Security Achieved
|
|
|
|
- **Alice's location**: Completely hidden from surveillance
|
|
- **Message origin**: Appears to come from Superball B's location
|
|
- **Traffic analysis**: 65-second delay + size changes prevent correlation
|
|
- **Identity preserved**: Alice's real pubkey and signature maintained
|
|
- **Plausible deniability**: No proof Alice initiated the posting
|
|
- **Malicious node detection**: Audit tags allow Alice to verify proper forwarding
|
|
- **Accountability**: Bad Superballs can be identified and avoided
|
|
|
|
### Audit Trail for Alice
|
|
- **T+50**: Audit tag `1a2b3c4d5e6f...` appears on relay2.com (✓ Superball A honest)
|
|
- **T+70**: Final message appears on relay3.com and relay4.com (✓ Superball B honest)
|
|
- **Size verification**: Event sizes match expected padding operations
|
|
- **Timing verification**: Delays match requested timeouts
|
|
|
|
Alice successfully posts controversial content under her identity while protecting her physical location AND maintaining the ability to detect and avoid malicious routing nodes. |