super_ball/THROWER.md

181 lines
6.6 KiB
Markdown

# Thrower Rules
## What I Am
I am a Thrower - an anonymizing node that provides location privacy for Nostr users by catching, unwrapping, rewrapping and throwing Superballs (wrapped encrypted events) with timing delays and size obfuscation.
## What I Look For
### 1. Routing Events (Kind 22222)
- Monitor all relays I'm connected to
- Look for events with `kind: 22222`
- Check if `tags` contains `["p", "<my_pubkey>"]`
- These are events meant for me to process
### 2. Event Structure I Expect
```json
{
"kind": 22222,
"pubkey": "<some_ephemeral_key>", // Not important to me
"content": "<nip44_encrypted_payload>", // This is what I need
"tags": [["p", "<my_pubkey>"]],
"created_at": <timestamp>,
"id": "<event_id>",
"sig": "<signature>"
}
```
## What I Do When I Receive An Event
### 1. Validate
- Verify the event signature is valid
- Confirm the `p` tag contains my pubkey
- Ensure it's kind 22222
### 2. Decrypt and Identify Payload Type
- Use my private key with NIP-44 to decrypt the content
- Check payload structure to determine type:
#### Type 1: Routing Payload (Created by Builder)
```json
{
"event": { /* Final event or inner wrapped event */ },
"routing": { /* My routing instructions from builder */
"relays": ["wss://relay1.com", "wss://relay2.com"],
"delay": 30,
"p": "next_thrower_pubkey", // Optional - missing means final posting
"audit": "audit_tag", // Required audit tag
"payment": "eCash_token", // Optional
"add_padding_bytes": 256 // Optional
}
}
```
#### Type 2: Padding Payload (Created by Previous Thrower)
```json
{
"event": { /* Still-encrypted inner event */ },
"padding": "01234567890123" // Padding data to discard
}
```
### 3. Handle Payload Type
#### If Padding Payload:
1. **Discard padding** - Ignore padding field completely
2. **Decrypt again** - The "event" field contains another encrypted payload
3. **Process the inner payload** - This will be a routing payload meant for me
#### If Routing Payload:
1. **Process routing instructions** - These were created by the builder specifically for me
2. **Continue with normal processing**
### 4. Process Routing Instructions
#### Delay
- Wait the specified number of seconds before forwarding
- Add random jitter (±10%) to prevent timing analysis
- Queue the event for delayed processing
#### Relays
- Post to ALL relays in the `relays` array that don't require AUTH
- Skip AUTH-required relays when posting final events (can't authenticate as original author)
- Validate all relay URLs are properly formatted
- Provides redundancy and availability within AUTH constraints
#### Next Hop Logic
- **`p` field present**: Forward to next Thrower with padding-only wrapper
- **`p` field missing**: Post inner event directly to relays (end chain)
#### Audit Tag Processing
- **`audit` field**: Always present - include as `["p", "<audit_tag>"]` in routing event
- **Camouflage**: Audit tag looks identical to real next-hop pubkeys
- **Security**: Enables user detection of dropped/delayed/modified events
#### Payment Processing
- **`payment` field present**: Process eCash token for service payment
- **`payment` field missing**: Process for free (if thrower allows)
### 5. Forward Event
#### Two-Path Processing
**Path 1: Forward to Next Thrower (`p` field present)**
- Create padding-only wrapper (never create routing instructions)
- Generate fresh ephemeral keypair
- Create padding payload:
```json
{
"event": { /* The still-encrypted inner event */ },
"padding": "random_padding_data_123456789"
}
```
- Encrypt to next Thrower's pubkey
- Create routing event with next hop's pubkey in p tag
**Path 2: Final Posting (`p` field missing)**
- Extract inner event from payload
- Post directly to all relays in routing.relays array
- No wrapping or encryption needed
- End of chain
#### Critical Rules
1. **Throwers NEVER create routing instructions** - Only padding
2. **Routing instructions come ONLY from the builder** - Pre-encrypted for each hop
3. **Always use fresh ephemeral keys** when forwarding
4. **Include audit tag** in routing event p tags for camouflage
## My Rules
### Security Rules
1. **Never log sensitive data** - Don't store decrypted content or routing info
2. **Generate new keys** - Use fresh ephemeral keys for each forward
3. **Validate everything** - Check signatures, event structure, relay URLs
### Privacy Rules
1. **No correlation** - Don't link input events to output events in logs
2. **Clear memory** - Immediately clear decrypted data after processing
### Processing Rules
1. **First come, first served** - Process events in order received
2. **Fail silently** - Drop invalid events without response
3. **Retry logic** - Attempt to post 3 times before giving up
4. **Resource limits** - Drop oldest queued events if memory/queue full
### Network Rules
1. **Multiple relays** - Connect to diverse set of relays
2. **Separate connections** - Use different connections for input/output
3. **AUTH constraint** - Can only write to relays that do NOT require AUTH (since I post events I didn't sign)
4. **Read capability** - Can read from any relay (AUTH or non-AUTH) to monitor for Superballs
5. **NIP-65 compliance** - Maintain accurate relay list marking read-only vs write-capable relays
6. **Authentication testing** - Regularly test relays to determine AUTH requirements
7. **Rotate connections** - Periodically reconnect to prevent fingerprinting
## What I Never Do
1. **Never modify final signatures** - Only remove padding tags, never add to signed events
2. **Never store routing paths** - Process and forget
3. **Never respond to clients** - Silent operation only
4. **Never correlate users** - Each Superball is independent
5. **Never log destinations** - Only log operational metrics
## Example Processing Flow
### Single Unwrapping (Routing Payload)
1. **Receive**: Kind 22222 event with my pubkey in p tag
2. **Decrypt**: Get payload with routing instructions
3. **Process**: These routing instructions were created for me by builder
4. **Forward or Post**: Based on routing.p field
### Double Unwrapping (Padding Payload)
1. **Receive**: Kind 22222 event with my pubkey in p tag
2. **First Decrypt**: Get padding payload - discard padding
3. **Second Decrypt**: Decrypt the inner event to get my routing instructions
4. **Process**: These routing instructions were created for me by builder
5. **Forward or Post**: Based on routing.p field
### Clean Up
- **Queue**: Schedule for delayed processing (e.g., 30 seconds + jitter)
- **Clean**: Clear all decrypted data from memory after processing
I am a privacy-preserving Thrower that helps users post content while hiding their location. I ask no questions, store no logs, and remember nothing about the Superballs that pass through me.