/cryptopals-crypto-challenges

The Cryptopals Crypto Challenges

Primary LanguagePythonMIT LicenseMIT

The Cryptopals Crypto Challenges

What It is

The cryptopals challenges (https://cryptopals.com/) are a set of practical cryptography exercises that simulate real-world crypto attacks. They're derived from weaknesses in real-world systems and modern cryptographic constructions.

What's The Purpose Of This Project

The following is my walkthrough of these challenges using the Python 3.10, although only the solution is provided without a detailed explanation (might be added later on), since it should be understandable from the code itself and inserted comments in it.

Status Of This Project

This is still a work in progress. Since I am not solving the challenges on a regular basis, the update schedule is erratic. In the table of contents, every solved challenge is indicated with a ✔️, while every unsolved challenge is marked with a ❌.

Structure Of This Project

.
├── cryptopals
│   ├── s01
│   │   ├── c01                     
│   │   │   ├── README.md
│   │   │   ├── solution_c01.py
│   │   │   └── test_c01.py
│   │   └── ...
│   ├── s02
│   ├── ...
│   ├── utils.py
│   └── ...
├── ...
├── .gitignore
├── LICENSE
├── pyproject.toml
├── README.md
└── requirements.txt

Sets

Each set of challenges has it's corresponding folder with the according number, e.g. the challenges from Set 1 - Basics reside in folder s01.

Challenges

Every challenge has it's corresponding folder with the according number, e.g. the Challenge 1 - Convert hex to base64 has its own folder c01.

Solution

The solution for the particular challenge has a "solution_" prefix added to it, e.g. solution for Challenge 1 is in module solution_c01.py.

#
#   01 - Convert hex to base64
#

import codecs


def hex_to_base64(hex_bytes: bytes) -> bytes:
    return codecs.encode(codecs.decode(hex_bytes, "hex"), "base64").rstrip()

Test

Test for the solution has a "test_" prefix added to it, e.g. test for solution of Challenge 1 is in test_c01 module.

#
#   01 - Convert hex to base64
#

from cryptopals.s01.c01.solution_c01 import hex_to_base64


def test_c01() -> None:
    # Input String
    string = b"49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"
    
    # Valid Result
    result = b"SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t"
    
    assert hex_to_base64(string) == result

Refactored Solutions

Every solution/code that proves useful is refactored and moved to a different module, that'll be used in the future challenges. For e.g., the solution for Challenge 1, is going to be refactored into a Converter class in the module utils:

# utils.py

class Converter:
    @staticmethod
    def hex_to_base64(hex_bytes: bytes) -> bytes:
        return codecs.encode(codecs.decode(hex_bytes, "hex"), "base64")

How To Run

Virtual Environment

Python virtual environment is being used for running these challenges, with a small guide on how to set it up here:

Installation And Activation

# Install virtualenv If Not Already Installed
$ pip install virtualenv

# Create The Virtual Environment
$ virtualenv -p python3 venv

# Activate The Virtual Environment
$ source venv/bin/activate

Deactivation

# Deactivate The Virtual Environment After Being Done Running This Project
(venv) $ deactivate

Dependencies

The dependencies must be installed for everything to work properly by running the following command:

# Install The Dependencies For The Virtual Environment
(venv) $ pip install -r requirements.txt

Tests

Running The Tests

To run the tests for the solutions, run the pytest command:

# Run pytest With The Verbosity Flag
(venv) $ pytest -v

test_c01.py::test_c01 PASSED                                                                                        [100%]

Timeout

The timeout for every test is set to 120 seconds by default, however it may have to be increased if some solutions take longer to give the final result for the tests. This timeout can be configured in the pyproject.toml file as follows:

[tool.pytest.ini_options]
timeout = 120

Table Of Contents

  • Set 1: Basics
    1. Convert hex to base64 ✔️
    2. Fixed XOR ✔️
    3. Single-byte XOR cipher ✔️
    4. Detect single-character XOR ✔️
    5. Implement repeating-key XOR ✔️
    6. Break repeating-key XOR ✔️
    7. AES in ECB mode ✔️
    8. Detect AES in ECB mode ✔️
  • Set 2: Block crypto
    1. Implement PKCS#7 padding ✔️
    2. Implement CBC mode ✔️
    3. An ECB/CBC detection oracle ✔️
    4. Byte-at-a-time ECB decryption (Simple) ✔️
    5. ECB cut-and-paste ✔️
    6. Byte-at-a-time ECB decryption (Harder) ✔️
    7. PKCS#7 padding validation ✔️
    8. CBC bitflipping attacks ✔️
  • Set 3: Block & stream crypto
    1. The CBC padding oracle ✔️
    2. Implement CTR, the stream cipher mode ✔️
    3. Break fixed-nonce CTR mode using substitutions ✔️
    4. Break fixed-nonce CTR statistically ✔️
    5. Implement the MT19937 Mersenne Twister RNG ✔️
    6. Crack an MT19937 seed ✔️
    7. Clone an MT19937 RNG from its output ✔️
    8. Create the MT19937 stream cipher and break it ✔️
  • Set 4: Stream crypto and randomness
    1. Break "random access read/write" AES CTR ✔️
    2. CTR bitflipping ✔️
    3. Recover the key from CBC with IV=Key ✔️
    4. Implement a SHA-1 keyed MAC ✔️
    5. Break a SHA-1 keyed MAC using length extension ✔️
    6. Break an MD4 keyed MAC using length extension ✔️
    7. Implement and break HMAC-SHA1 with an artificial timing leak ✔️
    8. Break HMAC-SHA1 with a slightly less artificial timing leak ✔️
  • Set 5: Diffie-Hellman and friends
    1. Implement Diffie-Hellman ✔️
    2. Implement a MITM key-fixing attack on Diffie-Hellman with parameter injection ✔️
    3. Implement DH with negotiated groups, and break with malicious "g" parameters ✔️
    4. Implement Secure Remote Password (SRP) ✔️
    5. Break SRP with a zero key ✔️
    6. Offline dictionary attack on simplified SRP ✔️
    7. Implement RSA ✔️
    8. Implement an E=3 RSA Broadcast attack ✔️
  • Set 6: RSA and DSA
    1. Implement unpadded message recovery oracle ✔️
    2. Bleichenbacher's e=3 RSA Attack ✔️
    3. DSA key recovery from nonce ✔️
    4. DSA nonce recovery from repeated nonce ✔️
    5. DSA parameter tampering ✔️
    6. RSA parity oracle ✔️
    7. Bleichenbacher's PKCS 1.5 Padding Oracle (Simple Case) ✔️
    8. Bleichenbacher's PKCS 1.5 Padding Oracle (Complete Case) ✔️
  • Set 7: Hashes
    1. CBC-MAC Message Forgery ❌
    2. Hashing with CBC-MAC ❌
    3. Compression Ratio Side-Channel Attacks ❌
    4. Iterated Hash Function Multicollisions ❌
    5. Kelsey and Schneier's Expandable Messages ❌
    6. Kelsey and Kohno's Nostradamus Attack ❌
    7. MD4 Collisions ❌
    8. RC4 Single-Byte Biases ❌
  • Set 8: Abstract Algebra
    1. Diffie-Hellman Revisited: Small Subgroup Confinement ❌
    2. Pollard's Method for Catching Kangaroos ❌
    3. Elliptic Curve Diffie-Hellman and Invalid-Curve Attacks ❌
    4. Single-Coordinate Ladders and Insecure Twists ❌
    5. Duplicate-Signature Key Selection in ECDSA (and RSA) ❌
    6. Key-Recovery Attacks on ECDSA with Biased Nonces ❌
    7. Key-Recovery Attacks on GCM with Repeated Nonces ❌
    8. Key-Recovery Attacks on GCM with a Truncated MAC ❌
    9. Truncated-MAC GCM Revisited: Improving the Key-Recovery Attack via Ciphertext Length Extension ❌
    10. Exploiting Implementation Errors in Diffie-Hellman ❌

License

Everything in this repository is released under the terms of the MIT License. For more information, please see the file "LICENSE".