Statements and Challenges
The previous chapter set proof-carrying data as the goal, where each step of a computation hands over its output together with a proof. Before building any proof, we need to say precisely what a proof is about and what it means for one to work. This chapter supplies that vocabulary.
It also introduces the three tools that every later chapter uses. The Schwartz–Zippel lemma explains why checking a polynomial at one random point tells us about the whole polynomial. Random linear combinations replace many claims with one. The Fiat–Shamir transform then removes the verifier's live participation by deriving its random choices from a hash.
1. Statements, instances, and witnesses
Suppose a prover wants to convince a verifier of the following claim, which the next chapter uses as its running example:
I know a number in such that .
This claim has a public part and a secret part. The number 35 is known to both parties, and we call this public part the instance. The number is known only to the prover, and we call this secret part the witness. The rule connecting them is a relation, which is a test that takes an instance and a witness and answers yes or no. Here the relation contains a pair exactly when . A statement is then a claim that a given instance has a witness in the relation.
The relation has to be cheap to evaluate, since it is the test the verifier would run if it were handed the witness. Finding a witness from the instance can be much harder. In the example above, the field is small enough to search:
Evaluating at all 43 elements of finds that the value 35 occurs at . Our is the only witness for this instance. The value gives , so the pair falls outside the relation. Some instances have no witness at all, and the instance 2 is one of them.
Later chapters use a second relation, the one behind every elliptic curve commitment. The instance is a point on a curve, the witness is a scalar , and the relation holds when for a public generator . We work on the toy curve over , which has 43 points. Coordinates are computed modulo 31, and scalars are computed modulo 43 because adding a point to itself 43 times returns the identity. The chapter on polynomial commitments returns to this distinction, and the curves appendix lists the parameters.
Take the generator and the secret scalar , which give the instance . The relation holds for the pair because recomputing yields . The pair falls outside it, since .
The two relations differ in one respect that affects what a proof must establish. The group has prime order, so every point is a multiple of . A witness for therefore always exists, and the claim "some satisfies this" tells the verifier nothing. The useful claim is that the prover knows , and Section 2 gives this difference a name.
The prover could convince the verifier by sending the witness, and the verifier could run the relation. We want to avoid that for two reasons. The witness may be secret, as the spending keys in a Zcash transaction are. It may also be enormous, because in proof-carrying data the witness for one step includes everything needed to check the previous steps. A proof has to be shorter than the witness and has to keep it hidden.
2. Completeness and soundness
We judge a proof system by how it treats honest and dishonest provers, and a useful system has to satisfy two requirements at once. Completeness says that a prover with a valid witness who follows the protocol always convinces the verifier. Soundness says that a prover making a false statement rarely convinces the verifier, however it deviates from the protocol.
Each requirement alone is easy to meet. A verifier that accepts everything is complete but not sound, and a verifier that rejects everything is sound but not complete. Sending the witness satisfies both but fails the goals from Section 1, so the real work is meeting both requirements with a short message that hides the witness.
We allow soundness to fail with a small probability, called the soundness error. Accepting a small error is what makes short proofs possible, as this chapter shows repeatedly. The error has to be small enough that no one could expect to see it happen, and Section 5 shows how a large field achieves that.
Three refinements of soundness appear in later chapters, and we state them here informally:
- Knowledge soundness says that a prover who convinces the verifier must actually know a witness. This is the property we need for the curve relation in Section 1, where a witness always exists.
- Computational soundness says that soundness holds only against provers with realistic computing power. A proof system with this weaker guarantee is called an argument. Ragu's proofs are arguments, because they rest on the hardness assumptions listed in Section 11.
- Zero knowledge says that the verifier learns nothing from the proof beyond the truth of the statement.
This site explains why cheating fails and which assumptions that depends on, but it does not give formal definitions or security proofs.
3. An interactive proof
The clearest way to see these properties is to run a protocol. We use Schnorr's protocol for the curve relation, because it is short enough to follow every step. Ragu's proof is a different and much larger protocol, but it has the same shape, in which the prover commits to something, the verifier answers with randomness, and the prover responds.
Building the protocol
The prover wants to show that it knows with . Sending would reveal it, so the prover has to send something derived from that can be checked against . One candidate is a multiple for a number chosen by the verifier, because the verifier can check it against . This fails immediately, since the verifier can divide by and recover .
Adding a random mask repairs this, giving the response . The value hides in the same way a one-time pad hides a message. The verifier now cannot check without some information about , so the prover announces ahead of time. Multiplying the response by shows why this is enough:
The last line contains only values the verifier holds, so the verifier can check it. These lines also establish completeness, because an honest prover passes for every and every .
The protocol has three messages, and their order is part of the protocol:
Here is one run:
| Step | Party | Value |
|---|---|---|
| 1 | Prover picks a mask and sends | , |
| 2 | Verifier sends a random challenge | |
| 3 | Prover sends the response | modulo 43 |
| 4 | Verifier computes the left side | |
| 5 | Verifier computes the right side |
Why the order matters
The verifier has to send after receiving . To see why, rearrange the check to isolate , which gives . If a cheater knows ahead of time, it can pick any and compute the that makes the equation hold.
Suppose a cheater holds only the public point and learns in advance that . It picks the response first, and then computes . The check passes because and . The cheater never used .
Sending first removes this option, since is fixed before exists. Section 9 shows what happens when the same ordering breaks in a non-interactive proof.
Why a cheater fails
Consider a cheater who sends some point and has prepared one response . The check involves one unknown, the challenge, and it holds for exactly one value of because generates the group.
We can test this on all pairs , trying every one of the 43 challenges against each pair. Every pair passes for exactly one challenge. A cheater who fixes and prepares one response therefore succeeds with probability .
A cheater might instead hope to prepare a different response for each challenge. Suppose it could answer two different challenges and for the same , with responses and . Writing both checks and subtracting removes :
Since , dividing by gives , so the cheater can compute the discrete log of .
Keep . The prover answers with and answers with . The difference gives and modulo 43, and dividing gives , which is the secret .
This gives us knowledge soundness in an informal sense. A prover who answers more than one challenge for a given can compute , and anyone who cannot compute is limited to one challenge out of 43, which on a Pasta curve is one out of about . The argument assumes that discrete log is hard. On the toy curve anyone can solve discrete log by counting, so these numbers show the mechanism and offer no security.
What the verifier learns
The response gives away nothing about , because the mask is uniform and is used once.
Fix and let the mask range over . The response takes each of the 43 values exactly once, with giving and giving , for example. We also listed the 43 pairs an honest prover can produce for this challenge, and the 43 pairs a simulator produces by picking first and computing . The two lists contain the same pairs.
The second comparison is informative. The same trick that lets a cheater forge when it knows early also lets anyone produce transcripts with the correct distribution without knowing . A transcript that anyone could have produced cannot teach the verifier anything about , which is the informal reason the protocol is zero knowledge for a verifier who picks honestly. Reusing a mask would destroy this, since two responses with the same reveal through the subtraction above.
4. Counting the roots of a polynomial
Schnorr's protocol relied on a linear equation in , which has one solution. Most protocols on this site check polynomial equations of high degree, so we need to count the solutions of those equations. The count rests on one algebraic fact about roots.
Each root gives a linear factor
Let have degree , and suppose . Subtracting changes nothing, so we can write
The term cancels because . Each remaining difference contains the factor , as multiplying out the following product confirms:
For this reads . Pulling out the common factor gives , where has degree .
Take over and , where . Subtracting gives , which has a root at . Dividing by leaves no remainder, so . Expanding this product returns the coefficients of .
A polynomial of degree d has at most d roots
Now suppose is another root of . Substituting into the factorization gives
In a field, a product of two nonzero values is never zero. Since , this forces , so every other root of is a root of . We can repeat the argument on , which has degree one lower. A nonzero constant has no roots, so the process removes at most roots before it stops. This proves that a nonzero polynomial of degree over a field has at most roots.
| Step | Polynomial | Degree | Root removed |
|---|---|---|---|
| Start | 3 | ||
| 1 | 2 | 1 | |
| 2 | 1 | 2 | |
| 3 | 0 | 3 |
The constant 2 has no roots, so the process stops after three steps. Evaluating the starting polynomial at all 43 points confirms that its roots are exactly 1, 2 and 3.
The field assumption is essential, because without it the cancellation step fails:
Work modulo 8, which is not a prime. The degree-2 polynomial has the four roots . At it factors as modulo 8, where neither factor is zero, so the cancellation step above is invalid.
The toy field is small enough to check the bound on every polynomial of a given degree. Multiplying a polynomial by a nonzero constant does not move its roots, so it is enough to count the monic cubics, whose leading coefficient is 1:
| Distinct roots | Monic cubics over | Share |
|---|---|---|
| 0 | 26488 | 0.333 |
| 1 | 38872 | 0.489 |
| 2 | 1806 | 0.023 |
| 3 | 12341 | 0.155 |
The counts add up to , and no polynomial reaches 4 roots.
The bound of 3 is what a cheater can reach at best, and many polynomials stay below it. A protocol's guarantee has to hold against the worst polynomial a cheater could choose, so we use the bound rather than the typical count.
5. Testing polynomials at a random point
The root count gives us a cheap test for equality. Let and be different polynomials of degree at most , and let be uniform in . If , then is a root of the nonzero polynomial , whose degree is at most . It has at most roots, so
This is the one-variable case of the Schwartz–Zippel lemma. Comparing two polynomials coefficient by coefficient takes time proportional to their size, whereas this test compares one field element from each side.
The test is more useful for identities that are expensive to check directly. Suppose a prover claims that . Multiplying the two polynomials out takes a number of field multiplications that grows with the square of the degree in the schoolbook method, but checking the claim at one point requires only three evaluations and one multiplication.
Let and . Their product is . At the point , and , whose product is modulo 43, and as well.
Now suppose a cheater sends plus some error polynomial. The test passes exactly at the roots of the error. The product has degree 6, which gives a bound of , and the next table counts the passing points for several errors.
| Error added to | Points where the test passes | Pass rate | Bound |
|---|---|---|---|
| 0 | 0.000 | 0.140 | |
| 1 | 0.023 | 0.140 | |
| 0 | 0.000 | 0.140 | |
| 3 | 0.070 | 0.140 | |
| 6 | 0.140 | 0.140 |
The last row reaches the bound, and the others stay under it. An error such as has no roots in this field, so the test catches it at every point.
Two conditions make the bound meaningful. The first is that the polynomials must be fixed before is chosen, for the same reason as the ordering in Section 3. The bound counts the roots of a fixed polynomial, and a prover who sees first can build a polynomial with a root at :
If the prover knows the point in advance, it can send . This polynomial differs from , yet , so the test at passes.
The chapter on polynomial commitments builds the tool that fixes a polynomial without revealing it.
The second condition is that the degree must be well below the field size. The bound says nothing once reaches :
The polynomial has degree 43 and is not the zero polynomial, yet it evaluates to 0 at all 43 points of . Its bound is , which promises nothing.
Real fields leave plenty of room:
With degree over a field with more than elements, such as either Pasta field, the probability is below .
6. Polynomials in several variables
The checks in later chapters often involve more than one challenge, which turns the polynomial being tested into a function of several variables. The consolidated equation in the next chapter, for example, uses two challenges. We therefore need the same kind of bound for several variables.
The relevant size measure is the total degree, the largest sum of exponents among the monomials. The monomial has total degree 3, so has total degree 3.
Schwartz–Zippel lemma
Let be a nonzero polynomial in variables with total degree over a field . If are chosen uniformly and independently from , then
The bound does not grow with the number of variables, so it is worth going through the two-variable argument. Longer lists of variables follow by repeating it.
Group the terms of by powers of :
where is the highest power of whose coefficient is a nonzero polynomial. Each monomial of has total degree at most , and already accounts for of it, so has degree at most .
Now picture choosing first and second. Two cases can occur:
- The chosen is a root of . By Section 4 there are at most such values, so this happens with probability at most . We give up on these rows and assume the worst, which is that vanishes for every .
- The chosen is not a root of . Then is a one-variable polynomial with nonzero leading coefficient and degree . It has at most roots, so a uniform hits one with probability at most .
Adding the two probabilities gives
The figure shows both cases for one polynomial:

For we have and , so the only bad row is , and it contains all 43 points as zeros. The other 42 rows hold at most 2 zeros each, because each is a nonzero degree-2 polynomial in . They contribute 43 zeros in total, and the sum stays below the limit of .
For variables, we treat one variable as and the rest as a group, and the same two cases apply with the lemma for variables in place of the root count.
Over there are points to test, so the probability bound becomes a limit of on the number of zeros. The next table counts the zeros of several polynomials.
| Polynomial | Total degree | Zeros among | Limit |
|---|---|---|---|
| 2 | 42 | 86 | |
| 2 | 85 | 86 | |
| 2 | 86 | 86 | |
| 3 | 46 | 129 | |
| 3 | 86 | 129 |
The third row reaches the limit exactly. It ignores and vanishes on two whole columns of the grid, so the bound cannot be improved in general.
To test every case rather than selected ones, we move to the smaller field , whose bivariate polynomials of total degree at most 2 have six coefficients. There are 15624 nonzero choices. None has more than 10 zeros among the 25 points of the grid, which matches the limit , and 240 of them reach it.
7. Random linear combinations
A proof system has to check a large number of equations, since a circuit has thousands of gates and each one contributes a claim of the form , where is the difference between the two sides. A proof that handled every equation separately would be very long, so we want one equation that fails whenever any of the original equations fails.
Adding the errors does not work, because they can cancel. Fixed weights do not work either, because the cheater can plan around them:
The errors are both nonzero, but they add to 0 modulo 43. Fixed weights known in advance do no better. With the weights , a cheater picks the errors , and modulo 43.
The remedy for both is to choose the weights at random after the errors are fixed, so that the cheater has nothing to plan around. There are two standard ways to do this.
Independent weights
The verifier picks a separate uniform for each claim and checks . Suppose some . Fix all the other weights to any values, and let be the sum of their terms. The check becomes
which has exactly one solution . A uniform hits that solution with probability exactly , however many claims there are.
Take the errors . Trying all choices of finds 1849 that give a zero combination, which is a share of exactly .
Powers of one challenge
Independent weights require one random value per claim. A single value can stand in for all of them if we use its powers as the weights:
The left side is a polynomial in whose coefficients are the errors. If any error is nonzero, this polynomial is nonzero with degree at most , so Section 5 gives an error of at most . The verifier sends one field element rather than , and the cost is a larger soundness error that a large field absorbs. The next chapter applies this form to circuit gates and constraints.
All nonzero error vectors of length 3 are few enough to enumerate:
| Values of that hide the errors | Nonzero error vectors of length 3 |
|---|---|
| 0 | 37968 |
| 1 | 3612 |
| 2 | 37926 |
The counts cover all nonzero vectors, and no vector is hidden by more than 2 of the 43 values, which agrees with the bound . The errors from the previous example are hidden by 2 values in this form, namely .
Combining evaluation claims
The same technique combines claims about polynomials. Suppose a prover claims and . Evaluation is linear in the coefficients, so for any ,
The verifier can therefore pick and test one claim, . Writing and , the right side minus the left side is , which is the two-claim case of the check above.
The true values at are and . A cheater claims and , with errors 1 and 2. At , the combined polynomial evaluates to , while the combined claim is , so the check fails. Trying all 43 values of finds that only hides the errors, because that is the single solution of modulo 43.
As with every challenge, the errors must be fixed before is known. A cheater who sees first can pick errors that cancel:
If the cheater learns first, it keeps the error and solves for modulo 43. It then claims and . Both claims are false, yet equals the value of at .
In linear algebra terms, one row replaces a system of equations. A system with rows becomes the single equation , in which a random vector combines the rows. The technique applies wherever claims combine linearly, which includes the curve points in Pedersen commitments. The chapters on batched openings, accumulation, and folding all build on it.
8. Removing the verifier with Fiat–Shamir
Interaction is a problem for proof-carrying data. A proof has to travel with its data and convince anyone who later receives it, including parties that did not exist when the prover ran. A live verifier cannot do that, and a recording of an interactive run does not help either, because Section 3 showed that anyone can write a valid transcript once the challenge is known in advance.
The observation behind the Fiat–Shamir transform is that the verifier in these protocols contributes nothing but random values. Protocols with this property are called public coin, since the verifier's coins are visible and it keeps no secrets. The challenge needs only two properties, which are that it looks random and that nobody can predict it before the prover's message is fixed. A hash of the prover's message has both properties, provided the hash behaves like a random function.
The transform therefore replaces each verifier message with a hash of everything sent so far. We keep this running record in an object called a transcript, with two operations. Absorbing adds a value to the record, and squeezing produces a challenge that depends on everything absorbed so far. Prover and verifier run the same sequence of operations, so they obtain the same challenges. For Schnorr's protocol, the sequence is:
- Start the transcript with a tag that names the protocol.
- Absorb the instance .
- Absorb the commitment .
- Squeeze the challenge .
Section 11 describes the toy hash we use here, which works over . It absorbs a curve point as its two coordinates. Each coordinate is an integer below 31, so it is also a distinct element of , and the output is a scalar for the toy curve. On real curves, moving values between the two fields of a curve cycle takes more care, and the chapters on curve cycles and endoscalars cover that step.
| Step | Party | Value |
|---|---|---|
| 1 | Prover starts the transcript with the tag and instance | tag , |
| 2 | Prover computes the commitment and absorbs it | |
| 3 | Prover squeezes the challenge | |
| 4 | Prover computes the response | modulo 43 |
| 5 | Prover publishes the proof | |
| 6 | Verifier replays steps 1 to 3 | |
| 7 | Verifier checks the equation | and |
The proof is now a single message that anyone can check at any time. The verifier no longer picks anything, and it instead recomputes the challenge and confirms the equation.
The challenge depends on the commitment, which restores the ordering from Section 3. A prover cannot choose after the challenge, because a different produces a different challenge. Later challenges depend on all earlier messages, because the transcript keeps its state between squeezes:
Changing the commitment to changes the challenge from to , and the old response no longer satisfies the check. The effect also carries forward. If the protocol had a later round, which absorbed and squeezed a second challenge, that challenge would be after and after , with the same in both runs.
9. Omitting data from the transcript
The transform is safe only when the transcript includes everything the verifier would have seen before choosing the challenge. Leaving out a value lets a prover choose that value after seeing the challenge, which is the attack from Section 3 in a new form. These mistakes have happened in deployed code. Trail of Bits named the class Frozen Heart in its disclosure of such flaws in implementations of Girault's proof of knowledge, Bulletproofs, and PLONK.
Omitting the commitment
Suppose the transcript absorbs the tag and but not . The challenge is then fixed before the commitment exists, so the early-challenge forgery from Section 3 works directly, with no search.
| Step | Value |
|---|---|
| Compute the challenge from the tag and alone | |
| Pick any response | |
| Solve for the commitment | |
| Verifier's left side | |
| Verifier's right side |
The flawed verifier accepts. A verifier that also absorbs derives the challenge instead of and rejects the same proof.
This breaks the protocol completely, since a cheater can forge a proof for any instance. The same mistake in a polynomial protocol has the same effect. If the evaluation point does not depend on a polynomial's commitment, the prover can change the polynomial to fit the point.
Omitting the instance
Suppose instead that the transcript absorbs but not . Bernhard, Pereira, and Warinschi call this variant weak Fiat–Shamir and examine its pitfalls. The cheater can no longer choose after the challenge, but it can now choose the statement afterward. Rearranging the check to isolate gives .
Start from the public point , whose relation to the cheater need not know. The flawed transcript gives without looking at any instance. Picking and solving gives . The check holds, since and .
The cheater now has a valid proof for , and the construction used only public points, so it never needed the discrete log of . The cheater cannot aim at a specific this way. A weak transcript also lets an observer adapt someone else's proof to a related statement, and in that case the observer does choose the target. The challenge does not change when the instance changes, so the observer can add a multiple of to the instance and add the corresponding amount to the response:
An honest prover publishes for under the flawed transcript, whose challenge is . An observer takes and computes and modulo 43. The pair passes for , because and .
The witness for is , and the observer does not know it because it does not know . A verifier would nevertheless accept this proof as evidence that someone does.
Omitting the protocol tag
Tags address a less direct problem. If two protocols use the same message format, a proof made for one would also pass in the other, even when the two assign different meanings to the same equation. Starting the transcript with a tag gives each protocol its own stream of challenges, a practice called domain separation.
With the tag , the instance and commitment above give the challenge . With the tag , the same two points give , and the response fails the check.
Our rule follows from these three cases. The transcript has to include the protocol tag, all public parameters that the tag does not already fix, the full instance, every prover message, and all earlier challenges, which the transcript state includes automatically.
10. Repeated trials
The transform also changes the soundness error in a way that is easy to miss. In an interactive run, a cheater gets one attempt, because the verifier sees each failure. In a non-interactive proof, a cheater can try as many transcripts as it likes on its own machine and publish only one that works. This is called grinding.
The toy field makes grinding visible, because each attempt has a chance of about :
A cheater repeats the early-challenge trick. It guesses a challenge, picks a response, computes , and tests whether the hash of the transcript returns its guess. Running through the pairs from the largest values downward with , attempt 19 succeeds with the guess , the response and . The honest verifier accepts this proof, and the search never touched . Across all 1806 pairs that give a nonidentity , exactly 42 succeed, which is one attempt in 43.
A cheater with attempts therefore has a success probability of up to about times the soundness error of a single attempt. The defense is a field large enough for the product to remain tiny:
Suppose a cheater can compute hashes, and each attempt faces the error with and a field above . Each attempt succeeds with probability below , and all attempts together succeed with probability below .
These numbers only illustrate how grinding scales, and we make no claim here about the overall security level of Ragu. The Ragu Book raises the same point in one of its discussions, noting that a complete accounting has to include an adversary's repeated Fiat–Shamir trials.
11. Poseidon and the random oracle assumption
Fiat–Shamir needs a hash function, and the choice matters more in recursive proofs than elsewhere. In a recursive proof, the verifier's work runs inside a circuit, so each challenge must be recomputed inside a circuit too. The next chapter explains that a circuit's main cost is its number of field multiplications. A hash such as SHA-256 works with bits and 32-bit words, and expressing those operations as field equations takes tens of thousands of constraints for each compression. Ragu instead uses Poseidon, a hash designed to work directly with field elements and to need few multiplications.
The sponge
Poseidon is built from a permutation of a small array of field elements, called the state. A construction called a sponge turns this permutation into a transcript. The state starts at zero and is split into rate cells, which interact with the outside, and capacity cells, which do not.
Absorbing adds input into the rate cells. Once they are full, or when the prover wants a challenge, the sponge applies . Squeezing reads values out of the rate cells and applies again when they run out. The capacity cells prevent a prover from controlling the whole state, because input can reach them only through the permutation.

The permutation
Each round of performs three operations on the state:
- It adds a fixed round constant to every cell, which makes the rounds differ and blocks attacks that exploit repeated structure.
- It applies the S-box, the map , to some of the cells. This is the only nonlinear step, and it provides the mixing that linear algebra cannot undo.
- It multiplies the state by a fixed invertible matrix, which spreads each cell's influence to all the others.
The exponent has to make the S-box invertible, because otherwise the round would lose information. The map is a bijection on exactly when shares no factor with , so the usable exponents depend on the field.
Over , the map takes only 22 distinct values and takes 15, whereas takes all 43, because 5 shares no factor with . The same reasoning rules out smaller exponents on the Pasta fields, where and are divisible by 2 and 3 but not by 5.
Computing takes three multiplications, as , then , then . The S-box is therefore the part of Poseidon that costs gates, which suggests applying it sparingly. Poseidon does so by running two kinds of rounds. Full rounds apply the S-box to every cell, and partial rounds apply it to the first cell only. A permutation places half of its full rounds at the start, all of its partial rounds in the middle, and the remaining full rounds at the end.
A toy Poseidon
Our examples use a small instance over with three cells, of which two are rate cells, along with 8 full rounds and 8 partial rounds. We derive its round constants from SHA-256 and use a Cauchy matrix for the mixing step. This instance has the structure of Poseidon and none of its security, because its parameters were chosen to fit on a page and its outputs have only 43 possible values. The next table shows the first round of the first permutation from Section 8, along with the fifth round of that permutation, which is the first partial round:
| Step | Full round | Partial round |
|---|---|---|
| Input state | ||
| After adding constants | ||
| After the S-box | ||
| After the mixing matrix |
The S-box changes every cell in the full round but only the first cell in the partial round. Running the sponge over the whole transcript from Section 8 gives the next table.
The transcript of Section 8 absorbs seven elements in order: the tag length 2, the tag , the coordinates of , and the coordinates of .
| Permutation | Elements added to the state | State afterward |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 | ||
| 4 |
The last permutation runs when the prover squeezes. The first entry of the resulting state is the challenge from Section 8.
The assumption
The argument of Section 8 treats the hash as a random oracle, an imaginary function that returns an independent uniform value for each new input. In that model, a prover has no way to predict a challenge other than computing the hash on the full transcript, and the challenges behave as a verifier's random choices would. The Ragu Book models Poseidon this way.
This assumption is stronger than collision resistance. A Pedersen commitment, for example, is collision resistant under the discrete log assumption, yet it would make a poor source of challenges. Its output moves predictably when its input changes, as the homomorphism shows, and a prover could exploit that structure to steer a challenge. A random oracle has no structure of this kind.
No real hash function is a random oracle, because a real hash has a short public description that anyone can analyze. The assumption is therefore a modeling choice with known limits. Goldwasser and Tauman built a secure identification scheme whose Fiat–Shamir signature version is secure with a random oracle but insecure under every concrete hash. More recently, Khovratovich, Rothblum, and Soukhanov gave a practical attack on a GKR-based argument made non-interactive with a concrete hash, producing accepting proofs of false statements. Neither result targets Ragu, and both show that the assumption needs scrutiny for each protocol. Confidence in Poseidon specifically comes from public cryptanalysis rather than from a proof.
Assumptions behind the protocols
The Ragu Book lists three assumptions, and later chapters refer back to them:
- Discrete log relation. Nobody can find a nontrivial linear relation among independently chosen curve generators. The chapter on polynomial commitments uses this for binding.
- Random oracle. Poseidon behaves like a random oracle when deriving Fiat–Shamir challenges, as described above.
- Knowledge soundness. An efficient prover who produces a valid commitment and evaluation proof knows the underlying polynomial. This is the same kind of property we saw in Section 3, applied to the polynomial commitment scheme.
12. The transcript in Ragu
Ragu's transcript has the structure described above, with a few differences that come from its goal of keeping in-circuit hashing cheap. The operation that combines two proofs is called "fuse" in the code and in much of the Ragu Book, while some pages of the book say "merge". This chapter uses "fuse", following the code.
Reconstructed from code at commit 3219e08, not confirmed by the authors
Parameters. The transcript wraps a Poseidon sponge over the circuit field. A comment in the test vectors states that Ragu's instance has five cells with a rate of 4, and that the tests check the permutation structure against halo2's published vectors at halo2's own width of three cells. A test fixes the cost of one permutation with Ragu's parameters at 288 gates. The constants themselves live in a dependency outside the repository, and we did not read them.
Tags. Transcript::new absorbs the length of the tag and then the tag itself in 16-byte chunks. The two tags are ragu-pcd-v1 for the fuse protocol and ragu-ipa-v1 for compression. The book explains that these tags version the protocol, so proofs made under an earlier tag stop verifying under a later one.
Challenges. The fuse prover alternates between absorbing a commitment and squeezing challenges:
| Absorbed | Squeezed |
|---|---|
| Tag, then the preamble bridge commitment | |
| The bridge commitment | , |
| The inner error bridge commitment | |
| The outer error bridge commitment | |
| The bridge commitment | |
| The query bridge commitment | |
| The bridge commitment | |
| The eval bridge commitment | pre_beta |
The later chapters explain what each commitment and challenge does. Here we need only the pattern, which is the one in Section 8. We read the word "bridge" as reflecting that these commitments are recorded in a form the transcript's field can absorb, which the chapters on curve cycles and endoscalars explain.
The in-circuit cost explains one further choice. Each recursive step has to recompute these challenges inside a circuit, and Ragu divides that work across two internal circuits, hashes_1 and hashes_2, by saving the sponge state between them. The chapter on recursion in Ragu returns to this split.
Absorption without length prefixes
Ragu's sponge adds input to the state and records no message lengths, so a trailing zero in the buffer has no effect on the result. We can see this on the toy sponge, which follows the same absorption rule:
Absorb the seven elements from the table above. The seventh waits in the buffer alone, so absorbing a zero after it leaves the sum unchanged. Both runs squeeze the challenge .
General-purpose transcript libraries prevent this ambiguity by prefixing each message with its length. Ragu prefixes only the tag, and its source comments give efficiency as the reason. The code argues that this is safe because the circuit code fixes how many elements are absorbed at each point and the verifier replays that exact sequence. A prover therefore has no way to attach a message of a different length, and protocols with different sequences have different tags.
An honest prover that retries
One challenge in the table has a special property. The fuse prover grinds pre_beta, re-randomizing the eval commitment and squeezing again until the value falls in the range an endoscalar requires. Section 10 treated repeated attempts as a cheater's tool, and here the honest prover uses them to meet a range condition. The chapter on endoscalars explains that requirement.
The Ragu Book and the code differ here
The book's transcript chapter says that Ragu uses the permutation as a fixed-length hash "rather than as a full sponge". The code at commit 3219e08 has a Sponge type that alternates absorbing and squeezing over one protocol run, and its documentation restricts it to fixed-length inputs. We read the book as describing the absence of length handling, and this site says "sponge", following the code.
The book's configuration guide also gives an illustrative figure of about 280 constraints for two Poseidon hashes, whereas the test counts 288 gates for one permutation. The two figures may count different things, and this site uses the test's number.
Ragu and Tachyon are both still changing. Tachyon has not activated on mainnet, and the details above describe one commit rather than a settled specification.
13. Where this chapter leaves us
This chapter took the following steps:
- A statement claims that a public instance has a secret witness in a relation, and a proof system has to be complete and sound, with a small soundness error.
- Schnorr's protocol shows the commit, challenge, and response pattern, and it shows why the challenge has to come after the commitment.
- A nonzero polynomial of degree over a field has at most roots, so two different low-degree polynomials rarely agree at a random point.
- The Schwartz–Zippel lemma extends this to several variables, with the bound for total degree .
- A random linear combination, usually built from powers of one challenge, replaces many claims with one.
- The Fiat–Shamir transform replaces the verifier's challenges with hashes of a transcript, which must include all public data and every prover message.
- Non-interactive proofs allow repeated trials, so the soundness error has to remain small after multiplying by the number of hashes a cheater can compute.
- Ragu derives its challenges with Poseidon, which it models as a random oracle.
We still have no way of expressing a real computation as a polynomial claim. The next chapter takes the statement from Section 1 and rewrites it as equations over a field, ending with a single equation that the tools from this chapter can check.