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¶
- encodings-learning-library ↗ — the sibling this one grew out of. Its Rotation is not encryption ↗ is where a substitution table stops being an encoding question, and 02_Classical_Ciphers is where this library picks it up.
- CONTRIBUTING.md — house rules, for whoever is about to write a page.