Skip to content
CryptoAcademy logo CryptoAcademy
Menu
Lesson Beginner · 10 min

Choosing the right primitive

Most cryptographic failures are not broken maths — they are the right algorithm used for the wrong job. This lesson is a lookup table you can keep.

In this lesson

  • Map a requirement to a modern algorithm
  • Explain why defaults beat clever designs
  • Audit a codebase for legacy primitives

The decision table

Requirement Use Avoid
Password storage Argon2id, bcrypt, scrypt SHA-256, MD5, encryption
File/message integrity SHA-256, SHA-3, BLAKE3 MD5, SHA-1
Message authentication HMAC-SHA-256 Home-grown MACs
Data at rest / in transit AES-256-GCM, ChaCha20-Poly1305 ECB mode, DES, RC4
Key exchange X25519 (TLS 1.3) Static RSA key exchange
Signatures Ed25519, ECDSA P-256 DSA, RSA PKCS#1 v1.5 padding
Random tokens / nonces CSPRNG (random_bytes) mt_rand, time(), UUIDv4

Example · A checklist for code review

Search the codebase for md5(, sha1(, AES/ECB, rand( and hard-coded IVs. Each hit is either a bug or a deliberate, documented exception.

Prefer libraries over algorithms

Use libsodium (NaCl), cryptography in Python, or your platform's TLS. You choose the primitive; the library handles nonces, padding and key derivation safely.

Break a weak design

Brute-force the Caesar cipher, then consider what "the algorithm is secret" bought the designer.

Try it yourself

Match properties to primitives

Practice · server-graded
  • Select every property of a cryptographic hash function.

    1 pt
Should I ever invent my own protocol?

Composing proven primitives is hard enough — novel protocol design needs formal review and years of scrutiny. Use what TLS/Signal already solved.

What about post-quantum?

Hybrid key exchange (X25519 + ML-KEM) is already shipping in TLS. Plan migrations for long-lived secrets now.

Share this page

Send this link to a friend, or scan the QR code to open it on your phone.