Why certain number-theoretic problems are treated as “hard” in complexity theory, and why hashing has an adversarial-input problem on judges like Codeforces: both come from the same handful of cryptographic primitives. Nothing here is a contest algorithm to implement from scratch; the value is knowing why factoring, discrete log and hash collisions are believed hard, since that belief is what several other notes lean on.

RSA

Public key with ( distinct large primes), private key with . Encrypt ; decrypt (fast modular exponentiation).

Why it’s believed secure: recovering from the public is believed to require factoring (known equivalent: computing lets you solve for directly, and together with lets you recover and , hence via the quadratic formula). Pollard’s rho / Pollard’s p-1 factor in -ish time for an -bit number — far too slow for 2048-bit RSA primes, but exactly the technique this repo already implements for factoring numbers small enough for a contest. Shor’s algorithm (quantum, see Quantum Computing Basics) factors in polynomial time, which is the reason RSA is considered broken once large fault-tolerant quantum computers exist.

Diffie–Hellman key exchange

Public: a prime and a primitive root (Primitive Roots). Alice picks secret , sends ; Bob picks secret , sends . Shared secret: — both sides compute the same value without ever transmitting or .

Why it’s believed secure: an eavesdropper sees and must recover — the computational Diffie–Hellman problem, believed as hard as the discrete logarithm problem (recover from ). Baby-step giant-step solves discrete log in — fine for the small moduli a contest uses, catastrophically slow for the 2048+-bit primes real Diffie–Hellman uses. Shor’s algorithm also solves discrete log in polynomial time on a quantum computer, by the same kind of period-finding it uses against factoring.

What makes a hash function cryptographically safe

PropertyMeansWhy judges care
Preimage resistancegiven , hard to find any with prevents forging an input for a known hash
Second-preimage resistancegiven , hard to find with —
Collision resistancehard to find any with the one that matters for CP string hashing

Polynomial string hashing mod a fixed, small, known modulus has none of these properties against an adversary who knows the modulus — anti-hash tests on Codeforces construct deliberate collisions by solving a linear system over the known modulus. The fixes used in practice (random base chosen at runtime, double hashing with two random moduli, or a modulus large and secret enough that it can’t be inverted offline) don’t make the hash cryptographic, they just make the specific collision-construction attack infeasible for that submission — a genuinely different and much weaker guarantee than what SHA-256 provides. Real cryptographic hashes (SHA-2, SHA-3/Keccak) are collision-resistant against anyone, with no secret parameter at all; they’re irrelevant for CP performance reasons (far slower per byte) but are the thing “hash function” means outside of CP.

The complexity assumptions underneath all of this

AssumptionBelieved true?What breaks if false
Integer factorization is hard (no polynomial classical algorithm)yes, unprovenRSA
Discrete log (and Diffie–Hellman) is hardyes, unprovenDiffie–Hellman, ElGamal
SHA-2/SHA-3 are collision-resistantyes (no known attack better than generic birthday bound), unprovendigital signatures, blockchains, anything hash-committed
widely believed, unprovenif false, breaks essentially all of modern cryptography at once, see [[24-beyond-cp/01-complexity-theory

None of these are theorems — they’re the strongest conjectures complexity theory has, and essentially all of applied cryptography rests on believing them.