WitsCoin

COMS4065A - Cryptography | University of the Witwatersrand

Leaderboard

Problems

Problem 1: Registration
POST /problem1/register with your @students.wits.ac.za email. You will receive a Vigenere phrase and secret key via email. Encrypt the phrase using your student number as the key (0=A, 1=B, 2=C, ..., 9=J). Submit to /problem1/verify with your email, encrypted phrase, and secret key.

Problem 2: Wallet Creation
Generate RSA keys using your secret key. Find the 2 primes p and q closest to your secret key. Submit your public key to /problem2/create.

After problem 2, you can check out the leaderboard to monitor your progress.

Problem 3: Signatures
Sign a message using raw RSA: s = hash^d mod n. Submit to /problem3/verify with your wallet address, message, and base64-encoded signature.

Problem 4: Make a transaction
Create a signed transaction at /problem4/transfer to send any amount of WitsCoin to any wallet. Use your RSA signature to authorize the transaction. Transactions start in PENDING state and are confirmed when a block is mined.

Problem 5: Mining and the Merkle Tree
Implement SHA-256 and find a valid nonce where the block hash has the required number of leading binary zeros.

Block Hash Format:
SHA-256(block_number + previous_hash + merkle_root + timestamp + nonce + reward)

The merkle_root is a hash of all transactions in the block. Learn how to compute the Merkle root →

Check /problem5/difficulty for current difficulty. Submit to /problem5/mine. Earn 50 WitsCoin per block.
Fetch the latest block from /blockchain/latest to get the previous hash and pending transactions. A good mining rate is ~4 to 5 million hashes per second.

Problem 6: Send to Joshua
Send at least 100 WitsCoin to joshua_wits_coin_2026. The leaderboard tracks who sent the most to Joshua.

API Documentation

GET /info

Returns detailed system information.

Response:

{
  "name": "WitsCoin",
  "version": "1.0.0",
  "mining_difficulty": 20,
  "mining_reward": 50,
  "hash_algorithm": "SHA-256",
  "signature_scheme": "RSA-RAW"
}

GET /problem1

Returns the Vigenere cipher challenge description.

POST /problem1/register

Register with your student email. Must use @students.wits.ac.za email.

Request:

{
  "email": "1234567@students.wits.ac.za"
}

Response 200 OK:

{
  "message": "Registration successful! Check your email for your secret key.",
  "student_number": "1234567"
}

Response 400 Bad Request:

{
  "error": "Invalid email format",
  "message": "Email must be in format: studentNumber@students.wits.ac.za"
}

POST /problem1/verify

Verify your encrypted Vigenere phrase and secret key. The secret key from your email is required to prove you own the email address.

Request:

{
  "email": "1234567@students.wits.ac.za",
  "encrypted_code": "ENCRYPTED_PHRASE_HERE",
  "secret_key": "your-secret-key-from-email"
}

Response 200 OK:

{
  "success": true,
  "message": "Congratulations! You have solved the Vigenere challenge...",
  "instruction": "Now create your wallet. You will need to provide your secret key AND generate RSA keys!"
}

Response 400 Bad Request:

{
  "error": "Incorrect code",
  "hint": "Check your Vigenere implementation. Remember: encryption adds, decryption subtracts (mod 26)."
}

Response 401 Unauthorized:

{
  "error": "Invalid secret key",
  "hint": "Check your email for the secret key sent after registration."
}

GET /problem2

Returns the wallet creation challenge with RSA key generation instructions.

POST /problem2/create

Create your wallet by providing RSA keys generated from your secret key.

Public key must be PEM format with BEGIN/END PUBLIC KEY headers.

Request:

{
  "email": "1234567@students.wits.ac.za",
  "secret_key": "vTxrnvTCZhHDNxt6rKSU...",
  "public_key": "-----BEGIN PUBLIC KEY-----\nMIIB...\n-----END PUBLIC KEY-----",
  "p": "859412498474947518650802749266779491",
  "q": "859412498474947518650802749266779467",
  "e": 65537
}

Response 200 OK:

{
  "success": true,
  "message": "Wallet created successfully!",
  "wallet_address": "wc_a1b2c3d4e5f6...",
  "balance": 50
}

GET /problem3

Returns the signature verification challenge with instructions for raw RSA signing.

POST /problem3/verify

Verify a digital signature to prove you can sign transactions using raw RSA.

Request:

{
  "wallet_address": "wc_a1b2c3d4e5f6...",
  "message": "I agree to the terms and conditions of WitsCoin - Signed: wc_a1b2c3d4e5f6...",
  "signature": "base64encodedsignature..."
}

Response 200 OK:

{
  "success": true,
  "message": "Signature verified successfully!",
  "instruction": "You can now send transactions at /problem4/transfer"
}

GET /problem4

Returns the transaction challenge with RSA signature instructions.

POST /problem4/transfer

Send WitsCoin to any wallet. Requires RSA signature. You must provide your secret key to authorize the transaction.

Request:

{
  "from_address": "wc_a1b2c3d4e5f6...",
  "secret_key": "vTxrnvTCZhHDNxt6rKSU...",
  "to_address": "joshua_wits_coin_2026",
  "amount": 100,
  "signature": "base64signature..."
}

Response 200 OK:

{
  "success": true,
  "message": "Transaction submitted!",
  "transaction_id": "uuid-here",
  "from": "wc_a1b2c3d4e5f6...",
  "to": "joshua_wits_coin_2026",
  "amount": 100,
  "total_to_joshua": 250,
  "leaderboard": "/leaderboard to see your ranking!"
}

Response 401 Unauthorized:

{
  "error": "Invalid secret key",
  "hint": "You must provide the secret key that was emailed to you."
}

Response 400 Bad Request:

{
  "error": "Insufficient balance",
  "balance": 50,
  "requested": 100
}

GET /problem5

Returns the mining challenge description with current difficulty.

GET /problem5/difficulty

Returns the current mining difficulty (number of leading binary zeros required).

POST /problem5/mine

Submit your mining solution. You must provide the secret key to prove wallet ownership.

Request:

{
  "wallet_address": "wc_a1b2c3d4e5f6...",
  "secret_key": "vTxrnvTCZhHDNxt6rKSU...",
  "nonce": 1234567,
  "hash": "00000000a3f2b4c5d6e7f8...",
  "timestamp": 1714567890
}

Response 200 OK:

{
  "success": true,
  "message": "Block mined successfully!",
  "block_number": 42,
  "hash": "00000000a3f2...",
  "nonce": 1234567,
  "reward": 50
}

Response 401 Unauthorized:

{
  "error": "Invalid secret key",
  "hint": "You must provide the secret key that was emailed to you."
}

GET /balance/{wallet_address}

Check the balance of any wallet.

Response:

{
  "address": "wc_a1b2c3d4e5f6...",
  "balance": 150,
  "message": "wc_a1b2c3d4e5f6... has 150 WitsCoin"
}

GET /blockchain/latest

Get the most recent block in the blockchain.

GET /blockchain/blocks

Get the last 10 blocks in the blockchain.

GET /blockchain/{block_number}

Get a specific block by its number.

GET /problem4/pending

View pending transactions in the pool. Transactions start in PENDING state and are confirmed when a block is mined.

POST /leaderboard

See the top transactors to Joshua's wallet. Requires authentication via secret_key in request body.

Request:

{
  "secret_key": "your-secret-key"
}

Response:

{
  "joshua_wallet": "joshua_wits_coin_2026",
  "goal_for_problem4": "Any transaction (send to any wallet)",
  "goal_for_problem6": ">100 WitsCoin sent to Joshua",
  "total_transactors": 42,
  "leaderboard": [
    {
      "rank": 1,
      "wallet": "wc_a1b2c3d4e5f6...",
      "total_amount": 500,
      "transaction_count": 5
    }
  ]
}

GET /help

List all available endpoints.

GET /hint/{topic}

Get hints for specific cryptographic topics.

Available topics: vigenere, rsa, sha256, mining, signature, blockchain, difficulty