You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The goal of this document is to give a good a understanding of our stark prover code. To this end, in the first section we go through a quick recap of how the proving system works at a high level mathematically; then we dive into how that's actually implemented in our code.
3
+
The goal of this document is to give a good a understanding of our stark prover code. To this end, in the first section we go through a recap of how the proving system works at a high level mathematically; then we dive into how that's actually implemented in our code.
Copy file name to clipboardExpand all lines: proving-system/stark/stark_docs/src/recap.md
+103-8Lines changed: 103 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,14 +1,14 @@
1
1
# STARKs Recap
2
2
3
-
##Verifying Computation through Polynomials
3
+
# Verifying Computation through Polynomials
4
4
5
5
In general, we express computation in our proving system by providing an *execution trace* satisfying certain *constraints*. The execution trace is a table containing the state of the system at every step of computation. This computation needs to follow certain rules to be valid; these rules are our *constraints*.
6
6
7
7
The constraints for our computation are expressed using an `Algebraic Intermediate Representation` or `AIR`. This representation uses polynomials to encode constraints, which is why sometimes they are called `polynomial constraints`.
8
8
9
9
To make all this less abstract, let's go through two examples.
10
10
11
-
###Fibonacci numbers
11
+
## Fibonacci numbers
12
12
13
13
Throughout this section and the following we will use this example extensively to have a concrete example. Even though it's a bit contrived (no one cares about computing fibonacci numbers), it's simple enough to be useful. STARKs and proving systems in general are very abstract things; having an example in mind is essential to not get lost.
14
14
@@ -40,7 +40,7 @@ A `valid` trace for this computation is a table satisfying two things:
40
40
41
41
The first item is called a `boundary constraint`, it just enforces specific values on the trace at certain points. The second one is a `transition constraint`; it tells you how to go from one step of computation to the next.
42
42
43
-
###Cairo
43
+
## Cairo
44
44
45
45
The example above is extremely useful to have a mental model, but it's not really useful for anything. The problem is it just works for the very narrow example of computing fibonacci numbers. If we wanted to prove execution of something else, we would have to write an `AIR` for it.
46
46
@@ -56,7 +56,7 @@ Ultimately, our goal is to give the tools to write a STARK prover for the cairo
56
56
57
57
Use the fibonacci example as your go-to for understanding all the moving parts; keep the Cairo example in mind as the thing we are actually building towards.
58
58
59
-
##Step by step walkthrough
59
+
# Step by step walkthrough
60
60
61
61
Below we go through a step by step explanation of a STARK prover. We will assume the trace of the fibonacci sequence mentioned above; it consists of only one column of length $2^n$. In this case, we'll take `n=3`. The trace looks like this
62
62
@@ -71,11 +71,11 @@ Below we go through a step by step explanation of a STARK prover. We will assume
71
71
| a_6 |
72
72
| a_7 |
73
73
74
-
###Trace polynomial
74
+
## Trace polynomial
75
75
76
76
The first step is to interpolate these values to generate the `trace polynomial`. This will be a polynomial encoding all the information about the trace. The way we do it is the following: in the finite field we are working in, we take an `8`-th primitive root of unity, let's call it `g`. It being a primitive root means two things:
77
77
78
-
-$g^8 = 1$ (`g` is an `8`-th root of unity).
78
+
-`g` is an `8`-th root of unity, i.e., $g^8 = 1$.
79
79
- Every `8`-th root of unity is of the form $g^i$ for some $0 \leq i \leq 7$.
80
80
81
81
With `g` in hand, we take the trace polynomial `t` to be the one satisfying
@@ -84,7 +84,7 @@ $$
84
84
t(g^i) = a_i
85
85
$$
86
86
87
-
From here onwards, we will talk about the validity of the trace in terms of properties that this polynomial must satisfy.
87
+
From here onwards, we will talk about the validity of the trace in terms of properties that this polynomial must satisfy. We will also implicitly identify a certain power of $g$ with its corresponding trace element, so for example we sometimes think of $g^5$ as $a_5$, the fifth row in the trace, even though technically it's $t$ *evaluated in* $g^5$ that equals $a_5$.
88
88
89
89
We talked about two different types of constraints the trace must satisfy to be valid. They were:
90
90
@@ -96,4 +96,99 @@ In terms of `t`, this translates to
96
96
- $t(g^0) = 1$ and $t(g) = 1$.
97
97
- $t(x g^2) - t(xg) - t(x) = 0$ for all $x \in \{g^0, g^1, g^2, g^3, g^4, g^5\}$. This is because multiplying by `g` is the same as advancing a row in the trace.
98
98
99
-
###
99
+
## Composition Polynomial
100
+
101
+
To convince the verifier that the trace polynomial satisfies the relationships above, the prover will construct another polynomial that shows that both the boundary and transition constraints are satisfied and commit to it. We call this polynomial the `composition polynomial`, and usually denote it with $H$. Constructing it involves a lot of different things, so we'll go step by step introducing all the moving parts required.
102
+
103
+
### Boundary polynomial
104
+
105
+
To show that the boundary constraints are satisfied, we construct the `boundary polynomial`. Recall that our boundary constraints are $t(g^0) = t(g) = 1$. Let's call $P$ the polynomial that interpolates these constraints, that is, $P$ satisfies:
106
+
107
+
$$
108
+
P(1) = 1 \\
109
+
P(g) = 1
110
+
$$
111
+
112
+
The boundary polynomial $B$ is defined as follows:
113
+
114
+
$$
115
+
B(x) = \dfrac{t(x) - P(x)}{(x - 1) (x - g)}
116
+
$$
117
+
118
+
The denominator here is called the `boundary zerofier`, and it's the polynomial whose roots are the elements of the trace where the boundary constraints must hold.
119
+
120
+
How does $B$ encode the boundary constraints? The idea is that, if the trace satisfies said constraints, then
121
+
122
+
$$
123
+
t(1) - P(1) = 1 - 1 = 0 \\
124
+
t(g) - P(g) = 1 - 1 = 0
125
+
$$
126
+
127
+
so $t(x) - P(x)$ has $1$ and $g$ as roots. Showing these values are roots is the same as showing that $B(x)$ is a polynomial instead of a rational function, and that's why we construct $B$ this way.
128
+
129
+
### Transition constraint polynomial
130
+
To convince the verifier that the transition constraints are satisfied, we construct the `transition constraint polynomial` and call it $C(x)$. It's defined as follows:
How does $C$ encode the transition constraints? We mentioned above that these are satisfied if the polynomial in the numerator vanishes in the elements $\{g^0, g^1, g^2, g^3, g^4, g^5\}$. As with $B$, this is the same as showing that $C(x)$ is a polynomial instead of a rational function.
137
+
138
+
### Constructing $H$
139
+
With the boundary and transition constraint polynomials in hand, we build the `composition polynomial` $H$ as follows: The verifier will sample four numbers $\alpha_1, \alpha_2, \beta_1, \beta_2$ and $H$ will be
where $D$ is the smallest power of two greater than the degrees of both $B$ and $C$, so for example if $deg(B) = 3$ and $deg(C) = 6$, then $D = 8$.
146
+
147
+
Why not just take $H(x) = B(x) + C(x)$? The reason for the alphas and betas is to make the resulting $H$ be always different and unpredictable for the prover, so they can't precompute stuff beforehand. The $x^{D - deg(...)}$ term is simply an optimization to make sure that $H$ always ends up having a power of two as its degree; it adds nothing to the security or soundness of the system, it just allows code implementations to run faster by using the Fast Fourier Transform.
148
+
149
+
With what we discussed above, showing that the constraints are satisfied is equivalent to saying that `H` is a polynomial and not a rational function (we are simplifying things a bit here, but it works for our purposes).
150
+
151
+
## Commiting to $H$
152
+
153
+
To show $H$ is a polynomial we are going to use the `FRI` protocol, which we treat as a black box. For all we care, a `FRI` proof will verify if what we committed to is indeed a polynomial. Thus, the prover will provide a `FRI` commitment to `H`, and if it passes, the verifier will be convinced that the constraints are satisfied.
154
+
155
+
There is one catch here though: how does the verifier know that `FRI` was applied to `H` and not any other polynomial? For this we need to add an additional step to the proving system.
156
+
157
+
158
+
## Consistency check
159
+
After commiting to `H`, the prover needs to show that `H` was constructed correctly according to the formula above. To do this, it will ask the prover to provide an evaluation of `H` on some random point `z` and evaluations of the trace at the points $t(z), t(zg)$ and $t(zg^2)$.
160
+
161
+
Because the boundary and transition constraints are a public part of the protocol, the verifiers knows them, and thus the only thing it needs to compute the evaluation $H(z)$ by themselves are the three trace evaluations mentioned above. Because it asked the prover for them, it can check both sides of the equation:
and be convinced that $H$ was constructed correctly.
168
+
169
+
We are still not done, however, as the prover could have now cheated on the values of the trace evaluations.
170
+
171
+
## Deep Composition Polynomial
172
+
173
+
TODO
174
+
175
+
## FRI and low degree extensions
176
+
177
+
TODO: Move this? it's a digression into LDEs, roots of unity, etc. It probably belongs in an explanation about the constraint evaluation blowup factor on the implementation side.
178
+
179
+
In our case, we will take a primitive $16$-th root of unity $\omega$. This means, as before:
180
+
181
+
- $\omega$ is an $16$-th root of unity, i.e., $\omega^{16} = 1$.
182
+
- Every $16$-th root of unity is of the form $\omega^i$ for some $0 \leq i \leq 15$.
183
+
184
+
Additionally, we also take it so that $\omega$ satisfies $\omega^2 = g$.
185
+
186
+
The evaluation of $t$ on the set $\{\omega^i : 0 \leq i \leq 15\}$ is called a *low degree extension* (`LDE`) of $t$. Notice this is not a new polynomial, they're evaluations of $t$ on some set of points. Also note that because $\omega^2 = g$, the `LDE` contains all the evaluations of $t$ on the set of powers of $g$. In fact,
187
+
188
+
$$
189
+
\{t(\omega^{2i}) : 0 \leq i \leq 15\} = \{t(g^i) : 0 \leq i \leq 7\}
190
+
$$
191
+
192
+
This will be important later on.
193
+
194
+
For our `LDE`, we chose $16$-th roots of unity, but we could have chosen any other power of two greater than $8$. In general, this choice is called the `blowup factor`, so that if the trace has $2^n$ elements, a blowup factor of $b$ means our LDE evaluates over the $2^{n} * b$ roots of unity ($b$ needs to be a power of two). The blowup factor is a parameter of the protocol related to its security.
0 commit comments