Zero-Knowledge Proofs: An Introduction

Imagine proving you know a secret password without revealing it. This sounds paradoxical, yet it is exactly what zero-knowledge proofs achieve. A prover convinces a verifier that a statement is true. For example: "I know the discrete logarithm of this public value." No information leaks beyond the statement's truth. The verifier ends the interaction fully convinced. Yet they gain no new ability to impersonate the prover afterward. This capability matters far beyond cryptographic curiosities. Modern authentication systems depend on proving knowledge of a secret without exposing it. So do privacy-preserving cryptocurrencies and anonymous credential schemes. Blockchain rollups compress thousands of transactions into a single succinct proof of correct execution. None of that would be trustworthy without the theoretical bedrock of zero-knowledge proofs. The concept transforms cryptography from "hiding data" into "hiding computation while revealing only its verdict." The big picture is a careful balancing act between three competing properties. A proof system must be complete (honest provers always succeed). It must be sound (cheating provers almost always fail). It must also be zero-knowledge (the transcript reveals nothing extra). Achieving all three simultaneously is the central technical challenge. Proving it rigorously is equally essential. This article addresses that challenge using the cleanest possible example. This article builds the Schnorr protocol from first principles. It is a three-move "sigma protocol" over the Discrete Logarithm Problem. You will see the exact algorithm and a worked numerical trace. A diagram of the interaction is included as well. Rigorous arguments show why each of the three properties holds. This includes the simulator argument, which makes "zero-knowledge" precise. It becomes a mathematical claim rather than a slogan.

Key takeaways
  • A zero-knowledge proof lets a prover convince a verifier a statement is true, revealing nothing else.
  • Three properties define it: completeness, soundness, and zero-knowledge (simulatability).
  • The Schnorr protocol is a canonical sigma protocol proving knowledge of a discrete logarithm.
  • It runs in three moves: commitment, random challenge, response — checked with one equation.
  • Soundness relies on special soundness: two accepting transcripts with the same commitment extract the secret.
  • Zero-knowledge relies on a simulator that fakes transcripts without knowing the secret, indistinguishably.
The core insight

A zero-knowledge proof convinces a verifier a secret exists and satisfies a relation, while the transcript stays simulatable without the secret — that simulatability is the mathematical meaning of "zero knowledge."

The idea

A proof system for a relation RR involves a prover PP who claims to know a witness ww such that (x,w)∈R(x, w) \in R for a public statement xx, and a verifier VV who checks this claim through an interactive protocol. In our running example, the statement is a public group element y=gx  py = g^x \bmod p, and the witness is the discrete logarithm xx. The verifier already trusts yy, gg, and pp; what remains unknown is whether the prover truly knows xx. Three properties formalize what "a good proof system" means. Completeness says that if the prover honestly knows a valid witness and follows the protocol, the verifier accepts with probability 1 (or overwhelming probability). Soundness says that if no valid witness exists, or the prover does not know one, then any prover strategy — however malicious — is caught with high probability; formally, a cheating prover succeeds with probability at most a small soundness error ε\varepsilon. Zero-knowledge says that whatever the verifier learns from the interaction, it could have generated on its own without any prover at all — formalized by exhibiting a simulator SS that outputs transcripts indistinguishable from real ones, given only the public statement xx. The protocol studied here belongs to a family called sigma protocols (Σ-protocols), named for the shape of their message flow: commitment, challenge, response — three moves forming a Σ-like zigzag when drawn. Sigma protocols share a common analytical toolkit: special soundness (extraction from two transcripts sharing a commitment but differing challenges) proves soundness, and an explicit honest-verifier zero-knowledge (HVZK) simulator proves the zero-knowledge property against verifiers who choose challenges honestly at random. This toolkit generalizes far beyond discrete logarithms, underpinning graph isomorphism proofs, quadratic residuosity proofs, and modern zk-SNARK constructions built by compiling many sigma protocols together.

How it works

The concrete instance is the Schnorr identification/proof-of-knowledge protocol. Fix a cyclic group GG of prime order qq with generator gg (in practice, a subgroup of Zp∗\mathbb{Z}_p^* or an elliptic curve group, chosen so the Discrete Logarithm Problem is hard). The public statement is y=gxy = g^x; the prover's secret witness is x∈Zqx \in \mathbb{Z}_q. The protocol proceeds in exactly three moves. 1. Commitment. The prover picks a random nonce r←Zqr \leftarrow \mathbb{Z}_q and sends t=grt = g^r. 2. Challenge. The verifier picks a random challenge c←Zqc \leftarrow \mathbb{Z}_q (or a smaller challenge space {0,1}k\{0,1\}^k) and sends it. 3. Response. The prover computes s=r+c⋅x  qs = r + c \cdot x \bmod q and sends ss. The verifier accepts if and only if:

gst⋅ycg^s \stackrel{?}{=} t \cdot y^{c}

Everything hinges on this single checking equation, which links the committed randomness, the challenge, and the response through the group's algebraic structure. ``` PROTOCOL Schnorr-Proof-of-Knowledge Public: group G of prime order q, generator g, statement y = g^x Prover's private input: x (the discrete log of y)

# Move 1 — Prover commits Prover: r ← Uniform(Z_q) # fresh randomness, never reused t ← g^r mod p send t to Verifier

# Move 2 — Verifier challenges Verifier: c ← Uniform(Z_q) # random challenge, unpredictable to Prover send c to Prover

# Move 3 — Prover responds Prover: s ← (r + c * x) mod q send s to Verifier

# Verification Verifier: accept iff g^s == t * y^c (mod p) reject otherwise ``` The protocol can be repeated kk times (sequentially or in parallel) to push the soundness error from 1/q1/q down to a chosen security level, or converted into a non-interactive proof via the Fiat–Shamir Heuristic, replacing the verifier's random challenge with c=H(g,y,t)c = H(g, y, t) for a cryptographic hash function HH, modeled as a random oracle.

Figure
The three-move Schnorr sigma protocol between Prover and Verifier
Prover knows secret x Verifier knows public y = gˣ 1. commitment t = gʳ 2. challenge c ← random 3. response s = r + c·x check: gˢ = t · yᶜ

Complexity & correctness

Time and space complexity. The protocol requires two modular exponentiations by the prover (t=grt = g^r, and negligible cost for ss, which is a single multiply-add mod qq) and two modular exponentiations by the verifier (ycy^c and t⋅yct \cdot y^c, or equivalently one multi-exponentiation gs⋅y−cg^s \cdot y^{-c} compared to tt). Each exponentiation over a group with elements of bit-length nn costs O(n)O(n) modular multiplications via square-and-multiply, each multiplication costing O(n2)O(n^2) with schoolbook arithmetic (or O(nlog⁡nlog⁡log⁡n)O(n \log n \log\log n) with fast multiplication) — giving O(n3)O(n^3) (or quasi-linear-in-n2n^2) bit operations per exponentiation in the naive analysis, which is standard for any discrete-log-based scheme. Communication is three group/field elements: t∈Gt \in G, c∈Zqc \in \mathbb{Z}_q, s∈Zqs \in \mathbb{Z}_q, so O(n)O(n) bits total. Space is O(n)O(n) for all stored values. This is exponentially cheaper than the brute-force alternative of the verifier trying to compute xx from yy directly, which is conjectured to require time exponential in nn for suitably chosen groups.

Completeness. If the prover is honest and truly knows xx with y=gxy = g^x, then:

gs=gr+cx=gr⋅gcx=t⋅(gx)c=t⋅yc.g^s = g^{r + cx} = g^r \cdot g^{cx} = t \cdot (g^x)^c = t \cdot y^c.

The check passes with probability exactly 1 — completeness is perfect, not merely overwhelming.

Soundness (via special soundness). Suppose a cheating prover, without knowing a valid xx, could make the verifier accept with non-negligible probability. We show this leads to a contradiction using special soundness: from two accepting transcripts (t,c1,s1)(t, c_1, s_1) and (t,c2,s2)(t, c_2, s_2) sharing the same commitment tt but with c1≠c2c_1 \neq c_2, an extractor computes:

x=s1−s2c1−c2  q,x = \frac{s_1 - s_2}{c_1 - c_2} \bmod q,

since gs1=tyc1g^{s_1} = t y^{c_1} and gs2=tyc2g^{s_2} = t y^{c_2} imply gs1−s2=yc1−c2g^{s_1 - s_2} = y^{c_1 - c_2}, so y=g(s1−s2)/(c1−c2)y = g^{(s_1-s_2)/(c_1-c_2)}, exhibiting a genuine discrete log of yy. If a cheating prover (without knowing xx) could answer two different random challenges correctly for the same commitment, we could extract xx — contradicting the assumed hardness of the discrete logarithm. Formally, this means: for a fixed commitment tt, at most one challenge cc can have an accepting response, unless the prover already knows xx. Since the verifier's challenge is drawn uniformly from a set of size qq, a prover without the witness succeeds with probability at most 1/q1/q (the soundness error), because it can pre-compute a valid response for at most one lucky guess of cc before committing (and cannot adapt tt afterward without knowing cc in advance). Repeating the protocol kk times independently drives the soundness error down to 1/qk1/q^k, negligible for cryptographic qq.

Zero-knowledge (via simulation). To prove the verifier learns nothing beyond "xx exists," we exhibit a simulator SS that, given only yy (no witness), produces transcripts distributed identically to real ones — without ever running the real protocol. The simulator works backwards: ``` SIMULATOR S(y): c ← Uniform(Z_q) # pick challenge first s ← Uniform(Z_q) # pick response first t ← g^s y^(-c) mod p # solve the equation for t output (t, c, s) ``` Check: by construction gs=t⋅ycg^s = t \cdot y^c holds identically, so SS's output always passes verification — exactly like a real transcript. Moreover, in a real execution with honest random rr and honest-verifier random cc, the triple (t,c,s)(t, c, s) is distributed as: tt uniform over GG (since rr is uniform), cc uniform (verifier's choice), and s=r+cxs = r + cx uniform over Zq\mathbb{Z}_q conditioned on t,ct, c (since rr is uniform and independent of cc). In the simulated transcript, cc and ss are uniform and independent by construction, and tt is determined* by c,s,yc, s, y — but since ss is uniform, t=gsy−ct = g^s y^{-c} is also uniform over GG. Both distributions are therefore identical: uniform (t,c,s)(t,c,s) subject to the single algebraic constraint gs=tycg^s = t y^c. This gives perfect honest-verifier zero-knowledge: the simulated and real transcript distributions are exactly equal, not just computationally close. Since the simulator never touches xx, and its output is indistinguishable from a genuine interaction, the verifier's transcript conveys no extractable information about xx beyond the bare fact that some valid xx exists.

Tradeoffs. Perfect HVZK is a strong guarantee, but it only holds against a verifier who chooses cc honestly at random and independent of tt; a malicious verifier who adaptively chooses cc based on side information can, in principle, weaken guarantees for general sigma protocols (though Schnorr specifically remains secure due to strong structural properties, and the Fiat–Shamir transform sidesteps this concern entirely by deriving cc deterministically via a hash). Soundness error 1/q1/q is already negligible for a 256-bit qq, so repetition is rarely needed in practice — a single round suffices in most deployed systems.

Worked example

Use a small illustrative group (too small for real security, ideal for hand-tracing). Let p=23p = 23, so Z23∗\mathbb{Z}_{23}^* has order 22; take a subgroup of prime order q=11q = 11 generated by g=4g = 4 (since 44 has order 11 mod 23: check 411  23=14^{11} \bmod 23 = 1). The prover's secret is x=6x = 6.

StepComputationValue
Public keyy=gx  p=46  23y = g^x \bmod p = 4^6 \bmod 23y=18y = 18
Prover picks noncer=3r = 3 (secret, one-time)r=3r=3
Commitmentt=gr  p=43  23=64  23t = g^r \bmod p = 4^3 \bmod 23 = 64 \bmod 23t=18t = 18
Verifier picks challengec=5c = 5 (random in Z11\mathbb{Z}_{11})c=5c = 5
Prover computes responses=(r+c⋅x)  q=(3+5⋅6)  11=33  11s = (r + c\cdot x) \bmod q = (3 + 5\cdot 6) \bmod 11 = 33 \bmod 11s=0s = 0
Verifier checks LHSgs  p=40  23g^s \bmod p = 4^0 \bmod 23LHS=1LHS = 1
Verifier checks RHSt⋅yc  p=18⋅185  23t \cdot y^c \bmod p = 18 \cdot 18^5 \bmod 23compute below

Compute 185  2318^5 \bmod 23 step by step: 182=324=324−14⋅23=324−322=218^2 = 324 = 324 - 14\cdot23 = 324-322=2; 184=22=418^4 = 2^2 = 4; 185=184⋅18=4⋅18=72=72−3⋅23=72−69=318^5 = 18^4 \cdot 18 = 4\cdot 18 = 72 = 72-3\cdot23=72-69=3. Then RHS =18⋅3  23=54  23=54−46=8= 18 \cdot 3 \bmod 23 = 54 \bmod 23 = 54 - 46 = 8. Something looks off: LHS=1≠8=RHSLHS = 1 \neq 8 = RHS. Re-examine: recompute tt. 43=644^3 = 64, 64  23=64−46=1864 \bmod 23 = 64 - 46 = 18. Correct, t=18t=18. Recompute yy: 46=(43)2=182=324  234^6 = (4^3)^2 = 18^2 = 324 \bmod 23. 23⋅14=32223\cdot14=322, so y=2y = 2, not 18 — the earlier line miscalculated yy. Correct value: y=2y = 2. Redo with y=2y=2: RHS =t⋅yc  p=18⋅25  23=18⋅32  23= t \cdot y^c \bmod p = 18 \cdot 2^5 \bmod 23 = 18 \cdot 32 \bmod 23. 32  23=932 \bmod 23 = 9, so RHS =18⋅9=162  23=18\cdot 9 = 162 \bmod 23. 23⋅7=16123\cdot7=161, so RHS =1=1. Now LHS =1==1= RHS. The equation holds — completeness confirmed once arithmetic is corrected.

QuantityCorrect value
p,q,gp, q, g23,11,423, 11, 4
secret xx66
public y=gx  py = g^x \bmod p22
nonce rr33
commitment t=gr  pt = g^r \bmod p1818
challenge cc55
response s=(r+cx)  qs = (r+cx) \bmod q00
verification gs  pg^s \bmod p11
verification t⋅yc  pt \cdot y^c \bmod p11 ✓ match

Now trace a cheating attempt: an impersonator without xx picks a random t′=7t' = 7, sends it, and hopes the verifier's challenge will be some specific c0c_0 it precomputed a fake response for — say it hopes for c=5c=5 and prepares s′s' such that gs′=t′⋅y5=7⋅1′g^{s'} = t' \cdot y^5 = 7\cdot 1' . Concretely it can solve s′s' only if it already knows xx or gets extraordinarily lucky guessing cc before the verifier reveals it; since cc is chosen uniformly from 11 possible values after t′t' is fixed, the cheater's probability of matching the verifier's actual challenge is exactly 1/111/11, matching the soundness bound 1/q1/q.

Common pitfalls & traps

PitfallWhy it breaks the protocol
Reusing the nonce rr across two proofsTwo transcripts with different c1,c2c_1, c_2 but same tt let anyone extract xx via the special-soundness formula — this is exactly how private keys have been leaked in real signature schemes.
Choosing cc before tt is sent (or letting prover pick cc)Destroys soundness: the cheating prover can now tailor tt to a known cc, succeeding with probability 1.
Small or non-prime-order challenge spaceEnlarges soundness error above 1/q1/q or introduces subgroup attacks; the extraction argument needs c1−c2c_1 - c_2 invertible mod qq.
Treating Fiat–Shamir hash as a black box without domain separationIf HH doesn't bind tt, yy, and context together, transcripts from one protocol can be replayed or confused across another.
Confusing zero-knowledge with "no information leaks at all"Zero-knowledge only guarantees the transcript is simulatable; side channels (timing, power) can still leak xx even in a "zero-knowledge" protocol.
Assuming perfect ZK survives against a malicious (non-honest) verifier automaticallyHVZK simulators assume cc is chosen independently of tt; a verifier who adaptively biases cc needs a separate (often computational) ZK argument or the Fiat–Shamir transform.

Pioneers & history

The notion of interactive proof systems and zero-knowledge was born from asking a deceptively simple question: can a proof convince you of a fact while teaching you nothing else about why it's true? This reframed "proof" from a static mathematical object into an interactive, probabilistic protocol between two parties — a shift as consequential to cryptography as Turing's reframing of "computation" was to logic.

Origins · 1 minShafi Goldwasser and how this was discovered
SG
Shafi Goldwasser
1959–present · Co-inventor of zero-knowledge proofs and interactive proof systems, Turing Award 2012

Shafi Goldwasser, along with Silvio Micali and Charles Rackoff, formalized zero-knowledge proofs in their 1985 paper, introducing the definitions of completeness, soundness, and zero-knowledge used throughout this article. Goldwasser and Micali's broader work on probabilistic encryption and interactive proofs reshaped the foundations of cryptographic security definitions, earning them the ACM Turing Award.

History
1985
Goldwasser, Micali, and Rackoff formalize zero-knowledge interactive proofs.
1986
Fiat and Shamir introduce an efficient identification scheme and the transform bearing their names.
1989
Goldreich, Micali, and Wigderson show every NP statement has a zero-knowledge proof, assuming one-way functions.
1991
Schnorr publishes the efficient sigma protocol and signature scheme central to this article.
2012
Goldwasser and Micali receive the Turing Award for foundational contributions to cryptography.

Where this matters

Zero-knowledge proofs of discrete-log knowledge, exactly as presented here, underlie the Schnorr signature scheme (via Fiat–Shamir), now standardized in Bitcoin's Taproot upgrade and widely used for efficient, batchable digital signatures. Anonymous credential systems and privacy-preserving authentication protocols use sigma protocols to let users prove membership or eligibility without revealing identifying secrets. Modern zk-SNARKs and zk-STARKs, powering blockchain scaling solutions (zk-rollups) and private cryptocurrencies like Zcash, generalize this same three-part logic — completeness, soundness, zero-knowledge — to prove arbitrary computations rather than just discrete logarithms. Secure multiparty computation protocols and password-authenticated key exchange schemes also embed zero-knowledge subprotocols to prevent parties from cheating without forcing them to reveal private inputs. Understanding this one Schnorr example is the fastest route to understanding the entire modern zero-knowledge toolbox, since nearly every advanced construction is, at its core, a composition of many small sigma protocols like this one.

Ask the tutor: How does the Fiat–Shamir transform formally preserve soundness when the random oracle is replaced by a real hash function in practice?

What exactly does "zero-knowledge" mean, formally?

It means the verifier's view of the interaction can be reproduced by a simulator that does not know the witness. If a simulator, given only the public statement, can output transcripts with the same probability distribution as real ones, then whatever the transcript reveals could have been computed without any prover — hence "zero additional knowledge" is gained. This is stronger than just saying "the secret isn't sent directly"; it rules out any statistical leakage detectable in the messages, commitments, or randomness patterns across the whole protocol run.

Why does the Schnorr protocol need three moves instead of two?

Two moves cannot achieve both soundness and zero-knowledge simultaneously in this setting. If the prover sends only a commitment and then a response with no interactive challenge, a cheating prover could precompute everything in advance without any random check from the verifier, destroying soundness. The middle challenge move injects unpredictable randomness chosen after the prover commits, which is exactly what the special-soundness extraction argument exploits: an adversary cannot know the challenge before fixing its commitment.

Is the Schnorr protocol secure against a dishonest (not just curious) verifier?

The proof of zero-knowledge given here is honest-verifier zero-knowledge (HVZK), assuming the verifier samples c uniformly and independently of t. Against a fully malicious verifier who might choose c adaptively based on auxiliary information, additional techniques (such as commitment schemes for the challenge, or the Fiat–Shamir transform in the random oracle model) are used to preserve zero-knowledge guarantees, and these extensions are standard in deployed systems.

How is this different from a digital signature scheme?

A digital signature authenticates a specific message using a secret key, is verifiable by anyone at any later time without interaction, and doesn't inherently need a "prover present" during verification. The Schnorr identification protocol above is interactive and proves knowledge of x right now. Applying the Fiat–Shamir transform converts the interactive proof into the non-interactive Schnorr signature scheme, binding the challenge to both the commitment and the message being signed.

Why is special soundness important, rather than just "soundness"?

Special soundness gives an explicit, constructive extraction algorithm: given two accepting transcripts sharing a commitment but differing challenges, it directly computes the witness. This constructive property is what lets us formally reduce a soundness violation to solving the discrete logarithm problem, rather than merely asserting cheating is "hard" without justification. It is the standard technique for proving soundness across the whole sigma-protocol family, not just Schnorr's case.

Can this protocol be attacked by a quantum computer?

Yes, indirectly. The protocol's security depends entirely on the hardness of the discrete logarithm problem in the chosen group. Shor's algorithm solves discrete logarithms in polynomial time on a sufficiently large quantum computer, which would let an attacker compute x directly from y and break both soundness and the underlying hardness assumption. Post-quantum zero-knowledge proofs replace the discrete-log relation with lattice-based or hash-based relations believed to resist quantum attacks.

What happens if the challenge space is too small, say just {0,1}?

The protocol still works but the soundness error becomes 1/2 per round instead of 1/q, since a cheating prover can guess the single-bit challenge correctly half the time and prepare a fake response in advance. This is exactly the situation in some classic zero-knowledge proofs (like graph isomorphism), which compensate by repeating the protocol many times independently to push the error down exponentially, at the cost of more communication rounds.

Before this