Skip to content

Cryptography — Learning Library

A learning library about how cryptography actually works, built the same way as its siblings encodings-learning-library ↗ and rust-learning-library ↗: one idea per page, and every claim backed by a program that actually runs.

No page here hand-types what a program prints. Each lesson links real example files — Python, Rust, and shell — and a tool runs them, checks the output against a recorded answer key, and pastes that verified output into the page. CI fails, on Ubuntu and macOS, if any of them drift apart. So when a page says "this leaks the picture", that is not a warning — it is a test result.

📖 Read it as a site: https://masiarek.github.io/cryptography-learning-library/

This is a library for understanding, not a library for deploying. Every implementation here is written to be read: small, slow, and unhardened. Real cryptographic code has to survive attackers with a stopwatch and a fault injector, and none of this code has been near one. The rule is on every page that needs it, and it is not decoration: learn it here, use a reviewed library there.

The root problem: cryptography does not make a secret, it MOVES one

This is the sentence the whole library hangs from. A cipher does not make your message unreadable — it makes your message exactly as unreadable as the key is unknown. You have not removed a secret from the world; you have swapped a large, awkward secret (the message) for a small, portable one (the key), and everything you now have to do — generate the key, store it, send it to the other side, replace it, destroy it — is the real subject.

Read that way, a lot of things stop being separate topics:

  • ROT13 ↗ is not encryption because there is no secret to move into — the shift is published in the method's own name.
  • The one-time pad is perfect and nearly useless for the same reason from the other end: it moves the secret into a key as long as the message, so you have traded a problem for an identical one.
  • Public-key cryptography was revolutionary because it moves the secret into something you never have to transmit at all.
  • Passwords need a slow hash because the secret being moved is one a human chose, and humans choose from a small set.
  • And nearly every real-world break is a failure of that movement — a key reused, a nonce repeated, a random number that was not random — rather than a broken cipher.

Which leads to the second rule of this library: almost nothing is broken by breaking the maths. AES has stood for twenty-five years. SHA-256 has never been collided. The breaks are in the joins — how the pieces are put together, what leaks while they run, and who was holding the key. So the chapters build the primitives first and then spend a whole chapter on the joins.

Start here

00_Start_Here/ is the plan: the chapters in reading order, the four checkpoints they lead to, and how to work a lesson.

The course, in order

Chapter The question it settles
01_What_Cryptography_Is What is a key, what are you protecting, and against whom?
02_Classical_Ciphers The ciphers you can break by hand — and what breaking one teaches
03_Randomness Where do keys come from, and what does "random" have to mean?
04_Hashing A one-way function with no key: what it promises, and what it does not
05_Symmetric One shared key: block ciphers, the modes you must choose, and the nonce
06_Integrity_and_MACs How do you know a message was not changed — and who is asking?
07_Public_Key Two keys, one public: how a shared secret is made in the open
08_Passwords The secret a human chose, and why it needs different machinery
09_Protocols TLS, certificates, signatures, tokens — the primitives assembled
10_How_It_Breaks The joins: nonce reuse, padding oracles, timing, downgrade
11_Real_World What this looks like in a job — SAP, databases, key management
12_History Enigma, DES, the Crypto Wars, and why the politics is part of the subject
13_Frontier Post-quantum, zero-knowledge, homomorphic — what is actually here yet

The chapters are stubs for now — each one's questions written down, with a notice, and no example behind it yet — except the pages listed in ROADMAP.md as written. That is deliberate: the plan gets a shape and every page gets its permanent URL before the prose does.

What you need

Nothing to install. The examples are stdlib-only Python, bare rustc, and the openssl your machine already has — no cryptography, no pycryptodome, no crates. That constraint is the pedagogy: a library that pip-installs a crypto package teaches you to call it, and this one is about what the call is doing.

One thing worth knowing before your first shell example: /usr/bin/openssl on macOS is LibreSSL, and on Linux it is OpenSSL 3. They agree on every ciphertext and every digest — they have to, those are standards — and they disagree about how they print them and about which subcommands exist at all. CONTRIBUTING.md has the measured list.

See also