This commit is contained in:
Your Name 2025-09-17 10:03:26 -04:00
commit f86e0ce7dd
8 changed files with 547 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
Nostr_NIPs/

153
DAEMON.md Normal file
View File

@ -0,0 +1,153 @@
# Superball Daemon Rules
## What I Am
I am Superball - an anonymizing node that provides location privacy for Nostr users by forwarding their encrypted events with timing delays and size obfuscation.
## What I Look For
### 1. Routing Events (Kind 30000)
- Monitor all relays I'm connected to
- Look for events with `kind: 30000`
- Check if `tags` contains `["p", "<my_pubkey>"]`
- These are events meant for me to process
### 2. Event Structure I Expect
```json
{
"kind": 30000,
"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 30000
### 2. Decrypt
- Use my private key with NIP-44 to decrypt the content
- Extract the payload which contains:
```json
{
"event": { /* The event to forward */ },
"routing": {
"relays": ["wss://relay1.com", "wss://relay2.com"],
"delay": 30,
"pad": "+150", // or "-50"
"p": "next_superball_pubkey", // Optional - missing means final posting
"audit": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456", // Required audit tag
"payment": "eCash_token" // Optional
}
}
```
### 3. 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
#### Padding
- **Remove padding (`"pad": "-N"`)**: Delete N bytes worth of padding tags from the event
- **Add padding (`"pad": "+N"`)**: Create new routing wrapper with N bytes of padding tags
#### Relays
- Post to ALL relays in the `relays` array
- Validate all relay URLs are properly formatted
- Provides redundancy and availability
#### Next Hop Logic
- **`p` field present**: Create routing event for specified next Superball (can apply padding)
- **`p` field missing**: Extract inner event and post directly to relays (end chain, no padding changes)
#### Padding Logic
- **`p` field present + `pad` field**: Apply padding changes when creating routing wrapper
- **`p` field missing**: Ignore any `pad` field - cannot modify signed event
- **Final hop rule**: Never modify signed events, post exactly as received
#### 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 daemon allows)
### 4. Forward Event
#### Always Rewrap (Important for Privacy)
**ALWAYS** create a new routing event to hide whether padding was added or removed:
```json
{
"kind": 30000, // Always use routing event
"pubkey": "<my_ephemeral_key>", // Generate fresh ephemeral key
"content": "<encrypted_inner_event>", // Re-encrypt with my key
"tags": [
["p", "<next_hop_or_final_destination>"],
["p", "<audit_tag_from_routing>"], // Always include audit tag as p tag
["padding", "<random_data_1>"], // Adjusted padding
["padding", "<random_data_2>"] // May be more or less than before
]
}
```
#### Next Hop Handling
- **If `p` field in routing**: Create routing event with that pubkey in p tag
- **If no `p` field in routing**: Extract inner event and post directly to all relays
- **Multi-relay posting**: Post to every relay in the `relays` array
- **End of chain**: When no `p` field, I am the final hop
## 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
4. **Rate limiting** - Don't process more than X events per minute from same source
### Privacy Rules
1. **No correlation** - Don't link input events to output events in logs
2. **Clear memory** - Immediately clear decrypted data after processing
3. **Random timing** - Add jitter to specified delays
4. **Mix traffic** - Send decoy traffic when idle (optional)
### 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 support** - Prefer relays that support AUTH for privacy
4. **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 event is independent
5. **Never log destinations** - Only log operational metrics
## Example Processing Flow
1. **Receive**: Kind 30000 event with my pubkey in p tag
2. **Decrypt**: Extract inner event + routing instructions
3. **Queue**: Schedule for delayed processing (e.g., 30 seconds + jitter)
4. **Process**: Apply padding changes and prepare for forwarding
5. **Forward**: Post to target relay(s)
6. **Clean**: Clear all decrypted data from memory
I am a privacy-preserving relay that helps users post content while hiding their location. I ask no questions, store no logs, and remember nothing about the events that pass through me.

157
EXAMPLE.md Normal file
View File

@ -0,0 +1,157 @@
# 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.

1
Norman_Stingley.txt Normal file
View File

@ -0,0 +1 @@
Norman Stingley - inventor of the super-ball

198
PROTOCOL.md Normal file
View File

@ -0,0 +1,198 @@
# Superball Protocol
## Overview
Superball provides location privacy for Nostr by using encrypted routing through daemon nodes. Users can post content under their real identity while completely hiding their network location.
## Protocol Structure
### Step 1: Create Signed Event
User creates and signs their normal Nostr event:
```json
{
"kind": 1,
"pubkey": "user_pubkey",
"content": "Message content",
"tags": [],
"created_at": 1703000000,
"id": "event_id",
"sig": "user_signature"
}
```
### Step 2: Create Routing Instructions
User creates routing instructions:
```json
{
"relays": [
"wss://target-relay1.com",
"wss://target-relay2.com",
"wss://target-relay3.com"
],
"delay": 30,
"pad": "+150",
"p": "superball_b_pubkey", // Next superball (optional - if missing, final posting)
"audit": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456", // Audit pubkey (always required)
"payment": "eCash_token_here" // Optional payment for processing
}
```
### Step 3: Encrypt and Send
User creates a routing event with NIP-44 encryption:
```json
{
"kind": 30000, // Superball routing event
"pubkey": "ephemeral_key",
"content": "<nip44_encrypted_payload>",
"tags": [
["p", "superball_pubkey"]
],
"created_at": 1703000100,
"id": "routing_event_id",
"sig": "ephemeral_signature"
}
```
The encrypted payload contains:
```json
{
"event": {
"kind": 1,
"pubkey": "user_pubkey",
"content": "Message content",
"tags": [],
"created_at": 1703000000,
"id": "event_id",
"sig": "user_signature"
},
"routing": {
"relays": ["wss://target-relay1.com", "wss://target-relay2.com"],
"delay": 30,
"pad": "+150",
"p": "next_superball_pubkey", // Optional - if missing, final posting
"audit": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456", // Required audit pubkey
"payment": "eCash_token" // Optional payment
}
}
```
## Superball Processing
1. **Receive**: Monitor for kind 30000 events with p tag = own pubkey
2. **Decrypt**: Use NIP-44 to decrypt the content
3. **Parse**: Extract the event and routing instructions
4. **Apply Padding**: Modify padding according to instructions
5. **Delay**: Wait specified time
6. **Always Rewrap**: Create new routing event to hide padding operations
7. **Forward**: Post the new routing event to specified relay
## Always Rewrap Rule
### Privacy Protection
Superballs **ALWAYS** create a new routing wrapper to prevent analysis of padding operations:
- **Consistent behavior**: Every forward looks the same (new routing event)
- **Hide operations**: No way to tell if padding was added, removed, or unchanged
- **Fresh encryption**: New ephemeral key and encryption for each hop
- **Metadata mixing**: Padding levels change unpredictably at each hop
### Routing Event Structure
Every forward creates a new kind 30000 event:
```json
{
"kind": 30000,
"pubkey": "<fresh_ephemeral_key>",
"content": "<newly_encrypted_payload>",
"tags": [
["p", "<next_superball_or_final_user>"],
["p", "<audit_pubkey_from_routing>"],
["padding", "<adjusted_random_data>"]
]
}
```
## Audit Mechanism for Security
### Purpose
The audit mechanism allows users to detect malicious Superballs that drop events, ignore timing delays, or modify padding incorrectly.
### Audit Tag Structure
- **Format**: 64-character hex string (looks like a Nostr pubkey)
- **Generation**: User creates random audit tag for each hop
- **Labeling**: Always labeled as `["p", "<audit_pubkey>"]` in routing events
- **Camouflage**: Indistinguishable from real next-hop pubkeys to observers
### How It Works
1. **User includes audit tag** in routing instructions for each hop
2. **Superball posts audit tag** as additional `p` tag when forwarding
3. **User monitors relays** for audit tag appearances
4. **Timing and size analysis** reveals compliance with instructions
### Example Audit Detection
```json
// Alice creates routing with audit tag
{
"relays": ["wss://relay2.com"],
"delay": 45,
"pad": "+200",
"p": "sball_b_real_pubkey",
"audit": "a1b2c3...fake_pubkey_for_audit"
}
// Superball A should post this after 45s with +200 bytes:
{
"kind": 30000,
"tags": [
["p", "sball_b_real_pubkey"], // Real next hop
["p", "a1b2c3...fake_pubkey"], // Audit tag (looks identical)
["padding", "..."] // +200 bytes of padding
]
}
```
Alice monitors relay2.com and verifies the audit tag appears with correct timing and size.
### Security Properties
- **Misbehavior Detection**: Dropped, delayed, or incorrectly padded events
- **Reputation Building**: Users can rate Superball reliability over time
- **Privacy Preserved**: Audit tags look like normal routing to observers
- **Always Active**: Every routing event includes audit verification
## Routing Instructions Fields
### Required Fields
- **`relays`**: Array of relay URLs to post to (allows multi-relay posting)
- **`delay`**: Minimum delay in seconds before forwarding
### Required Fields
- **`audit`**: 64-character hex audit tag (format: Nostr pubkey)
- User-generated random identifier for this hop
- Always posted as `["p", "<audit_tag>"]` in routing event
- Enables detection of malicious Superballs
### Optional Fields
- **`pad`**: Padding instruction (`"+N"` to add, `"-N"` to remove N bytes)
- Only valid when `p` field is present (continuing chain)
- Ignored when `p` field missing (final hop - can't modify signed event)
- **`p`**: Pubkey of next Superball in chain
- If present: Create routing event for next Superball (can apply padding)
- If missing: Post final event directly to relays (end of chain, no padding changes)
- **`payment`**: eCash token for processing payment
- Allows monetized Superball services
- Optional - many daemons may operate for free
## Processing Logic
### Multi-Relay Posting
Superballs post to ALL specified relays in the `relays` array for redundancy and availability.
### Chain Termination
- **`p` field present**: Continue routing chain to specified Superball
- **`p` field missing**: Extract and post final event directly, end chain
## Benefits
- **Location Privacy**: User's network location completely hidden
- **Identity Preservation**: Posts appear with user's real pubkey
- **Simple Implementation**: Single NIP-44 encryption layer per hop
- **Purpose-Built**: Designed specifically for anonymous posting
- **Traffic Analysis Resistance**: Timing delays and padding protect against correlation

29
README.md Normal file
View File

@ -0,0 +1,29 @@
# Superball
![superball](super_ball.jpg)
Superball provides Tor-like location privacy for Nostr users. It's a daemon that bounces encrypted events between relays, allowing users to post content under their real identity while completely hiding their network location.
## How It Works
1. **User creates content** - Normal signed Nostr event with their real pubkey
2. **Encrypt with routing** - Bundle event + routing instructions, encrypt to Superball daemon
3. **Anonymous forwarding** - Event bounces through multiple daemons with delays and padding
4. **Final posting** - Original event appears on target relay with user's identity but from daemon's location
## Key Features
- **Location Privacy**: Hide your network location while preserving your identity
- **Traffic Analysis Resistance**: Random delays and size padding prevent correlation
- **Simple Protocol**: Uses NIP-44 encryption with new kind 30000 for routing
- **Flexible Routing**: Support for multi-hop paths through multiple daemons
- **Signature Preservation**: Original event signatures maintained for authenticity
- **Audit Security**: Detect and avoid malicious Superballs through cryptographic verification
## Documentation
- [`PROTOCOL.md`](PROTOCOL.md) - Technical protocol specification
- [`EXAMPLE.md`](EXAMPLE.md) - Complete walkthrough example
- [`DAEMON.md`](DAEMON.md) - Rules and behavior for Superball daemon operators
Perfect for journalists, activists, or anyone who needs to protect their physical location while maintaining accountability for their public statements.

View File

@ -0,0 +1,8 @@
{
"folders": [
{
"path": "."
}
],
"settings": {}
}

BIN
super_ball.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB