hash-of-wisdom/docs/PROTOCOL.md

17 KiB

Word of Wisdom Protocol Specification

Overview

The Word of Wisdom protocol is a TCP-based challenge-response protocol designed to mitigate DDoS attacks by requiring clients to solve a Proof-of-Work (PoW) puzzle before accessing protected resources (quotes).

The protocol uses HMAC-signed challenges for stateless server operation, aggressive timeouts to prevent slowloris attacks, and a simple binary framing with JSON payloads. It is stateless on the server thanks to HMAC-signed challenges, eliminating the need for challenge storage.

Proof of Work Algorithm Choice

Selected Algorithm: SHA-256 Hashcash with HMAC Authentication

The protocol uses SHA-256 based Hashcash with HMAC-signed challenges for secure, stateless operation.

For detailed analysis of alternative PoW algorithms and comprehensive justification of this choice, see POW_ANALYSIS.md.

Key Benefits

  • Proven Security: Battle-tested in Bitcoin with 15+ years of production experience
  • Stateless Server: HMAC signatures eliminate challenge storage, enabling horizontal scaling
  • Universal Compatibility: No memory requirements ensure compatibility across all client types
  • Fast Verification: Near-instant verification enables high server throughput under attack
  • Adjustable Difficulty: Fine-grained control through leading zero bits (3-10 bits practical range)

Difficulty Scaling Strategy

  • Normal Operations: 4-bit difficulty (average 16 hash attempts)
  • Load-Based Adjustment: +1 bit difficulty when server load exceeds threshold
  • Failure-Based Penalty: +2 bits per 5 failed attempts in 2-minute window (capped at +6 extra bits)
  • Success Reset: Failure counter resets to zero after successful solution

Protocol Flow

Challenge Request Flow

Client                                    Server
  |                                         |
  |-------- CHALLENGE_REQUEST ------------->|
  |                                         |
  |<------- CHALLENGE_RESPONSE -------------| (HMAC-signed)
  |                                         |
  [Connection closes]

Solution Submission Flow

Client                                    Server
  |                                         |
  |-------- SOLUTION_REQUEST -------------->|
  |                                         |
  |<------- QUOTE_RESPONSE -----------------| (if solution valid)
  |                                         |
  [Connection closes]

Error Flow

Client                                    Server
  |                                         |
  |-------- SOLUTION_REQUEST (invalid) ---->|
  |                                         |
  |<------- ERROR_RESPONSE -----------------| (if solution invalid)
  |                                         |
  [Connection closes]

Message Format

All protocol messages use a binary format with the following structure:

+------------------+------------------+------------------+
|   Message Type   |      Length      |     Payload      |
|     (1 byte)     |    (4 bytes)     |   (N bytes)      |
+------------------+------------------+------------------+
  • Message Type: Single byte indicating message type (see table below)
  • Length: 32-bit big-endian integer indicating payload length in bytes
  • Payload: Variable-length payload (can be empty, maximum 8KB for security)

Encoding Details

  • Endianness: All multi-byte integers use big-endian encoding
  • JSON Format: UTF-8 encoding, compact format (no pretty-printing)
  • Size Limits: Maximum 8KB payload to prevent memory exhaustion attacks

Message Types

Type Value Name Direction Description
0x01 CHALLENGE_REQUEST Client → Server Client requests a new PoW challenge
0x02 CHALLENGE_RESPONSE Server → Client Server issues HMAC-signed challenge
0x03 SOLUTION_REQUEST Client → Server Client submits challenge + nonce
0x04 QUOTE_RESPONSE Server → Client Server sends quote (if solution valid)
0x05 ERROR_RESPONSE Server → Client Server reports an error

Message Payloads

CHALLENGE_REQUEST (0x01)

  • Payload: Empty
  • Description: Client requests a new challenge from the server
  • Usage: First message in the protocol flow

CHALLENGE_RESPONSE (0x02)

  • Payload: JSON-encoded challenge object
  • Description: Server provides HMAC-signed challenge for PoW computation
  • Format:
{
  "timestamp": 1640995200,
  "difficulty": 4,
  "resource": "quotes",
  "random": "a1b2c3d4e5f6",
  "hmac": "base64url_encoded_signature"
}

Field Descriptions:

  • timestamp: Unix timestamp when challenge was created
  • difficulty: Number of leading zero bits required in solution hash
  • resource: Server resource identifier (e.g., "quotes")
  • random: Random hex string for challenge uniqueness
  • hmac: HMAC-SHA256 signature of canonical challenge fields (also serves as unique identifier)

Security Notes:

  • Server is stateless: no need to store challenges locally
  • HMAC signature prevents challenge forgery and tampering
  • Timestamp enables TTL validation without server-side storage

SOLUTION_REQUEST (0x03)

  • Payload: JSON-encoded solution object
  • Description: Client submits PoW solution with original challenge
  • Format:
{
  "challenge": {
    "timestamp": 1640995200,
    "difficulty": 4,
    "resource": "quotes",
    "random": "a1b2c3d4e5f6",
    "hmac": "base64url_encoded_signature"
  },
  "nonce": "solution_nonce_value"
}

Requirements:

  • Client must echo the complete original challenge object
  • Nonce must produce a valid PoW hash with required difficulty
  • Challenge must not be expired (within TTL window)

QUOTE_RESPONSE (0x04)

  • Payload: JSON-encoded quote object
  • Description: Server sends inspirational quote after successful PoW verification
  • Format:
{
  "text": "The only way to do great work is to love what you do.",
  "author": "Steve Jobs",
  "category": "motivation"
}

Field Descriptions:

  • text: The inspirational quote text
  • author: Attribution for the quote
  • category: Thematic category (motivation, wisdom, success, etc.)

ERROR_RESPONSE (0x05)

  • Payload: JSON-encoded error object
  • Description: Server reports errors in client requests or server state
  • Format:
{
  "code": "INVALID_SOLUTION",
  "message": "The provided PoW solution is incorrect",
  "retry_after": 30
}

Field Descriptions:

  • code: Machine-readable error code (see Error Codes section)
  • message: Human-readable error description
  • retry_after: Optional delay in seconds before client should retry

Error Codes

Code Description Client Action Server Action
MALFORMED_MESSAGE Invalid frame format or JSON parsing error Disconnect and retry with correct format Log error and close connection
INVALID_CHALLENGE Challenge HMAC signature verification failed Request new challenge from server Generate new valid challenge
INVALID_SOLUTION PoW hash verification failed for submitted nonce Retry with correct nonce computation Log failed attempt for rate limiting
EXPIRED_CHALLENGE Challenge timestamp exceeds TTL window Request fresh challenge from server Generate new challenge with current timestamp
RATE_LIMITED Client exceeds request rate limits Wait for retry_after seconds before retry Apply temporary throttling to client IP
SERVER_ERROR Internal server error or temporary unavailability Retry connection after delay Log error and investigate system health
TOO_MANY_CONNECTIONS Server at maximum connection capacity Retry connection later Reject new connections until capacity available
DIFFICULTY_TOO_HIGH Adaptive difficulty exceeds client capabilities Request new challenge or give up May reduce difficulty if appropriate

Error Response Format

All errors follow the consistent ERROR_RESPONSE format:

{
  "code": "ERROR_CODE_NAME",
  "message": "Human readable description of the error",
  "retry_after": 30,
  "details": {
    "additional_context": "Optional additional error context"
  }
}

Error Handling Strategy

  • Client Errors: Provide specific actionable error codes
  • Server Errors: Log detailed information server-side, return generic client errors
  • Rate Limiting: Include retry timing information in error responses
  • Security: Avoid exposing internal system details in error messages

Hashcash Challenge Format

The server uses SHA-256 based Hashcash with HMAC authentication for Proof of Work challenges.

Challenge String Structure

resource:timestamp:difficulty:random

Example:

192.168.1.100:8080:1640995200:4:a1b2c3d4e5f6

Solution Process

  1. Receive: Client receives HMAC-signed challenge from server
  2. Extract: Client extracts challenge fields to construct challenge string
  3. Iterate: Client appends different nonce values to challenge string
  4. Hash: Client computes SHA-256 hash of challenge_string:nonce
  5. Check: Client checks if hash has required number of leading zero bits
  6. Repeat: If not valid, increment nonce and repeat from step 4
  7. Submit: When valid nonce found, submit solution to server

Verification Process

Server verifies solutions through the following steps:

  1. HMAC Verification: Verify challenge HMAC signature against server secret
  2. TTL Check: Verify challenge timestamp is within TTL window (5 minutes)
  3. Reconstruction: Reconstruct challenge string from submitted challenge fields
  4. Hash Computation: Compute SHA-256 hash of challenge_string:nonce
  5. Difficulty Check: Verify hash has required number of leading zero bits
  6. Success: If all checks pass, grant access to quote resource

Difficulty Examples

Difficulty Leading Zero Bits Average Attempts Example Hash
3 3 bits 8 000a1b2c...
4 4 bits 16 0001a2b3...
5 5 bits 32 0000a1b2...
6 6 bits 64 00001a2b...

Connection Management

Connection Lifecycle

The protocol uses separate TCP connections for challenge requests and solution submissions:

Challenge Request:

  1. Connect: Client establishes TCP connection to server
  2. Request: Client sends CHALLENGE_REQUEST
  3. Receive: Client receives CHALLENGE_RESPONSE with HMAC-signed challenge
  4. Disconnect: Connection closes automatically

Solution Submission:

  1. Solve: Client solves PoW challenge offline
  2. Connect: Client establishes new TCP connection to server
  3. Submit: Client sends SOLUTION_REQUEST with challenge and nonce
  4. Receive: Client receives QUOTE_RESPONSE or ERROR_RESPONSE
  5. Disconnect: Connection closes automatically

Timeouts and Limits

Parameter Value Purpose
Challenge TTL 5 minutes Prevents stale challenge reuse
Solution Timeout 5 seconds Prevents slowloris attacks
Connection Timeout 15 seconds Limits connection holding time
Message Size Limit 8KB Prevents memory exhaustion
Max Connections 1000 Global server capacity limit

Timeout Behavior

  • Challenge Expiry: Challenges become invalid after 5 minutes from timestamp
  • Solution Window: Client has 5 seconds to submit solution after challenge
  • Connection Limits: Connections auto-close after 15 seconds of inactivity
  • Resource Protection: Aggressive timeouts prevent resource exhaustion attacks

Rate Limiting & DDOS Protection

Connection-Level Protection (HAProxy/Envoy)

Handled before application layer by reverse proxy:

Metric Limit Purpose
New Connections/sec ≤10 per IP Prevents connection flooding
Concurrent Connections ≤20 per IP Limits resource usage per client
Burst Allowance 30 connections Handles legitimate traffic spikes
Global Connection Cap 1000 total Protects server capacity

Application-Level Protection

Failed Solution Tracking

  • Counter: Track invalid solution attempts per client IP/identifier
  • Window: Rolling 2-minute time window for failure counting
  • Penalty: Each group of 5 failures increases difficulty by +2 bits
  • Cap: Maximum +6 additional difficulty bits to prevent client DOS
  • Reset: Successful solution resets failure counter to zero

Adaptive Difficulty Scaling

  • Load-Based: +1 difficulty bit when server CPU/memory exceeds threshold
  • Attack Response: Automatic difficulty increase during detected attacks
  • Recovery: Gradual difficulty reduction as attack subsides
  • Monitoring: Continuous monitoring of success/failure ratios

Rate Limiting Rules

Rule Limit Action
Challenge Requests 10 per minute per IP Temporary IP throttling
Solution Attempts 5 per minute per IP Increased difficulty penalty
Invalid Solutions 5 per 2 minutes +2 difficulty bits
Connection Frequency 10 per second per IP Connection rejection

Security Considerations

PoW Security

  • Minimum Difficulty: 3 leading zero bits (prevents trivial bypass attempts)
  • Maximum Difficulty: 10 leading zero bits (prevents excessive client DOS)
  • Dynamic Scaling: Adjusts automatically based on server load and attack patterns
  • CPU-Bound Work: Memory-independent computation ensures fairness across hardware

Challenge Security

  • Uniqueness: Each challenge includes timestamp and cryptographic random data
  • Expiration: Challenges automatically expire after 5-minute TTL window
  • HMAC Authentication: Prevents challenge forgery and tampering
  • Stateless Verification: No server-side storage required for validation
  • Replay Protection: Timestamp and HMAC combination prevents replay attacks

Input Validation

  • Message Size: Strict 8KB maximum per message (prevents memory exhaustion)
  • JSON Schema: All JSON payloads validated against strict schemas
  • Challenge Format: Rigorous validation of challenge structure and fields
  • Nonce Validation: Proper integer bounds checking for nonce values
  • Encoding Validation: UTF-8 encoding validation for all text fields

Network Security

  • Connection Limits: Per-IP and global connection rate limiting
  • Timeout Protection: Aggressive timeouts prevent slowloris attacks
  • Resource Binding: Challenges tied to client connection context
  • Error Information: Limited error details to prevent information disclosure

Operational Security

  • HMAC Secret: Server maintains secret key for challenge signing
  • Logging: Comprehensive attack detection and monitoring
  • Metrics: Real-time visibility into attack patterns and system health
  • Graceful Degradation: System remains functional under attack conditions

Implementation Notes

Protocol Implementation

  • Endianness: All multi-byte integers use big-endian encoding for consistency
  • JSON Encoding: UTF-8 encoding for all text, compact format (no pretty-printing)
  • Required Fields: All JSON fields marked as required must be present
  • Optional Fields: Handle optional fields gracefully with sensible defaults

Server Implementation

  • HMAC Secret: Server maintains cryptographically secure secret key
  • Challenge Generation: Use cryptographically secure random number generator
  • Quote Storage: Preload quotes from file/database on startup
  • Concurrent Handling: Support for multiple simultaneous client connections
  • Resource Management: Proper cleanup of connections and temporary resources

Client Implementation

  • PoW Computation: Efficient nonce iteration and hash computation
  • Connection Management: Proper TCP connection lifecycle handling
  • Error Handling: Graceful handling of all error conditions
  • Retry Logic: Intelligent retry with exponential backoff

Error Handling

  • Server Errors: Always send ERROR_RESPONSE for client-detectable errors
  • Logging: Comprehensive server-side logging for debugging and monitoring
  • Connection Termination: Graceful connection closure on errors
  • Client Recovery: Clients should handle errors and retry appropriately

Performance Considerations

  • Keep-Alive: Not supported (one quote per connection for simplicity)
  • Connection Pooling: Server supports concurrent connection handling
  • Memory Efficiency: Minimal memory footprint per connection
  • CPU Efficiency: Optimized hash computation and verification
  • Scalability: Stateless design enables horizontal scaling

Future Extensions

  • Resource Types: Protocol designed to support resources beyond quotes
  • Authentication: Framework supports future authentication mechanisms
  • Compression: Payload compression can be added without protocol changes
  • Encryption: TLS termination recommended at load balancer level