Learn / Math / Hash Functions & Random Oracles
14. Hash Functions & Random Oracles
Hash Functions · Lesson 15 of 18 · 4:02
The tool that doesn't come from algebra at all but shows up everywhere in ZK — how a hash function turns a live back-and-forth between a prover and a verifier into something the prover can do entirely alone.

This series has spent thirteen lessons building up numbers, polynomials, fields, groups, and curves. This lesson steps outside algebra entirely — into a tool that doesn’t come from any of that machinery, yet shows up everywhere in ZK anyway: the hash function. By the end, the goal is to see exactly how it turns a live, back-and-forth conversation between a prover and a verifier into something a prover can do completely alone.

What is a hash function?

A hash function takes anything — a word, a sentence, an entire file — and always hands back an output of the exact same size.

any size in, the same size out input: any size digest: fixed size Hi 2cf24dba… 9824 Hello, world! 315f5bdb… f2d3 A 5 GB video file e3b0c442… b855 H(x) DETERMINISTIC · FIXED SIZE · ONE-WAY same input always gives the same digest — change one bit and it changes completely
Fig. 1 — three wildly different inputs, all passing through H(x), all coming out the same fixed length.
A hash function

H:{0,1}∗→{0,1}nH : \{0,1\}^{*} \rightarrow \{0,1\}^{n}

Input of any length goes in; output of one fixed length nn comes out. Three properties make it useful: it’s deterministic (the same input always gives the same digest), fixed-size (output length never varies), and one-way (there’s no going backward).

The one-way property

Going from xx to f(x)f(x) — computing the function — is easy. Going backward, from f(x)f(x) trying to recover xx, is infeasible. There’s no shortcut; the only option is searching through every possible xx.

easy to compute, infeasible to reverse x f(x) EASY compute f(x) from x INFEASIBLE cannot recover x from f(x) EASY FORWARD · IMPOSSIBLE BACKWARD
Fig. 2 — computing forward is trivial. Reversing it means brute-forcing every possible input.

Collision resistance

That’s the second property a good hash function needs, separate from being one-way, and just as important. Take two inputs one letter apart — Hello and Hellp — and run both through the same hash function. Landing on the same digest is exactly what’s not supposed to happen.

two different inputs, the same digest — blocked two different inputs x₁ : Hello ≠ x₂ : Hellp H(x) COLLISION same digest 2cf24dba…9824 NO TWO INPUTS, ONE DIGEST finding x₁ ≠ x₂ with H(x₁) = H(x₂) is infeasible
Fig. 3 — two different inputs, even one character apart, must never land on the same digest.
Collision resistance

Finding any x1≠x2x_1 \ne x_2 with H(x1)=H(x2)H(x_1) = H(x_2) must be infeasible — not impossible in principle (pigeonhole guarantees collisions exist somewhere), just impossible to actually find one.

The random oracle model

To reason about hash functions mathematically, cryptographers lean on a simplified mental model: pretend the hash function is a magic box that hands out pure randomness. Ask about x1x_1 for the first time, and the oracle hands back r1r_1 — a fresh random answer. Ask about a new input x2x_2, and it hands back a completely different random answer, r2r_2. The oracle remembers both. Ask about x1x_1 again, and it doesn’t roll new randomness — it looks up what it already committed to and returns the exact same r1r_1.

O(x): truly random, yet consistent queries responses x₁ r₁ random x₂ r₂ random x₁ again r₁ again O(x) MEMORY TABLE x₁ → r₁ x₂ → r₂ random on first use NEW INPUT: FRESH OUTPUT · REPEAT INPUT: SAME OUTPUT
Fig. 4 — a new query gets a fresh random answer; a repeated query gets back exactly what it got before.

Why this matters for ZK

Here’s the payoff for the whole lesson — the reason ZK proof systems care about any of this. Normally, an interactive proof needs both sides online at the same time: the prover sends a commitment aa, the verifier fires back a random challenge cc, and the prover replies with a response zz. That live round-trip is a real constraint.

The Fiat-Shamir transform removes it. Instead of waiting on a verifier, the prover derives that same challenge themselves — by hashing the transcript so far.

the hash removes the verifier from the room INTERACTIVE Prover Verifier 1. commitment a 2. random challenge c 3. response z both online at once NON-INTERACTIVE Prover Verifier prover derives the challenge c = H(transcript) proof (a, c, z) verifier checks later, offline THE HASH PLAYS THE VERIFIER'S ROLE it acts as a random oracle, so H(transcript) gives a fresh, unpredictable challenge
Fig. 5 — on the left, prover and verifier both have to be online. On the right, the prover hashes the transcript to produce its own challenge, and sends the whole proof as one package.
The Fiat-Shamir transform

c=H(transcript)c = H(\text{transcript})

The hash plays the verifier’s role. Because it behaves like a random oracle, H(transcript)H(\text{transcript}) gives a fresh, unpredictable challenge — exactly like a live verifier would, without a verifier needing to be there at all.

That one substitution — a hash standing in for a verifier’s random coin flip — is what turns an interactive proof into something a prover can run alone, and it’s the trick underneath every non-interactive proof system that follows.