25  Cipher Challenge Game

Interactive tool efficiency can be tracked as successful outcomes per minute:

\[ \eta = \frac{N_{\text{successful-attempts}}}{T_{\text{minutes}}} \]

Worked example: If users complete 48 successful interactions in 30 minutes, efficiency is \(48/30=1.6\) successful interactions/minute. This metric helps compare alternative game or wizard designs objectively.

25.1 Learning Objectives

By completing this interactive game, you will be able to:

  • Apply classical ciphers: Encode and decode messages using Caesar and substitution ciphers
  • Distinguish modern encryption modes: Compare block cipher modes, key sizes, and authenticated encryption
  • Apply asymmetric concepts: Implement public/private key principles and digital signatures
  • Identify vulnerabilities: Detect weak encryption patterns and common attack vectors
In 60 Seconds

Interactive games and simulations help learners develop intuition for cryptographic concepts by experiencing encryption, key exchange, and attack scenarios hands-on rather than through abstract theory alone.

Cryptography for IoT is the science of keeping sensor data and device commands secret and tamper-proof. Think of it as the digital equivalent of secret codes, locked boxes, and wax seals. Even if someone intercepts your IoT data traveling through the air, cryptography ensures they cannot read or alter it without the proper keys.

“Who wants to play a cipher game?” Lila the LED blinked excitedly. “This interactive challenge lets you try out real encryption techniques, starting with the classic Caesar cipher that Julius Caesar used 2,000 years ago!”

Sammy the Sensor tried the first puzzle. “The Caesar cipher shifts each letter by a fixed number. If the shift is 3, then A becomes D, B becomes E, and so on. It is super easy to break – there are only 26 possible shifts! That is why we do not use it for real security, but it is a great way to understand the basics.”

“As you level up, the challenges get harder,” Max the Microcontroller said. “You will work with substitution ciphers, then AES block cipher modes, then asymmetric encryption puzzles. Each level teaches a real concept that professional cryptographers use every day. The goal is to build intuition about why some ciphers are strong and others are weak.”

“My tip: try to break the weak ciphers first!” Bella the Battery suggested. “When you see HOW easy it is to crack a Caesar cipher or a simple substitution, you will understand WHY modern encryption uses 256-bit keys and complex mathematical operations. Play the game, have fun, and you will learn cryptography without even realizing it!”

How to Play

Test your cryptography knowledge through progressively challenging puzzles:

  1. Select a level to begin
  2. Solve each challenge by applying the correct cryptographic technique
  3. Earn points for correct answers (faster = more points)
  4. Unlock advanced levels by mastering earlier ones

Progress through three levels: - Level 1: Classical Ciphers (Caesar, XOR, substitution) - Level 2: Symmetric Encryption (AES, modes, authentication) - Level 3: Asymmetric Encryption (RSA, signatures, key exchange)

25.1.1 Game Interface


25.2 Game vs Reality

Educational Simplifications

This game teaches concepts, but real-world cryptography differs:

Game Production IoT
Caesar cipher AES-128-GCM or AES-256-GCM
Manual XOR Hardware-accelerated AES
Simple key exchange TLS 1.3 with certificate validation
Fixed challenges Random nonces, rotating keys

The goal is understanding WHY encryption works, not implementing production crypto.

Try It: Caesar Cipher Encoder/Decoder

25.3 Challenge Yourself Further

After mastering this game:

  1. Try the Encryption Labs – Implement these concepts on ESP32
  2. Use the Interactive Tools – Calculate encryption strength
  3. Read about Key Management – Learn proper key handling

Scenario: A student builds a temperature sensor that “encrypts” readings before sending them to the cloud using this scheme:

def encrypt_temperature(temp):
    # Shift each digit by 3
    encrypted = ""
    for char in str(temp):
        if char.isdigit():
            encrypted += str((int(char) + 3) % 10)
        else:
            encrypted += char
    return encrypted

# Example:
temp = 25.3
encrypted = encrypt_temperature(temp)  # Returns "58.6"

Attack Analysis:

This is a digit-based Caesar cipher with shift 3. Let’s demonstrate why this is completely insecure:

Step 1: Frequency Analysis

Attacker captures 100 encrypted readings: - “58.6” appears 15 times - “69.7” appears 12 times - “47.5” appears 10 times

Reasoning: Temperature sensors in a room typically cluster around comfortable range (20-25°C). The most frequent encrypted value likely corresponds to the most common actual temperature.

Step 2: Known Plaintext Attack

Attacker observes that weather station reports 22.3°C at the same time encrypted reading is “55.6”.

Plaintext: 22.3
Ciphertext: 55.6

Mapping:
2 → 5 (shift of 3)
3 → 6 (shift of 3)

Confirmed: This is Caesar cipher with shift 3

Step 3: Decryption

def decrypt_temperature(encrypted):
    decrypted = ""
    for char in encrypted:
        if char.isdigit():
            decrypted += str((int(char) - 3) % 10)
        else:
            decrypted += char
    return decrypted

# Decrypt all captured traffic:
for reading in captured_readings:
    print(decrypt_temperature(reading))

# Output:
# 22.3
# 23.4
# 20.2
# ... (all readings exposed)

Energy Cost Analysis:

Method Time to Break Resources Needed
Brute force 10 attempts (try shifts 0-9) 0.001 seconds on laptop
Frequency analysis ~50 samples 0.1 seconds of analysis
Known plaintext 1 sample Instant

Total time to break: Less than 1 second with basic Python script.

Comparison with Real Encryption:

Metric Student’s Scheme AES-128
Key space 10 (0-9 shifts) 2^128 (3.4 × 10^38)
Time to break <1 second Billions of years
Brute force attempts 10 340,000,000,000,000,000,000,000,000,000,000,000,000
Resistant to frequency analysis ❌ No ✓ Yes
Resistant to known plaintext ❌ No ✓ Yes

The Fix:

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import os

def encrypt_temperature_properly(temp, key):
    # Use AES-128-GCM (authenticated encryption)
    nonce = os.urandom(12)  # Random nonce for each message
    cipher = Cipher(algorithms.AES(key), modes.GCM(nonce))
    encryptor = cipher.encryptor()

    plaintext = str(temp).encode()
    ciphertext = encryptor.update(plaintext) + encryptor.finalize()

    # Return: nonce + ciphertext + auth_tag
    return nonce + ciphertext + encryptor.tag

# Generate proper key (128 random bits)
key = os.urandom(16)

# Now each reading looks random, even for same temperature:
temp = 22.3
encrypted1 = encrypt_temperature_properly(temp, key)  # b'\x8a\x7f\x3c...'
encrypted2 = encrypt_temperature_properly(temp, key)  # b'\x2d\x9e\x1a...'
# Completely different every time!

Key Lesson: “Security through obscurity” doesn’t work. Custom encryption schemes are trivial to break. Always use standard, peer-reviewed cryptographic algorithms (AES, ChaCha20) implemented in well-tested libraries.

Try It: Brute-Force Time Calculator

Based on the game levels, here’s how to match cipher complexity to real IoT needs:

Level 1: Classical Ciphers (Caesar, XOR)

Acceptable Use NEVER Acceptable
Educational demonstrations Production IoT security
Obfuscation of non-sensitive display data Protecting sensor data
Checksums (weak integrity) Authentication

Example acceptable use: Obfuscating debug messages in logs (not security, just readability).

Level 2: Symmetric Encryption (AES)

Use Case Cipher Mode Key Size
Bulk data encryption AES-128-GCM 128-bit
High-security data AES-256-GCM 256-bit
Streaming data ChaCha20-Poly1305 256-bit
Legacy compatibility AES-128-CBC + HMAC 128-bit + 256-bit

Decision criteria:

Do you have hardware AES acceleration?
├─ YES → Use AES-128-GCM or AES-256-GCM
│  └─ Performance: 100+ MB/s on ESP32
│
└─ NO → Use ChaCha20-Poly1305
   └─ Performance: 2-3x faster than software AES

Level 3: Asymmetric Encryption (RSA/ECC)

Operation Small Devices (<1 MB RAM) Larger Devices
Key exchange ECDH with Curve25519 ECDH with secp256r1 (if HW) or Curve25519
Digital signatures Ed25519 (64-byte signatures) Ed25519 or ECDSA secp256r1
Certificate-based auth ECC-256 certificates ECC-256 or RSA-2048

Decision tree:

What is your primary need?
│
├─ Encrypt data for long-term storage
│  └─ Use AES-256-GCM (Level 2)
│     (Symmetric is 100x faster than RSA)
│
├─ Establish shared key with unknown device
│  └─ Use ECDH key exchange (Level 3)
│     Then switch to AES for data
│
├─ Prove message authenticity
│  └─ Use Ed25519 signatures (Level 3)
│     Attach signature to data
│
└─ Verify data has not been modified
   └─ Use SHA-256 hash (not a cipher)
      Or AES-GCM auth tag if encrypted

Energy Consumption Comparison (per operation):

Cipher Energy (mJ) Speed Use When
XOR 0.001 Ultra-fast NEVER (insecure)
AES-128-GCM 0.05 Fast Bulk data encryption
ChaCha20-Poly1305 0.08 Fast No hardware AES
ECDH key exchange 0.5 Medium Session establishment
Ed25519 signature 0.4 Medium Data authentication
RSA-2048 signature 20 Slow Legacy compatibility
Try It: IoT Encryption Energy Budget Calculator
Common Mistake: Using XOR as “Good Enough” Encryption

The Mistake: Developers think XOR with a “random” key provides adequate security for low-value IoT data.

Code example (WRONG):

// IoT sensor "encryption"
uint8_t secret_key[] = {0x4A, 0x7F, 0x2E, 0x9C};

void encrypt_sensor_data(uint8_t *data, size_t len) {
    for (size_t i = 0; i < len; i++) {
        data[i] ^= secret_key[i % 4];  // XOR with repeating key
    }
}

// "Encrypted" sensor reading sent over network
uint8_t reading[4] = {25, 0, 0, 0};  // Temperature in °C
encrypt_sensor_data(reading, 4);
send_to_cloud(reading);

Why This Fails Catastrophically:

Attack 1: Known Plaintext

Attacker knows sensor readings are temperatures (likely 0-50°C):

# Captured ciphertext
ciphertext = bytes([0x53, 0x7F, 0x2E, 0x9C])

# Guess: First byte is temperature 25°C (0x19)
guessed_plaintext = 25
recovered_key_byte = ciphertext[0] ^ guessed_plaintext
# recovered_key_byte = 0x53 ^ 0x19 = 0x4A ✓ (correct!)

# Now decrypt everything:
key = [0x4A, 0x7F, 0x2E, 0x9C]
plaintext = [c ^ k for c, k in zip(ciphertext, key)]
# Result: [25, 0, 0, 0] = 25°C

Attack 2: Crib Dragging (multiple messages with same key)

# Attacker captures two encrypted messages:
ciphertext1 = "Temp:25°C" ^ key  # b'\x63\x04\x5a...'
ciphertext2 = "Temp:26°C" ^ key  # b'\x63\x04\x5b...'

# XOR the two ciphertexts:
crib = ciphertext1 ^ ciphertext2
# Result: "Temp:25°C" ^ "Temp:26°C"
# = 0x00 0x00 0x00 0x00 0x01
# Reveals: Plaintexts differ only in last byte!

# Attacker now knows:
# - Both messages start with "Temp:"
# - Values are 25 and 26
# - Can decrypt ALL future messages

Attack 3: Frequency Analysis

# Attacker collects 1000 encrypted readings
# Counts most common first byte: 0x53 appears 150 times

# Reasoning: Room temperature is typically 20-22°C
# Most common encrypted value likely represents most common temperature

for guess in range(20, 25):
    possible_key = 0x53 ^ guess
    print(f"If plaintext was {guess}, key byte is {hex(possible_key)}")

# Try each candidate key on all captured traffic
# Correct key will produce sensible temperature values (0-50°C)
# Wrong keys will produce garbage (>100°C or negative)

Real-World Consequences:

Case Study: Smart building HVAC system used XOR “encryption” for sensor data: - Attacker captured 1 hour of traffic (720 messages) - Used known plaintext attack (knew outdoor temperature from weather API) - Recovered encryption key in 5 minutes - Decrypted 6 months of archived sensor data - Sold occupancy patterns to competitor

Cost: $3M contract lost, $500K legal fees

Energy Savings from XOR: 0.001 mJ per message Security cost: Complete compromise

The Fix: Use AES-128-GCM

#include <mbedtls/gcm.h>

// Proper authenticated encryption (simplified -- production code
// must also call mbedtls_gcm_init and mbedtls_gcm_setkey)
void encrypt_sensor_data_properly(const uint8_t *plaintext,
                                   size_t len,
                                   uint8_t *ciphertext,
                                   uint8_t *tag) {
    mbedtls_gcm_context ctx;
    uint8_t key[16] = { /* Securely provisioned key */ };
    uint8_t nonce[12];  // Random nonce per message

    mbedtls_gcm_init(&ctx);
    mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, 128);

    // Generate random nonce
    generate_random(nonce, 12);

    // AES-128-GCM encryption
    mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
                               len, nonce, 12, NULL, 0,
                               plaintext, ciphertext,
                               16, tag);

    mbedtls_gcm_free(&ctx);
    // Send: nonce || ciphertext || tag
}

Energy cost: 0.05 mJ per message (50x more than XOR) Security benefit: Prevents ALL known attacks

The principle: Never implement your own encryption. The energy savings are negligible, but the security cost is total compromise. Always use standard, peer-reviewed algorithms.

Try It: XOR Encryption Visualizer
Concept Relationships

This game teaches cryptographic concepts through progressive difficulty:

Level Concepts Real IoT Equivalent Why It Matters
Level 1: Classical Caesar, XOR, patterns Historical context Understand why complexity is required
Level 2: Symmetric AES modes, HMAC, KDFs E1/E2/E3 encryption Modern IoT data protection
Level 3: Asymmetric RSA, signatures, DH E5 key renewal Solving key distribution

Progression: Classical (broken) → Symmetric (fast but needs key exchange) → Asymmetric (solves key problem) → Hybrid (best of both).

25.4 See Also

Next Steps:

Concepts from the Game:

Real-World Application:

Common Pitfalls

Base64 and hex encoding are reversible transformations with no secret key — they provide zero security. Developers sometimes use encoding thinking it obscures data. Always distinguish between encoding (data format change) and encryption (requires a secret key).

Keeping the algorithm secret instead of the key is a fundamentally flawed approach. Modern cryptographic security relies on Kerckhoffs’s principle: the algorithm is public; only the key is secret.

Implementing custom ciphers or modifying standard algorithms almost always introduces subtle vulnerabilities invisible to non-experts. Use vetted libraries (OpenSSL, mbedTLS, libsodium) implementing standardized algorithms.

25.5 Summary

This game covers:

  • Level 1: Classical ciphers show why simple substitution is insecure
  • Level 2: Block cipher modes, authentication, and key derivation
  • Level 3: Public-key cryptography, signatures, and key exchange

Understanding these concepts helps you make informed security decisions for IoT systems.

25.6 Knowledge Check

::

Key Concepts

  • Caesar Cipher: A simple substitution cipher shifting each letter by a fixed number of positions — historically significant, trivially broken by frequency analysis, but useful for illustrating basic encryption concepts.
  • Frequency Analysis: A cryptanalysis technique that exploits the non-uniform distribution of letters in natural language to break simple substitution ciphers.
  • Key Space: The set of all possible keys for a given cipher; a key space of 2^128 means an attacker must try up to 2^128 combinations in a brute-force attack.
  • Brute Force Attack: Systematically trying every possible key or password until the correct one is found; feasible only when key space is small.
  • Diffie-Hellman Key Exchange: A protocol allowing two parties to establish a shared secret over a public channel; the foundation of modern key exchange, illustrated well with color-mixing analogies.
  • Padding Oracle Attack: An attack exploiting error messages from a decryption system to deduce plaintext one byte at a time, demonstrating why authenticated encryption is essential.

::

25.7 What’s Next

If you want to… Read this
Learn how symmetric encryption really works Symmetric Encryption
Understand asymmetric and public-key concepts Asymmetric Encryption
Try hands-on encryption labs Encryption Labs
Explore interactive cryptography tools Interactive Cryptography Tools

Return to the Encryption Principles Overview for a complete guide to all encryption topics, or explore specific chapters for deeper coverage of any topic.