diff --git a/docs/src/starks/protocol.md b/docs/src/starks/protocol.md index 58900c7bc8..127535c0f3 100644 --- a/docs/src/starks/protocol.md +++ b/docs/src/starks/protocol.md @@ -34,7 +34,7 @@ These values are determined the program, the specifications of the AIR being us - $m$ is the total number of columns: $m := m' + m''$. - $P_k^T$ denote the transition constraint polynomials for $k=1,\dots,n_T$. We are assuming these are of degree at most 2. - $Z_j^T$ denote the transition constraint zerofiers for $k=1,\dots,n_T$. -- $b=2^l$ is the *[blowup factor](/starks/protocol_overview.html#general-case-the-blowup-factor)*. +- $b=2^l$ is the *[blowup factor](/starks/protocol_overview.html#fri)*. - $c$ is the *grinding factor*. - $Q$ is number of FRI queries. - We assume there is a fixed hash function from $\mathbb{F}$ to binary strings. We also assume all Merkle trees are constructed using this hash function. @@ -67,7 +67,7 @@ The operation $\text{Verify}(i,y,r,s)$ returns _Accept_ or _Reject_ depending on In our cases the sets $A$ will be of the form $A=(f(a), f(ab), f(ab^2), \dots, f(ab^L))$ for some elements $a,b\in\mathbb{F}$. It will be convenient to use the following abuse of notation. We will write $\text{Open}(A, ab^i)$ to mean $\text{Open}(A, i)$. Similarly, we will write $\text{Verify}(ab^i, y, r, s)$ instead of $\text{Verify}(i, y, r, s)$. Note that this is only notation and $\text{Verify}(ab^i, y, r, s)$ is only checking that the $y$ is the $i$-th element of the commited vector. ##### Batch -As we mentioned in the protocol overview. When committing to multiple vectors $A_1, \dots, A_k$, where $A_i = (y_0^{(i), \dots, y_L^{(i)}})$ one can build a single Merkle tree. Its $j$-th leaf is the concatenation of all the $j$-th coordinates of all vectors, that is, $(y_j^{(1)}||\dots||y_j^{(k)})$. The commitment to this batch of vectors is the root of this Merkle tree. +As we mentioned in the [protocol overview](protocol_overview.html#batch). When committing to multiple vectors $A_1, \dots, A_k$, where $A_i = (y_0^{(i), \dots, y_L^{(i)}})$ one can build a single Merkle tree. Its $j$-th leaf is the concatenation of all the $j$-th coordinates of all vectors, that is, $(y_j^{(1)}||\dots||y_j^{(k)})$. The commitment to this batch of vectors is the root of this Merkle tree. ## Protocol diff --git a/docs/src/starks/protocol_overview.md b/docs/src/starks/protocol_overview.md index 130c8b3b71..193d09d0b8 100644 --- a/docs/src/starks/protocol_overview.md +++ b/docs/src/starks/protocol_overview.md @@ -11,7 +11,7 @@ Then the verifier chooses a random point $z$ and challenges the prover to reveal In summary, at a very high level, the STARK protocol can be organized into three major parts: - Arithmetization and commitment of execution trace. -- Construction of composition polynomial $H$. +- Construction and commitment of composition polynomial $H$. - Opening of polynomials at random $z$. # Arithmetization @@ -50,17 +50,19 @@ Suppose the vector $Y=(y_1, \dots, y_M)$ is the vector of evaluations of a polyn More precisely, the protocol depends on the following parameters - Powers of two $N = 2^n$ and $M = 2^m$ with $n < m$. -- A vector $D=(d_1,\dots,d_M)$, with $d_i$ in $\mathbb{F}$ for all $i$ and $d_i\neq d_j$ for all $i\neq j$. +- A vector $D=(d_1,\dots,d_M)$, with $d_i = h\omega^i$, with $h$ a nonzero value in $\mathbb{F}$ and $\omega$ a primitive $M$-root of unity + +The number $b = M/N = 2^{m-n}$ is called the **blowup factor** and the security of the protocol depends in part on this parameter. The specific shape of the domain set $D$ has some symmetric properties important for the inner workings of FRI, such as $-d_i \in D$ for all $i$. A prover holds a vector $Y=(y_1,\dots,y_M)$, and the verifier holds the commitment $[Y]$ of it. The result of the FRI protocol will be _Accept_ if the unique polynomial $p$ of degree less than $M-1$ such that $Y=(p(d_1),\dots,p(d_M))$ has degree less than $N-1$. Even more precisely, the protocol proves that $Y$ is very close to a vector $(p(d_1),\dots,p(d_M))$ with $p$ of degree less than $N-1$, but it may differ in negligible proportion of the coordinates. ### Variant useful for STARKs -FRI is usually described as above. In STARK, FRI is used as a building block of the polynomial commitment scheme of the next section. For it, a small variant of FRI is needed. +FRI is usually described as above. In STARK, FRI is used as a building block for the polynomial commitment scheme of the next section. For that, a small variant of FRI is needed. Suppose the prover holds a vector $Y = (y_1, \dots, y_M)$ and the verifier holds its commitment $[Y]$ as before. Suppose further that both parties know a function $F$ that takes two field elements and outputs another field element. For example $F$ could be the function $F(a,b) = a + b^{-1}$. More precisely, the kind of functions we need are $F: \mathbb{F} \times D \to \mathbb{F}$. -The protocol can be used to prove that the transformed vector $(F(y_1, d_1), \dots, F(y_M, d_M))$ is the vector of evaluations of a polynomial $q$ of degree at most $N-1$. Or more precisely, it differs only in a negligible proportion of the coordinates. Note that in this variant, the verifier holds originally the commitment of the vector $Y$ and not the commitment of the transformed vector. In the example, the verifier holds the commitment $[Y]$ and FRI will return _Accept_ if $(y_1 + d_1^{-1}, \dots, y_M + d_M^{-1})$ is the vector of evaluations of a polynomial of degree at most $N-1$. +The protocol can be used to prove that the transformed vector $(F(y_1, d_1), \dots, F(y_M, d_M))$ is the vector of evaluations of a polynomial $q$ of degree at most $N-1$. Note that in this variant, the verifier holds originally the commitment of the vector $Y$ and not the commitment of the transformed vector. In the example, the verifier holds the commitment $[Y]$ and FRI will return _Accept_ if $(y_1 + d_1^{-1}, \dots, y_M + d_M^{-1})$ is the vector of evaluations of a polynomial of degree at most $N-1$. ## Polynomial commitments @@ -72,7 +74,7 @@ STARK uses a univariate polynomial commitment scheme. The following is what is e Let's see how both of these protocols work in detail. The same configuration parameters of FRI are needed: - Powers of two $N = 2^n$ and $M = 2^m$ with $n < m$. -- A vector $D=(d_1,\dots,d_M)$, with $d_i$ in $\mathbb{F}$ for all $i$ and $d_i\neq d_j$ for all $i\neq j$. +- A vector $D=(d_1,\dots,d_M)$, with $d_i = h\omega^i$, with $h$ a nonzero value in $\mathbb{F}$ and $\omega$ a primitive $M$-root of unity The commitment scheme will only work for polynomials of degree at most $N$ (polynomials of degree $N$ are allowed). This means: anyone can commit to any polynomial, but the Open protocol will pass only for polynomials satisfying that degree bound. @@ -106,37 +108,31 @@ Suppose the prover is trying to cheat and sends the commitment $[Y]$ of a vector During proof generation, polynomials are committed and opened several times. Computing these for each polynomial independently is costly. In this section, we'll see how batching polynomials can reduce the amount of computation. Let $P=\{p_1, \dots, p_L\}$ be a set of polynomials. We will commit and open $P$ as a whole. We note this batch commitment as $[P]$. -We need the same configuration parameters as before: $N=2^n$, $M=2^m$ with $N0$. - -As described earlier, to commit to a single polynomial $p$, a Merkle tree is built over the vector $(p(d_1), \dots, p(d_m))$. When committing to a batch of polynomials $P=\{p_1, \dots, p_n\}$, the leaves of the Merkle tree are instead the concatenation of the polynomial evaluations. That is, in the batch setting, the Merkle tree is built for the vector $(p_1(d_1)||\dots||p_L(d_1), \dots, p_L(d_m)||\dots||p_n(d_m))$. The commitment $[P]$ is the root of this Merkle tree. This reduces the proof size: we only need one Merkle tree for $L$ polynomials. The verifier can then only ask for values in batches. When the verifier chooses an index $i$, the prover sends $p_1 (d_i) , \dots , p_L (d_i)$ along with one authentication path. The verifier on his side computes the concatenation $p_1(d_i)||\dots||p_L(d_i)$ and validates it with the authentication path and $[P]$. This also reduces the computational time. By traversing the Merkle tree one time, it can reveal several components simultaneously. +We need the same configuration parameters as before: $N=2^n$, $M=2^m$ with $N