Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: fix typos #647

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crypto/src/merkle_tree/test_merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub type TestMerkleTree<F> = MerkleTree<FieldElement<F>>;

/// This hasher is for testing purposes
/// It adds the fields
/// Under no circunstance it can be used in production
/// Under no circumstance it can be used in production
pub struct TestBackend<F> {
phantom: PhantomData<F>,
}
Expand Down
2 changes: 1 addition & 1 deletion docs/src/starks/protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ For $i\in[0,2^{n+k})$, the operation $\text{Open}(A, i)$ returns the pair $(y_i,
The operation $\text{Verify}(i,y,r,s)$ returns _Accept_ or _Reject_ depending on whether the $i$-th element of $A$ is $y$. It checks whether the authentication path $s$ is compatible with $i$, $y$ and the Merkle tree root $r$.


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.
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 committed vector.

##### Batch
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.
Expand Down
4 changes: 2 additions & 2 deletions docs/src/starks/protocol_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ Such a scheme consists of the commit and the open protocols. STARK uses a univar

## Vector commitments

Given a vector $Y = (y_0, \dots, y_M)$, commiting to $Y$ means the following. The prover builds a Merkle tree out of it and sends its root to the verifier. The verifier can then ask the prover to reveal, or _open_, the value of the vector $Y$ at some index $i$. The prover won't have any choice except to send the correct value. The verifier will expect the corresponding value $y_i$ and the authentication path to the tree's root to check its authenticity. The authentication path also encodes the vector's position $i$ and its length $M$.
Given a vector $Y = (y_0, \dots, y_M)$, committing to $Y$ means the following. The prover builds a Merkle tree out of it and sends its root to the verifier. The verifier can then ask the prover to reveal, or _open_, the value of the vector $Y$ at some index $i$. The prover won't have any choice except to send the correct value. The verifier will expect the corresponding value $y_i$ and the authentication path to the tree's root to check its authenticity. The authentication path also encodes the vector's position $i$ and its length $M$.

The root of the Merkle tree is said to be the **commitment** of $Y$, and we denote it here by $[Y]$.

## FRI

In STARKs, all commited vectors are of the form $Y = (p(d_1), \dots, p(d_M))$ for some polynomial $p$ and some fixed domain $D = (d_1, \dots, d_M)$. The domain is always known to the prover and the verifier. It can be proved, as long as $M$ is less than the total number of field elements, that every vector $(y_0, \dots, y_M)$ is equal to $(p(d_1), \dots, p(d_M))$ for a unique polynomial $p$ of degree at most $M-1$. This is called the Lagrange interpolation theorem. It means, there is a unique polynomial of degree at most $M-1$ such that $p(d_i) = y_i$ for all $i$. And $M-1$ is an upper bound to the degree of $p$. It could be less. For example, the vector of all ones $Y = (1,1,\dots,1)$ is the evaluation of the constant polynomial $p = 1$, which has degree $0$.
In STARKs, all committed vectors are of the form $Y = (p(d_1), \dots, p(d_M))$ for some polynomial $p$ and some fixed domain $D = (d_1, \dots, d_M)$. The domain is always known to the prover and the verifier. It can be proved, as long as $M$ is less than the total number of field elements, that every vector $(y_0, \dots, y_M)$ is equal to $(p(d_1), \dots, p(d_M))$ for a unique polynomial $p$ of degree at most $M-1$. This is called the Lagrange interpolation theorem. It means, there is a unique polynomial of degree at most $M-1$ such that $p(d_i) = y_i$ for all $i$. And $M-1$ is an upper bound to the degree of $p$. It could be less. For example, the vector of all ones $Y = (1,1,\dots,1)$ is the evaluation of the constant polynomial $p = 1$, which has degree $0$.

Suppose the vector $Y=(y_1, \dots, y_M)$ is the vector of evaluations of a polynomial $p$ of degree strictly less than $M-1$. Suppose one party holds the vector $Y$ and another party holds only the commitment $[Y]$ of it. The FRI protocol is an efficient interactive protocol with which the former can convince the latter that the commitment they hold corresponds to the vector of evaluations of a polynomial $p$ of degree strictly less than $M$.

Expand Down
4 changes: 2 additions & 2 deletions docs/src/starks/recap.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,15 @@ Why not just take \\(H(x) = B(x) + C(x)\\)? The reason for the betas is to make

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).

## Commiting to \\(H\\)
## Committing to \\(H\\)

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.

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 protocol.


## Consistency check
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)\\).
After committing 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)\\).

Because the boundary and transition constraints are a public part of the protocol, the verifier knows them, and thus the only thing it needs to compute the evaluation \\((z)\\) by itself are the three trace evaluations mentioned above. Because it asked the prover for them, it can check both sides of the equation:

Expand Down
2 changes: 1 addition & 1 deletion exercises/challenge_3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ P = p_1(X) * 0 + p_2(X) * 0 + p_3(X) * 0 + p_4(X)
```
At the current moment, the X is equal to `42`.

Suddenly Gohan, and Piccolo recieve a message from Bulma that the scouters verify the sensed power level of individual enemies using KZG and for multiple enemies with batched KZG method. Vegeta knows for sure that the power level of Gohan is `p_4(X) = 9000`, so he will know if we change that. If only the team had a way to trick their opponents to believe that their total power level is `P > 9000` - then the enemies will surely flee.
Suddenly Gohan, and Piccolo receive a message from Bulma that the scouters verify the sensed power level of individual enemies using KZG and for multiple enemies with batched KZG method. Vegeta knows for sure that the power level of Gohan is `p_4(X) = 9000`, so he will know if we change that. If only the team had a way to trick their opponents to believe that their total power level is `P > 9000` - then the enemies will surely flee.
2 changes: 1 addition & 1 deletion exercises/message/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ Now, realizing, verifier is broken, we need to check that the composition polyno
The "hack" has 2 ingredients:

In Round 3, the evil prover lies about H(z) so it matches the exact value the verifier will reconstruct from the trace(s).
Because the constraints are not satisfied, the committed H(x)'s values are garbage. We also lied about H(z). Therefore in theory Deep(x)'s term(s) involving H are total garbage, and definitely not a low degree polynomial. But we can lie about Deep(x)'s values too. In Round 4, the evil prover anticipates the verifier will do a consistency check at some random iota_0 that compares the committed Deep(x) value at iota_0 to the RHS of Deep's definition recomputed from the commited H(iota_0) and traces(iota_0). So the prover creates Deep(x) h_1 and h_2 terms by interpolating through as many evaluations of the RHS definition as the low-degree check will allow. The number of such evaluations is LDE domain length / blowup_factor, so this ensures the single consistency check will pass with probability (LDE domain length / blowup_factor) / LDE domain length, in other words 1 / blowup_factor.
Because the constraints are not satisfied, the committed H(x)'s values are garbage. We also lied about H(z). Therefore in theory Deep(x)'s term(s) involving H are total garbage, and definitely not a low degree polynomial. But we can lie about Deep(x)'s values too. In Round 4, the evil prover anticipates the verifier will do a consistency check at some random iota_0 that compares the committed Deep(x) value at iota_0 to the RHS of Deep's definition recomputed from the committed H(iota_0) and traces(iota_0). So the prover creates Deep(x) h_1 and h_2 terms by interpolating through as many evaluations of the RHS definition as the low-degree check will allow. The number of such evaluations is LDE domain length / blowup_factor, so this ensures the single consistency check will pass with probability (LDE domain length / blowup_factor) / LDE domain length, in other words 1 / blowup_factor.
Loading