Ragu & Tachyon
Home
  • Scaling Zcash
  • An Introduction to Proof-Carrying Data
  • Statements and Challenges
  • Arithmetization
  • QAP and Polynomial Encoding
  • Polynomial Commitments
  • The Inner Product Argument
  • Batched Openings
  • The Complete Proof
  • Recursive Proofs
  • Accumulation
  • Split Accumulation
  • Curve Cycles
  • Revdot Folding
  • Wiring and the Registry
  • Endoscalars
  • Staging
  • Recursion in Ragu
  • Notes, Nullifiers, and Tachygrams
  • Pool State and Anchors
  • Oblivious Sync
  • The Proof Tree
  • Aggregation and Bundles
Final Recap
  • Notation
  • Glossary
  • Curves
Home
  • Scaling Zcash
  • An Introduction to Proof-Carrying Data
  • Statements and Challenges
  • Arithmetization
  • QAP and Polynomial Encoding
  • Polynomial Commitments
  • The Inner Product Argument
  • Batched Openings
  • The Complete Proof
  • Recursive Proofs
  • Accumulation
  • Split Accumulation
  • Curve Cycles
  • Revdot Folding
  • Wiring and the Registry
  • Endoscalars
  • Staging
  • Recursion in Ragu
  • Notes, Nullifiers, and Tachygrams
  • Pool State and Anchors
  • Oblivious Sync
  • The Proof Tree
  • Aggregation and Bundles
Final Recap
  • Notation
  • Glossary
  • Curves
  • Scaling Zcash
  • An Introduction to Proof-Carrying Data
  • Statements and Challenges
  • Arithmetization
  • QAP and Polynomial Encoding
  • Polynomial Commitments
  • The Inner Product Argument
  • Batched Openings
  • The Complete Proof
  • Recursive Proofs
  • Accumulation
  • Split Accumulation
  • Curve Cycles
  • Revdot Folding
  • Wiring and the Registry
  • Endoscalars
  • Staging
  • Recursion in Ragu
  • Notes, Nullifiers, and Tachygrams
  • Pool State and Anchors
  • Oblivious Sync
  • The Proof Tree
  • Aggregation and Bundles
  • Final Recap
  • Appendix

    • Notation
    • Glossary
    • Curves

Arithmetization

A proof system cannot directly reason about a program. Its algebra works with field elements, so the first step in any proof is to rewrite the statement as equations over a field. This rewriting is called arithmetization, and every later step depends on its output.

This chapter takes one small computation through the whole process. We start with ordinary arithmetic, express it as a list of multiplications and linear equations, and then compress all of those equations into a single equation with one secret vector. That final equation is the form Ragu proves, and the next chapter turns it into a statement about polynomials.

1. What arithmetization produces

We continue with the running example from the previous chapter:

I know a number x such that x3+x+5=35.

In the terms of that chapter, 35 is the instance and x is the witness. Arithmetization has to produce a fixed set of equations, determined only by the statement's structure, such that a witness satisfies the equations exactly when the statement is true.

The equations cannot depend on the secret value, because the verifier must know them in advance. A program with an if branch therefore has to compute both branches and select one arithmetically. For example, a value s is restricted to a bit by the equation s(s−1)=0, and the expression s⋅p+(1−s)⋅q selects between p and q. Hash functions and signature checks reduce to field equations in the same way, with many more of them.

All arithmetic in this chapter happens in F43​, the scalar field of the toy curve from the curves appendix. The statement is an equation in this field, though the small values in our example make it look like ordinary arithmetic.

2. Flattening a computation

The expression x3+x+5 contains several operations at once, so we first split it into steps that each perform one operation. Each intermediate result gets its own name:

StepOperationValue for x=3
1w1​=x⋅x9
2w2​=w1​⋅x27
3w2​+x+535

The steps have different costs in a proof system. Step 3 is a linear combination of values we already have, and later sections show that linear combinations can be checked in bulk with a single random combination. Steps 1 and 2 multiply two unknown values, which no linear check can express. Multiplications are therefore what a proof system counts as its main cost, and we keep their number small.

3. Gates

Each multiplication becomes a gate. A circuit with n gates uses three vectors a,b,c∈Fqn​, and gate i requires

ai​⋅bi​=ci​.

The entries of these vectors are called wires. Together they form the witness, which also goes by the name trace because it records one execution of the computation. In vector form, all the gates together say a∘b=c, where ∘ is the entrywise product.

Our computation has two multiplications, so n=2:

Gate iai​bi​ci​Check
03393⋅3=9
193279⋅3=27

4. Linear constraints

The gates alone are not enough, because they treat every wire as independent. Nothing yet says that the a1​ of gate 1 is the output c0​ of gate 0, or that the same x is used everywhere. A separate set of linear constraints connects the wires and ties them to the instance. Constraint j has the form

i=0∑n−1​uj,i​ai​+i=0∑n−1​vj,i​bi​+i=0∑n−1​wj,i​ci​=kj​,

which we can write with inner products as

⟨uj​,a⟩+⟨vj​,b⟩+⟨wj​,c⟩=kj​.

The vectors uj​,vj​,wj​ are public and describe the circuit. The vector k is the public input vector, which holds the instance.

Our statement needs four constraints. The first three connect wires, and the last one checks the output. It moves the constant 5 to the right side, which gives the target value 35−5:

jConstraintuj​vj​wj​kj​
0a0​−b0​=0(1,0)(−1,0)(0,0)0
1a1​−c0​=0(0,1)(0,0)(−1,0)0
2b1​−a0​=0(−1,0)(0,1)(0,0)0
3c1​+a0​=30(1,0)(0,0)(0,1)30

Step 3 from Section 2 has disappeared into constraint 3 at no additional cost in gates. This is why addition is cheap here: a sum of any number of wires appears as one row of coefficients, with no new multiplication.

Ragu allows up to 4n constraint rows, a limit that comes from the size of the polynomial holding the wiring data. Our circuit has room for 8 rows, and the four unused rows are all zeros, which any witness satisfies.

The gates and constraints together reject false statements:

Try x=4 instead. Filling in the gates gives a=(4,16), b=(4,4) and c=(16,21), with 4⋅4=16 and 16⋅4=21 modulo 43. Both gates and the first three constraints hold. The last constraint gives c1​+a0​=25, which is not 30, so this witness is rejected.

5. Reducing the gates to one equation

The verifier now faces n gate equations and 4n constraints, and a real circuit has thousands of each. A proof that handled every equation separately would be enormous, so we want to replace them all with one equation that still fails if any of them fails.

Let ei​=ai​bi​−ci​ be the error of gate i. The previous chapter's random linear combination does this job, with the errors as the claims and the powers of a random value z as the weights:

i=0∑n−1​ziei​=i=0∑n−1​zi(ai​bi​−ci​).

This sum is a polynomial in z with the errors as its coefficients, so it is 0 for every z when all the gates hold. If any gate fails, the bound from that section applies, because the prover must fix the witness before seeing z. A uniformly random z then hides the failure with probability below n/∣Fq​∣.

For the honest witness both gate errors are 0, so the sum is 0 for every z. Now take a dishonest witness with a=(3,8), b=(3,3) and c=(8,27). It satisfies all the linear constraints above, but its gate errors are a0​b0​−c0​=1 and a1​b1​−c1​=40 modulo 43. At z=5 the sum is 1+5⋅40=29, which exposes the error. Checking all 43 values of z finds 1 value that hides it, z=29, the root of this degree-1 polynomial.

On a field of about 2255 elements, this probability is negligible. We have traded certainty for an overwhelming probability, in exchange for checking only one equation.

6. Reducing the constraints to one equation

The constraints collapse in the same way, using a second random value y. Multiplying constraint j by yj and adding gives

j=0∑4n−1​yj(⟨uj​,a⟩+⟨vj​,b⟩+⟨wj​,c⟩)=j=0∑4n−1​yjkj​.

Inner products are linear, so we can move the powers of y inside. Define the combined vectors

u(y)=j∑​yjuj​,v(y)=j∑​yjvj​,w(y)=j∑​yjwj​.

The equation becomes

⟨u(y),a⟩+⟨v(y),b⟩+⟨w(y),c⟩=⟨k,y4n⟩,

where y4n=(1,y,…,y4n−1). The combined vectors are public once y is known, so this is one linear equation in the witness.

At y=7, the combined vectors are u(y)=(37,7), v(y)=(42,6) and w(y)=(36,42). The left side for the honest witness is 2+15+39=13 modulo 43. The right side is 73⋅30=13, because only k3​ is nonzero.

We now have two equations, one quadratic in the witness and one linear. The remaining sections merge them into one equation about a single vector.

7. Reading one coefficient of a product

The merged equation needs a specific form, and the reason comes from polynomial multiplication. Take polynomials p and q with coefficient vectors p,q∈Fqm​. The coefficient of Xk in the product p(X)q(X) is the sum of pi​qj​ over all pairs with i+j=k. For the middle exponent k=m−1, this sum is

i=0∑m−1​pi​qm−1−i​.

Each entry of p meets the entry of q at the mirrored position. This is the inner product of p with the reversal q^​ of q, which is called the revdot product:

⟨⟨p,q⟩⟩=⟨p,q^​⟩=i=0∑m−1​pi​qm−1−i​.

Let p(X)=1+2X+3X2+4X3 and q(X)=5+6X+7X2+8X3 over F43​. The coefficient of X3 in p(X)q(X) collects every pair of exponents that adds to 3: 1⋅8+2⋅7+3⋅6+4⋅5=17 modulo 43. The revdot product computes the same sum, since q^​=(8,7,6,5) and ⟨p,q^​⟩=17. The full product has coefficients (5,16,34,17,18,9,32), and the entry for X3 is the one in the middle.

So a claim about a revdot product is a claim about one coefficient of a polynomial product. This link is why Ragu writes its checks as revdot products, and the next chapter uses it to reach a polynomial test. Our goal for the rest of this chapter is to express both equations as one revdot product.

8. Arranging the witness

A gate's product ai​bi​ has to appear in a revdot product of the witness with itself. Since revdot pairs position k with position m−1−k, we need to place ai​ and bi​ at mirrored positions. We also need room for the ci​ wires, whose partners must not create unwanted products.

A vector of length 4n with four blocks of length n achieves this:

r=c∥a^∥b∥d^.

The vector d is an extra block of wires that we set to zero for now, so each ci​ has a partner of value 0. Reversing the a block places ai​ at position 2n−1−i, and bi​ sits at position 2n+i. These two positions add up to 4n−1, so they are partners. A vector with this arrangement is called a structured vector.

With n=2, the positions and their partners are:

Position kEntryValuePartner position 7−kPartner entry
0c0​97d0​
1c1​276d1​
2a1​95b1​
3a0​34b0​
4b0​33a0​
5b1​32a1​
6d1​01c1​
7d0​00c0​

Eight cells labeled c0, c1, a1, a0, b0, b1, d1, d0, with arcs joining position 3 to 4, 2 to 5, 1 to 6, and 0 to 7.

Each product appears twice in the revdot sum, once from each end of the pair. With d=0, the c wires contribute nothing, so

⟨⟨r,r⟩⟩=2i=0∑n−1​ai​bi​.

For our witness, r=(9,27,9,3,3,3,0,0). Multiplying each entry by its partner and summing gives ⟨⟨r,r⟩⟩=29, and 2⟨a,b⟩=2(3⋅3+9⋅3)=29 modulo 43.

The Ragu Book's chapters arrange the witness differently

The Ragu Book's core arithmetization chapter uses c∥b^∥a∥0, which swaps the roles of a and b. Its local arithmetization chapter uses the arrangement above, and the wiring code at commit 3219e08 matches it. The two arrangements give the same products, because ai​bi​=bi​ai​. This site uses the arrangement from the code.

9. Weighting each gate

The sum 2∑i​ai​bi​ has lost track of which product belongs to which gate, so it cannot check the gates individually. Section 5 solved the same problem by giving each gate its own power of z, and we can build this weighting into the revdot product.

Multiply entry k of the second vector by zk. This operation is called dilation, and the result is r∘z4n, where z4n=(1,z,…,z4n−1). The revdot product becomes

⟨⟨r,r∘z4n⟩⟩=k=0∑4n−1​rk​r4n−1−k​z4n−1−k.

Now we group the terms by gate. The wires ai​ and bi​ occupy positions 2n−1−i and 2n+i. Taking k=2n−1−i produces ai​bi​z2n+i, and taking k=2n+i produces bi​ai​z2n−1−i. The pair of wires ci​,di​ contributes in the same way at positions i and 4n−1−i. The result is

⟨⟨r,r∘z4n⟩⟩=i=0∑n−1​ai​bi​(z2n−1−i+z2n+i)+i=0∑n−1​ci​di​(zi+z4n−1−i).

Each gate now has its own weight, built from powers of z that no other gate uses. With d=0, the second sum vanishes.

At z=5 the powers are (1,5,25,39,23,29,16,37), so r∘z8=(9,6,10,31,26,1,0,0).

krk​r7−k​z7−kTerm
090370
1270160
293299
3332335
433397
5392530
602750
70910

The last column sums to 38. The formula above gives the same value, using weights z3+z4=19 and z2+z5=11: 9⋅19+27⋅11=38 modulo 43.

10. Removing the output wires

The expression above contains the products ai​bi​, but a gate check needs the differences ai​bi​−ci​. We therefore have to subtract ci​ with the same weight as its gate:

−i=0∑n−1​ci​(z2n−1−i+z2n+i).

This sum is linear in the witness, so it can be written as a revdot product of r with a public vector t. The wire ci​ sits at position i, and its partner is position 4n−1−i. Placing the desired coefficient at that partner position gives

t4n−1−i​=−(z2n−1−i+z2n+i)for 0≤i<n,

with all other entries of t equal to zero. Adding the two revdot products and using linearity gives

⟨⟨r,r∘z4n+t⟩⟩=i=0∑n−1​(ai​bi​−ci​)(z2n−1−i+z2n+i).

This expression is the gate check from Section 5 with different weights. It is zero for every z when all the gates hold, and otherwise it is a nonzero polynomial in z.

At z=5, t=(0,0,0,0,0,0,32,24). Its two nonzero entries sit at positions 7 and 6, the partners of c0​ and c1​. Then ⟨⟨r,t⟩⟩=5, and adding the dilated term gives 38+5=0 modulo 43, as it should for a witness that satisfies its gates.

11. Encoding the constraints

The combined constraint equation from Section 6 is linear in the witness, so it fits the same pattern. We want a public vector s such that ⟨⟨r,s⟩⟩ equals its left side. Each wire's coefficient goes at the partner of that wire's position:

WirePosition in rCoefficientPosition in s
ai​2n−1−iu(y)i​2n+i
bi​2n+iv(y)i​2n−1−i
ci​iw(y)i​4n−1−i

Filling in these entries gives ⟨⟨r,s⟩⟩=⟨k,y4n⟩ for a witness that satisfies the constraints.

At y=7, placing the vectors from Section 6 at the partner positions gives s=(0,0,6,42,37,7,42,36), and ⟨⟨r,s⟩⟩=13. This equals ⟨k,y8⟩=13.

The vector s contains the whole circuit structure, compressed by y. The chapter on wiring and the registry studies how a verifier can check s without computing it from scratch.

12. The consolidated equation

Both checks are now revdot products with the same left vector r. The revdot product is linear in its second argument, so we can add them into one equation:

⟨⟨r,r∘z4n+t+s⟩⟩=⟨k,y4n⟩​

This is the output of arithmetization. It contains one secret vector, r. Everything else depends only on the circuit, the instance, and the challenges z and y.

At z=5 and y=7, the combined right vector is r∘z8+t+s=(9,6,16,30,20,8,31,17). Its revdot product with r=(9,27,9,3,3,3,0,0) is 13, and ⟨k,y8⟩=13. Checking the equation at all 432=1849 pairs (z,y) confirms that the honest witness passes at every pair.

Why a false witness fails

Subtracting the right side from the left side splits the equation into two parts:

Eg​(z)i=0∑n−1​(ai​bi​−ci​)(z2n−1−i+z2n+i)​​+Ec​(y)(⟨⟨r,s⟩⟩−⟨k,y4n⟩)​​=0.

The first part depends only on z, and every power of z in it is at least zn, since 2n−1−i≥n for i<n. The second part depends only on y. A gate error therefore cannot cancel a constraint error for all values of the challenges, because the two parts vary independently. If either part is nonzero, the whole expression is a nonzero polynomial in (z,y) of degree at most 4n−1. The prover has to fix r before seeing the challenges, so a random pair passes with probability at most (4n−1)/∣Fq​∣. This bound is the two-variable Schwartz–Zippel lemma from the previous chapter.

On the toy field we can count the exact number of passing challenges for several dishonest witnesses:

Dishonest witnessabcPassing pairs (z,y)Fraction
Gates fail, constraints hold(3,8)(3,3)(8,27)172 of 18490.093
Gates hold, last constraint fails(4,16)(4,4)(16,21)43 of 18490.023
Both fail(4,8)(4,4)(8,21)40 of 18490.022

The bound for this circuit is (4n−1)/∣Fq​∣=7/43≈0.163, and each row falls below it.

Those rates are large only because the field has 43 elements. For n=211 on a 255-bit field, the bound falls below 2−240.

Notice that the argument depends on the challenge order. A prover who learned z and y before fixing r could look for a witness that satisfies only this one equation. The chapter on polynomial commitments provides the tool that fixes r first.

13. The arithmetization in Ragu

Reconstructed from code at commit 3219e08, not confirmed by the authors

Our toy circuit sets d=0 and moves constants into k. Ragu's implementation differs in the following ways:

  • Four wires per gate. The local arithmetization chapter gives each gate the two equations ai​bi​=ci​ and ci​di​=0. The second equation is the second sum from Section 9, which the dilation already checks. At a gate with ci​=0, the wire di​ is free to hold extra witness data.
  • A wire that holds the constant 1. The circuit setup code reserves gate 0 as a system gate, with d0​=1 as the ONE wire and a blinding factor in a0​. A constraint ties this wire to the constant term of the instance. Constants such as our 5 can then appear in constraints as multiples of ONE, instead of being moved to k.
  • Virtual wires. Ragu's Driver interface has mul for gates, enforce_zero for constraints, and add for a virtual wire, which is a named linear combination of existing wires. A virtual wire adds no gate, which matches the cost of addition we saw in Section 4.

The core chapter of the Ragu Book describes the simpler form with d=0, and this chapter follows that form for its example.

14. Comparison with R1CS and PLONK

Other proof systems make different choices at this stage. Two of them are worth knowing, and the first is needed for the next chapter.

R1CS (rank-1 constraint system) uses one vector w containing the constant 1, the instance, and the witness. Three public matrices define the constraints:

Aw∘Bw=Cw.

Each row is one constraint that multiplies two linear combinations of w and compares the result with a third. Our statement fits in three rows:

With w=(1,35,3,9,27), holding the constant 1, the public output, x, w1​ and w2​, the three matrices are

A=​005​000​101​010​001​​,B=​001​000​110​000​000​​,C=​000​001​000​100​010​​.

The products are Aw=(3,9,35) and Bw=(3,3,1). Their entrywise product is (9,27,35), which equals Cw.

R1CS and Ragu's system have the same expressive power, and each can be converted to the other with a linear increase in size. R1CS merges the wiring into its multiplication rows, while Ragu's system (called Bootle16, after its source paper) keeps gates and linear constraints apart. That separation is what makes the revdot form above possible.

PLONK uses gates with selectable coefficients, of the form qL​a+qR​b+qO​c+qM​ab+qC​=0, and adds separate copy constraints to connect wires. Later variants add custom gates and lookup tables that reduce the number of gates for certain operations. Ragu deliberately avoids these features. It uses a simple circuit model and splits large computations into many small circuits that communicate along the PCD tree.

15. Where this chapter leaves us

This chapter took the following steps:

  1. A computation becomes a list of multiplication gates and linear constraints over a field.
  2. Random powers of z and y reduce all gates and constraints to two equations, at the cost of a small failure probability.
  3. A revdot product corresponds to one coefficient of a polynomial product.
  4. A structured vector r places each ai​ and bi​ at mirrored positions, and dilation by z weights each gate separately.
  5. The public vectors t and s add the gate outputs and the wiring, which gives one equation.

The prover still has to convince the verifier of this equation without revealing r. The next chapter starts from the R1CS form to derive the standard QAP reduction, and then uses Section 7 to reach a polynomial test for the consolidated equation.

Last Updated: 11/4/26, 10:49 AM
Contributors: Hanh
Prev
Statements and Challenges
Next
QAP and Polynomial Encoding