From b6540206f36d577638d1fa08bf31bb7f933a3cd1 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 3 May 2023 15:03:30 +0200 Subject: [PATCH 01/15] Book: introduce unified notation for PlonK --- book/macros.txt | 4 +++- book/src/kimchi/final_check.md | 4 ++-- book/src/kimchi/lookup.md | 8 ++++---- book/src/plonk/domain.md | 2 +- book/src/plonk/maller.md | 6 +++--- book/src/plonk/overview.md | 4 ++-- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/book/macros.txt b/book/macros.txt index 2048c9d02c..ff5d96db6e 100644 --- a/book/macros.txt +++ b/book/macros.txt @@ -62,4 +62,6 @@ \enc:{\small \mathsf{Enc}} \gid:{\mathsf{gid}} \counter:{\mathsf{counter}} -\prg:{\small \mathsf{PRG}} \ No newline at end of file +\prg:{\small \mathsf{PRG}} + +\plonk:\textsf{Plonk} diff --git a/book/src/kimchi/final_check.md b/book/src/kimchi/final_check.md index 18a49234e7..02bb50e911 100644 --- a/book/src/kimchi/final_check.md +++ b/book/src/kimchi/final_check.md @@ -1,6 +1,6 @@ -# Understanding the implementation of the $f(\zeta) = Z_H(\zeta) t(\zeta)$ check +# Understanding the implementation of the $f(\zeta) = Z_H(\zeta) t(\zeta)$ check -Unlike the latest version of vanilla PLONK that implements the the final check using a polynomial opening (via Maller's optimization), we implement it manually. (That is to say, Izaak implemented Maller's optimization for 5-wires.) +Unlike the latest version of vanilla $\plonk$ that implements the the final check using a polynomial opening (via Maller's optimization), we implement it manually. (That is to say, Izaak implemented Maller's optimization for 5-wires.) But the check is not exactly $f(\zeta) = Z_H(\zeta) t(\zeta)$. This note describes how and why the implementation deviates a little. diff --git a/book/src/kimchi/lookup.md b/book/src/kimchi/lookup.md index a261672716..bab15b1d75 100644 --- a/book/src/kimchi/lookup.md +++ b/book/src/kimchi/lookup.md @@ -1,6 +1,6 @@ # Plookup in Kimchi -In 2020, [plookup](https://eprint.iacr.org/2020/315.pdf) showed how to create lookup proofs. Proofs that some witness values are part of a [lookup table](https://en.wikipedia.org/wiki/Lookup_table). Two years later, an independent team published [plonkup](https://eprint.iacr.org/2022/086) showing how to integrate Plookup into Plonk. +In 2020, [plookup](https://eprint.iacr.org/2020/315.pdf) showed how to create lookup proofs. Proofs that some witness values are part of a [lookup table](https://en.wikipedia.org/wiki/Lookup_table). Two years later, an independent team published [plonkup](https://eprint.iacr.org/2022/086) showing how to integrate Plookup into $\plonk$. This document specifies how we integrate plookup in kimchi. It assumes that the reader understands the basics behind plookup. @@ -38,7 +38,7 @@ where $\text{diff}$ is a new set derived by applying a "randomized difference" b > Note: This assumes that the lookup table is a single column. You will see in the next section how to address lookup tables with more than one column. -The equality between the multisets can be proved with the permutation argument of plonk, which would look like enforcing constraints on the following accumulator: +The equality between the multisets can be proved with the permutation argument of $\plonk$, which would look like enforcing constraints on the following accumulator: * init: $\mathsf{acc}_0 = 1$ * final: $\mathsf{acc}_n = 1$ @@ -208,7 +208,7 @@ What about the second vector $s$? ## The sorted vector $s$ -We said earlier that in original plonk the size of $s$ is equal to $|s| = |f|+|t|$, where $f$ encodes queries, and $t$ encodes the lookup table. +We said earlier that in original $\plonk$ the size of $s$ is equal to $|s| = |f|+|t|$, where $f$ encodes queries, and $t$ encodes the lookup table. With our multi-query approach, the second vector $s$ is of the size $$n \cdot |\#\text{queries}| + |\text{lookup\_table}|$$ @@ -216,7 +216,7 @@ $$n \cdot |\#\text{queries}| + |\text{lookup\_table}|$$ That is, it contains the $n$ elements of each **query vectors** (the actual values being looked up, after being combined with the joint combinator, that's $4$ per row), as well as the elements of our lookup table (after being combined as well). Because the vector $s$ is larger than the domain size $n$, it is split into several vectors of size $n$. Specifically, in the plonkup paper, the two halves of $s$, which are then interpolated as $h_1$ and $h_2$. -The denominator in plonk in the vector form is +The denominator in $\plonk$ in the vector form is $$ \big(\gamma(1+\beta) + s_{i-1} + \beta s_{i}\big)\big(\gamma(1+\beta)+s_{n+i-1} + \beta s_{n+i}\big) $$ diff --git a/book/src/plonk/domain.md b/book/src/plonk/domain.md index 98e05aa954..186f03758e 100644 --- a/book/src/plonk/domain.md +++ b/book/src/plonk/domain.md @@ -1,6 +1,6 @@ # Domain -Plonk needs a domain to encode the circuit on (for each point we can encode a row/constraint/gate). +$\plonk$ needs a domain to encode the circuit on (for each point we can encode a row/constraint/gate). We choose a domain $H$ such that it is a multiplicative subgroup of the scalar field of our curve. ## 2-adicity diff --git a/book/src/plonk/maller.md b/book/src/plonk/maller.md index d5e0d26965..254ebb0c02 100644 --- a/book/src/plonk/maller.md +++ b/book/src/plonk/maller.md @@ -1,6 +1,6 @@ # Maller's Optimization to Reduce Proof Size -In the PLONK paper, they make use of an optimization from Mary Maller in order to reduce the proof size. +In the $\plonk$ paper, they make use of an optimization from Mary Maller in order to reduce the proof size. ## Explanation @@ -87,9 +87,9 @@ The problem here is that you can't multiply the commitments together without usi If you're using an inner-product-based commitment, you can't even multiply commitments. -question: where does the multiplication of commitment occurs in the pairing-based protocol of PLONK? And how come we can use bootleproof if we need that multiplication of commitment? +question: where does the multiplication of commitment occurs in the pairing-based protocol of $\plonk$? And how come we can use bootleproof if we need that multiplication of commitment? -## Appendix: Original explanation from the PLONK paper +## Appendix: Original explanation from the $\plonk$ paper https://eprint.iacr.org/2019/953.pdf diff --git a/book/src/plonk/overview.md b/book/src/plonk/overview.md index 9b2426ddc7..bb088e9420 100644 --- a/book/src/plonk/overview.md +++ b/book/src/plonk/overview.md @@ -1,13 +1,13 @@ # Overview -The proof system in Mina is a variant of [PLONK](). To understand PLONK, you can refer to our [series of videos](https://www.youtube.com/watch?v=RUZcam_jrz0&list=PLBJMt6zV1c7Gh9Utg-Vng2V6EYVidTFCC) on the scheme. +The proof system in Mina is a variant of [$\plonk$](https://eprint.iacr.org/2019/953.pdf). To understand $\plonk$, you can refer to our [series of videos](https://www.youtube.com/watch?v=RUZcam_jrz0&list=PLBJMt6zV1c7Gh9Utg-Vng2V6EYVidTFCC) on the scheme. In this section we explain our variant, called **kimchi**. kimchi is not formally a zk-SNARK, as it is not succinct in the proof size. zk-SNARKs must have a $log(n)$ proof size where n is the number of gates in the circuit. In kimchi, due to the Bootleproof polynomial commitment approach, our proofs are $log(d)$ where $d$ is the maximum degree of the committed polynomials (in the order of the number of rows). In practice, our proofs are in the order of dozens of kilobytes. Note that kimchi is a zk-SNARK in terms of verification complexity ($log(n$)) and the proving complexity is quasilinear ($O(nlogn)$) – recall that the prover cannot be faster than linear. -Essentially what PLONK allows you to do is to, given a program with inputs and outputs, take a snapshot of its execution. Then, you can remove parts of the inputs, or outputs, or execution trace, and still prove to someone that the execution was performed correctly for the remaining inputs and outputs of the snapshot. +Essentially what $\plonk$ allows you to do is to, given a program with inputs and outputs, take a snapshot of its execution. Then, you can remove parts of the inputs, or outputs, or execution trace, and still prove to someone that the execution was performed correctly for the remaining inputs and outputs of the snapshot. There are a lot of steps involved in the transformation of "I know an input to this program such that when executed with these other inputs it gives this output" to "here's a sequence of operations you can execute to convince yourself of that". At the end of this chapter, you will understand that the protocol boils down to filling a number of tables (illustrated in the diagram below): tables that specify the circuit, and tables that describes an execution trace of the circuit (given some secret and public inputs). From c8c605a6891f46297c01106ed66b8bed8f7482de Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 29 Nov 2023 18:49:14 +0100 Subject: [PATCH 02/15] Delete trailing whitespaces --- book/src/kimchi/final_check.md | 8 ++++---- book/src/kimchi/overview.md | 18 +++++++++--------- book/src/specs/poseidon.md | 20 ++++++++++---------- book/src/specs/urs.md | 4 ++-- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/book/src/kimchi/final_check.md b/book/src/kimchi/final_check.md index 02bb50e911..440bbef277 100644 --- a/book/src/kimchi/final_check.md +++ b/book/src/kimchi/final_check.md @@ -70,7 +70,7 @@ $$\begin{align} & (w[5](\zeta) + \beta \cdot \sigma[5](\zeta) + \gamma) \cdot \\ & (w[6](\zeta) + \gamma) \end{align}$$ - + So at the end, when we have to check for the identity $f(\zeta) = Z_H(\zeta) t(\zeta)$ we'll actually have to check something like this (I colored the missing parts on the left hand side of the equation): $$ @@ -151,7 +151,7 @@ $$ & = \color{darkred}{(1 - z(\zeta))[\frac{(\zeta^n - 1)}{n(\zeta - 1)} \alpha^{PERM1} + \frac{\omega^{n-k}(\zeta^n - 1)}{n(\zeta - \omega^{n-k})} \alpha^{PERM2}]} \end{align} $$ - + finally we extract some terms from the lagrange basis: $$ @@ -182,7 +182,7 @@ $$ with $\alpha^{PERM0} = \alpha^{17}, \alpha^{PERM1} = \alpha^{18}, \alpha^{PERM2} = \alpha^{19}$ -Why do we do things this way? Most likely to reduce +Why do we do things this way? Most likely to reduce Also, about the code: @@ -230,7 +230,7 @@ $$ and `bnd` is: -$$bnd(x) = +$$bnd(x) = a^{PERM1} \cdot \frac{z(x) - 1}{x - 1} + a^{PERM2} \cdot \frac{z(x) - 1}{x - sid[n-k]} diff --git a/book/src/kimchi/overview.md b/book/src/kimchi/overview.md index b8ad73a78e..740acd763d 100644 --- a/book/src/kimchi/overview.md +++ b/book/src/kimchi/overview.md @@ -1,11 +1,11 @@ # Overview -Here we explain how the Kimchi protocol design is translated into the `proof-systems` repository, from a high level perspective, touching briefly on all the involved aspects of cryptography. The concepts that we will be introducing can be studied more thoroughly by accessing the specific sections in the book. +Here we explain how the Kimchi protocol design is translated into the `proof-systems` repository, from a high level perspective, touching briefly on all the involved aspects of cryptography. The concepts that we will be introducing can be studied more thoroughly by accessing the specific sections in the book. -In brief, the Kimchi protocol requires three different types of arguments `Argument`: -- **Custom gates:** they correspond to each of the specific functions performed by the circuit, which are represented by gate constraints. +In brief, the Kimchi protocol requires three different types of arguments `Argument`: +- **Custom gates:** they correspond to each of the specific functions performed by the circuit, which are represented by gate constraints. - **Permutation:** the equality between different cells is constrained by copy constraints, which are represented by a permutation argument. It represents the wiring between gates, the connections from/to inputs and outputs. -- **Lookup tables:** for efficiency reasons, some public information can be stored by both parties (prover and verifier) instead of wired in the circuit. Examples of these are boolean functions. +- **Lookup tables:** for efficiency reasons, some public information can be stored by both parties (prover and verifier) instead of wired in the circuit. Examples of these are boolean functions. All of these arguments are translated into equations that must hold for a correct witness for the full relation. Equivalently, this is to say that a number of expressions need to evaluate to zero on a certain set of numbers. So there are two problems to tackle here: @@ -24,22 +24,22 @@ $$q(X) := \frac{p(X)}{v_S(X)}$$ And still, where's the hype? If you can provide such a quotient polynomial, one could easily check that if $q(a) = p(a) / v_S(a)$ for a random number $a\in\mathbb{F}$ \ $S$ (recall you will check in a point out of the set, otherwise you would get a $0/0$), then with very high probability that would mean that actually $p(X) = q(X) \cdot v_S(X)$, meaning that $p(X)$ vanishes on the whole set $S$, with **just one point**! -Let's take a deeper look into the _"magic"_ going on here. First, what do we mean by _high probability_? Is this even good enough? And the answer to this question is: as good as you want it to be. +Let's take a deeper look into the _"magic"_ going on here. First, what do we mean by _high probability_? Is this even good enough? And the answer to this question is: as good as you want it to be. **First** we analyse the math in this check. If the polynomial form of $p(X) = q(X) \cdot v_S(X)$ actually holds, then of course for any possible $a\in\mathbb{F}$ \ $S$ the check $p(a) =_? q(a) \cdot v_S(a)$ will hold. But is there any unlucky instantiation of the point $a$ such that $p(a) = q(a) \cdot v_S(a)$ but $p(X) \neq q(X) \cdot v_S(X)$? And the answer is, yes, there are, BUT not many. But how many? How unlikely this is? You already know the answer to this: **Schwartz-Zippel**. Recalling this lemma: -> Given two different polynomials $f(X)$ and $g(X)$ of degree $d$, they can at most intersect (i.e. _coincide_) in $d$ points. Or what's equivalent, let $h(X) := f(X) - g(X)$, the polynomial $h(X)$ can only evaluate to $0$ in at most $d$ points (its roots). +> Given two different polynomials $f(X)$ and $g(X)$ of degree $d$, they can at most intersect (i.e. _coincide_) in $d$ points. Or what's equivalent, let $h(X) := f(X) - g(X)$, the polynomial $h(X)$ can only evaluate to $0$ in at most $d$ points (its roots). Thus, if we interchange $p(X) \rightarrow f(X)$ and $q(X)\cdot v_S(X) \rightarrow g(X)$, both of degree $d$, there are at most $\frac{d}{|\mathbb{F}- S|}$ unlucky points of $a$ that could trick you into thinking that $p(X)$ was a multiple of the vanishing polynomial (and thus being equal to zero on all of $S$). So, how can you make this error probability negligible? By having a field size that is big enough (the formal definition says that the inverse of its size should decrease faster than any polynomial expression). Since we are working with fields of size $2^{255}$, we are safe on this side! **Second**, is this really faster than checking that $p(x)=0$ for all $x\in S$ ? At the end of the day, it seems like we need to evaluate $v_S(a)$, and since this is a degree $|S|$ polynomial it looks like we are still performing about the same order of computations. But here comes math again. _In practice_, we want to define this set $S$ to have a _nice structure_ that allows us to perform some computations more efficiently than with arbitrary sets of numbers. Indeed, this set will normally be a **multiplicative group** (normally represented as $\mathbb{G}$ or $\mathbb{H}$), because in such groups the vanishing polynomial $v_\mathbb{G}(X):=\prod_{\omega\in\mathbb{G}}(X-\omega)$ has an efficient representation $v_\mathbb{G}(X)=X^{|\mathbb{G}|}-1$, which is much faster to evaluate than the above product. -**Third**, we may want to understand what happens with the evaluation of $p(a)$ instead. Since this is a degree $d ≥ |\mathbb{G}|$, it may look like this will as well take a lot of effort. But here's where cryptography comes into play, since the verifier will _never_ get to evaluate the actual polynomial by themselves. Various reasons why. One, if the verifier had access to the full polynomial $p(X)$, then the prover should have sent it along with the proof, which would require $d+1$ coefficients to be represented (and this is no longer succinct for a SNARK). Two, this polynomial could carry some secret information, and if the verifier could recompute evaluations of it, they could learn some private data by evaluating on specific points. So instead, these evaluations will be a "mental game" thanks to **polynomial commitments** and **proofs of evaluation** sent by the prover (for whom a computation in the order of $d$ is not only acceptable, but necessary). The actual proof length will depend heavily on the type of polynomial commitments we are using. For example, in Kate-like commitments, committing to a polynomial takes a constant number of group elements (normally one), whereas in Bootleproof it is logarithmic. But in any case this will be shorter than sending $O(d)$ elements. +**Third**, we may want to understand what happens with the evaluation of $p(a)$ instead. Since this is a degree $d ≥ |\mathbb{G}|$, it may look like this will as well take a lot of effort. But here's where cryptography comes into play, since the verifier will _never_ get to evaluate the actual polynomial by themselves. Various reasons why. One, if the verifier had access to the full polynomial $p(X)$, then the prover should have sent it along with the proof, which would require $d+1$ coefficients to be represented (and this is no longer succinct for a SNARK). Two, this polynomial could carry some secret information, and if the verifier could recompute evaluations of it, they could learn some private data by evaluating on specific points. So instead, these evaluations will be a "mental game" thanks to **polynomial commitments** and **proofs of evaluation** sent by the prover (for whom a computation in the order of $d$ is not only acceptable, but necessary). The actual proof length will depend heavily on the type of polynomial commitments we are using. For example, in Kate-like commitments, committing to a polynomial takes a constant number of group elements (normally one), whereas in Bootleproof it is logarithmic. But in any case this will be shorter than sending $O(d)$ elements. ### Aggregation -So far we have seen how to check that a polynomial equals zero on all of $\mathbb{G}$, with just a single point. This is somehow an aggregation _per se_. But we are left to analyse how we can prove such a thing, for many polynomials. Altogether, if they hold, this will mean that the polynomials encode a correct witness and the relation would be satisfied. These checks can be performed one by one (checking that each of the quotients are indeed correct), or using an efficient aggregation mechanism and checking only **one longer equation at once**. +So far we have seen how to check that a polynomial equals zero on all of $\mathbb{G}$, with just a single point. This is somehow an aggregation _per se_. But we are left to analyse how we can prove such a thing, for many polynomials. Altogether, if they hold, this will mean that the polynomials encode a correct witness and the relation would be satisfied. These checks can be performed one by one (checking that each of the quotients are indeed correct), or using an efficient aggregation mechanism and checking only **one longer equation at once**. So what is the simplest way one could think of to perform this one-time check? Perhaps one could come up with the idea of adding up all of the equations $p_0(X),...,p_n(X)$ into a longer one $\sum_{i=0}^{n} p_i(X)$. But by doing this, we may be cancelling out terms and we could get an incorrect statemement. @@ -47,7 +47,7 @@ So instead, we can multiply each term in the sum by a random number. The reason $$\bigwedge_{i_n} p_i(X) =_? 0 \iff_{w.h.p.} \sum_{i=0}^{n} \rho_i \cdot p_i(X) =_? 0 $$ -This sounds great so far. But we are forgetting about an important part of proof systems which is proof length. For the above claim to be sound, the random values used for aggregation should be verifier-chosen, or at least prover-independent. So if the verifier had to communicate with the prover to inform about the random values being used, we would get an overhead of $n$ field elements. +This sounds great so far. But we are forgetting about an important part of proof systems which is proof length. For the above claim to be sound, the random values used for aggregation should be verifier-chosen, or at least prover-independent. So if the verifier had to communicate with the prover to inform about the random values being used, we would get an overhead of $n$ field elements. Instead, we take advantage of another technique that is called **powers-of-alpha**. Here, we make the assumption that powers of a random value $\alpha^i$ are indistinguishable from actual random values $\rho_i$. Then, we can twist the above claim to use only one random element $\alpha$ to be agreed with the prover as: diff --git a/book/src/specs/poseidon.md b/book/src/specs/poseidon.md index 36e1c5a45f..59af050af5 100644 --- a/book/src/specs/poseidon.md +++ b/book/src/specs/poseidon.md @@ -15,24 +15,24 @@ We might want to piggy back on the [zcash poseidon spec](https://github.com/C2SP We define a base sponge, and a scalar sponge. Both must be instantiated when verifying a proof (this is due to recursion-support baked in Kimchi). -External users of kimchi (or pickles) are most likely to interact with a wrap proof (see the [pickles specification](./pickles.md)). +External users of kimchi (or pickles) are most likely to interact with a wrap proof (see the [pickles specification](./pickles.md)). As such, the sponges they need to instantiate are most likely to be instantiated with: * Poseidon-Fp for base sponge -* Poseidon-Fq for the scalar sponge +* Poseidon-Fq for the scalar sponge ### Base Sponge * `new(params) -> BaseSponge`. Creates a new base sponge. * `BaseSponge.absorb(field_element)`. Absorbs a field element by calling the underlying sponge `absorb` function. * `BaseSponge.absorb_point(point)`. Absorbs an elliptic curve point. If the point is the point at infinity, absorb two zeros. Otherwise, absorb the x and y coordinates with two calls to `absorb`. -* `BaseSponge.absorb_scalar(field_element_of_scalar_field)`. Absorbs a scalar. +* `BaseSponge.absorb_scalar(field_element_of_scalar_field)`. Absorbs a scalar. * If the scalar field is smaller than the base field (e.g. Fp is smaller than Fq), then the scalar is casted to a field element of the base field and absorbed via `absorb`. * Otherwise, the value is split between its least significant bit and the rest. Then both values are casted to field elements of the base field and absorbed via `absorb` (the high bits first, then the low bit). * `BaseSponge.digest() -> field_element`. The `squeeze` function of the underlying sponge function is called and the first field element is returned. -* `BaseSponge.digest_scalar() -> field_element_of_scalar_field`. -* `BaseSponge.challenge // TODO: specify`. -* `BaseSponge.challenge_fq // TODO: specify`. +* `BaseSponge.digest_scalar() -> field_element_of_scalar_field`. +* `BaseSponge.challenge // TODO: specify`. +* `BaseSponge.challenge_fq // TODO: specify`. ### Scalar Sponge @@ -64,7 +64,7 @@ def apply_mds(state): n[1] = state[0] * mds[1][0] + state[1] * mds[1][1] + state[2] * mds[1][2] n[2] = state[0] * mds[2][0] + state[1] * mds[2][1] + state[2] * mds[2][2] return n - + # a round in the permutation def apply_round(round, state): # sbox @@ -89,9 +89,9 @@ def permutation(state): state[1] += constant[1] state[2] += constant[2] round_offset = 1 - + for round in range(round_offset, ROUNDS + round_offset): - apply_round(round, state) + apply_round(round, state) ``` ### Sponge @@ -115,7 +115,7 @@ def absorb(sponge, field_element): elif sponge.offset == RATE: sponge.state = permutation(sponge.state) sponge.offset = 0 - + # absorb by adding to the state sponge.state[sponge.offset] += field_element sponge.offset += 1 diff --git a/book/src/specs/urs.md b/book/src/specs/urs.md index 83dfa635c1..dd63174520 100644 --- a/book/src/specs/urs.md +++ b/book/src/specs/urs.md @@ -2,7 +2,7 @@ ```admonish Note that the URS is called SRS in our codebase at the moment. -SRS is incorrect, as it is used in the presence of a trusted setup (which kimchi does not have). +SRS is incorrect, as it is used in the presence of a trusted setup (which kimchi does not have). This needs to be fixed. ``` @@ -68,7 +68,7 @@ TODO: specify the encoding ### Vesta -**`Gs`**. +**`Gs`**. ``` G0 = (x=121C4426885FD5A9701385AAF8D43E52E7660F1FC5AFC5F6468CC55312FC60F8, y=21B439C01247EA3518C5DDEB324E4CB108AF617780DDF766D96D3FD8AB028B70) From 82236b9c6ffec73e17a96e82aa9d35e7dbd794b6 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 29 Nov 2023 18:51:57 +0100 Subject: [PATCH 03/15] Lookup: be more explicit --- book/src/kimchi/lookup.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/book/src/kimchi/lookup.md b/book/src/kimchi/lookup.md index bab15b1d75..c0faf0ff7a 100644 --- a/book/src/kimchi/lookup.md +++ b/book/src/kimchi/lookup.md @@ -29,10 +29,21 @@ Essentially, plookup proves that all the elements in $f$ are indeed in the looku * $\{(1+\beta)f, \text{diff}(t)\}$ * $\text{diff}(\text{sorted}(f, t))$ -where $\text{diff}$ is a new set derived by applying a "randomized difference" between every successive pairs of a vector. For example: +where $\text{diff}$ is a new set derived by applying a "randomized difference" +between every successive pairs of a vector, and $(f, t)$ is the set union of $f$ +et $t$. + +More precisely, for a set $S = +\{s_{0}, s_{1}, \cdots, s_{n} \}$, $\text{diff}(S)$ is defined as the set +$\{s_{0} + \beta s_{1}, s_{1} + \beta s_{2}, \cdots, s_{n - 1} + \beta s_{n}\}$. + +For example, with: * $f = \{5, 4, 1, 5\}$ * $t = \{1, 4, 5\}$ + +we have: +* $\text{sorted}(f,t) = \{1, 1, 4, 4, 5, 5, 5\}$ * $\{\color{blue}{(1+\beta)f}, \color{green}{\text{diff}(t)}\} = \{\color{blue}{(1+\beta)5, (1+\beta)4, (1+\beta)1, (1+\beta)5}, \color{green}{1+\beta 4, 4+\beta 5}\}$ * $\text{diff}(\text{sorted}(f, t)) = \{1+\beta 1, 1+\beta 4, 4+\beta 4, 4+\beta 5, 5+\beta 5, 5+\beta 5\}$ From 279c384af5b19489661bd8259e674ff1c1fc55ca Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 29 Nov 2023 18:53:54 +0100 Subject: [PATCH 04/15] Add plookup macro --- book/macros.txt | 1 + book/src/plonk/plookup.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/book/macros.txt b/book/macros.txt index ff5d96db6e..52977782b5 100644 --- a/book/macros.txt +++ b/book/macros.txt @@ -65,3 +65,4 @@ \prg:{\small \mathsf{PRG}} \plonk:\textsf{Plonk} +\plookup:\textsf{Plookup} diff --git a/book/src/plonk/plookup.md b/book/src/plonk/plookup.md index 23466337e0..a0f83e22ea 100644 --- a/book/src/plonk/plookup.md +++ b/book/src/plonk/plookup.md @@ -1,6 +1,6 @@ -# Plookup +# $\plookup$ -Plookup allows us to check if witness values belong to a look up table. This is usualy useful for reducing the number of constraints needed for bit-wise operations. So in the rest of this document we'll use the XOR table as an example. +$\plookup$ allows us to check if witness values belong to a look up table. This is usualy useful for reducing the number of constraints needed for bit-wise operations. So in the rest of this document we'll use the XOR table as an example. ![XOR table](../img/xor.png) From 22b08d2200a935018f1c118914a0c4d0a4bc79ae Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 29 Nov 2023 18:55:35 +0100 Subject: [PATCH 05/15] Unify Plookup --- book/src/kimchi/lookup.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/book/src/kimchi/lookup.md b/book/src/kimchi/lookup.md index c0faf0ff7a..f3d980cde0 100644 --- a/book/src/kimchi/lookup.md +++ b/book/src/kimchi/lookup.md @@ -1,12 +1,12 @@ -# Plookup in Kimchi +# $\plookup$ in Kimchi -In 2020, [plookup](https://eprint.iacr.org/2020/315.pdf) showed how to create lookup proofs. Proofs that some witness values are part of a [lookup table](https://en.wikipedia.org/wiki/Lookup_table). Two years later, an independent team published [plonkup](https://eprint.iacr.org/2022/086) showing how to integrate Plookup into $\plonk$. +In 2020, [$\plookup$](https://eprint.iacr.org/2020/315.pdf) showed how to create lookup proofs. Proofs that some witness values are part of a [lookup table](https://en.wikipedia.org/wiki/Lookup_table). Two years later, an independent team published [plonkup](https://eprint.iacr.org/2022/086) showing how to integrate $\plookup$ into $\plonk$. -This document specifies how we integrate plookup in kimchi. It assumes that the reader understands the basics behind plookup. +This document specifies how we integrate $\plookup$ in kimchi. It assumes that the reader understands the basics behind $\plookup$. ## Overview -We integrate plookup in kimchi with the following differences: +We integrate $\plookup$ in kimchi with the following differences: * we snake-ify the sorted table instead of wrapping it around (see later) * we allow fixed-ahead-of-time linear combinations of columns of the queries we make @@ -16,15 +16,15 @@ We integrate plookup in kimchi with the following differences: The following document explains the protocol in more detail -### Recap on the grand product argument of plookup +### Recap on the grand product argument of $\plookup$ -As per the Plookup paper, the prover will have to compute three vectors: +As per the $\plookup$ paper, the prover will have to compute three vectors: * $f$, the (secret) **query vector**, containing the witness values that the prover wants to prove are part of the lookup table. * $t$, the (public) **lookup table**. * $s$, the (secret) concatenation of $f$ and $t$, sorted by $t$ (where elements are listed in the order they are listed in $t$). -Essentially, plookup proves that all the elements in $f$ are indeed in the lookup table $t$ if and only if the following multisets are equal: +Essentially, $\plookup$ proves that all the elements in $f$ are indeed in the lookup table $t$ if and only if the following multisets are equal: * $\{(1+\beta)f, \text{diff}(t)\}$ * $\text{diff}(\text{sorted}(f, t))$ @@ -58,13 +58,13 @@ The equality between the multisets can be proved with the permutation argument o \mathsf{acc}_i = \mathsf{acc}_{i-1} \cdot \frac{(\gamma + (1+\beta) f_{i-1}) \cdot (\gamma + t_{i-1} + \beta t_i)}{(\gamma + s_{i-1} + \beta s_{i})(\gamma + s_{n+i-1} + \beta s_{n+i})} $$ -Note that the plookup paper uses a slightly different equation to make the proof work. It is possible that the proof would work with the above equation, but for simplicity let's just use the equation published in plookup: +Note that the $\plookup$ paper uses a slightly different equation to make the proof work. It is possible that the proof would work with the above equation, but for simplicity let's just use the equation published in $\plookup$: $$ \mathsf{acc}_i = \mathsf{acc}_{i-1} \cdot \frac{(1+\beta) \cdot (\gamma + f_{i-1}) \cdot (\gamma(1 + \beta) + t_{i-1} + \beta t_i)}{(\gamma(1+\beta) + s_{i-1} + \beta s_{i})(\gamma(1+\beta) + s_{n+i-1} + \beta s_{n+i})} $$ -> Note: in plookup $s$ is longer than $n$ ($|s| = |f| + |t|$), and thus it needs to be split into multiple vectors to enforce the constraint at every $i \in [[0;n]]$. This leads to the two terms in the denominator as shown above, so that the degree of $\gamma (1 + \beta)$ is equal in the nominator and denominator. +> Note: in $\plookup$ $s$ is longer than $n$ ($|s| = |f| + |t|$), and thus it needs to be split into multiple vectors to enforce the constraint at every $i \in [[0;n]]$. This leads to the two terms in the denominator as shown above, so that the degree of $\gamma (1 + \beta)$ is equal in the nominator and denominator. ### Lookup tables @@ -84,7 +84,7 @@ Note: the $(0, 0, 0)$ **entry** is at the very end on purpose (as it will be use ### Querying the table -The plookup paper handles a vector of lookups $f$ which we do not have. So the first step is to create such a table from the witness columns (or registers). To do this, we define the following objects: +The $\plookup$ paper handles a vector of lookups $f$ which we do not have. So the first step is to create such a table from the witness columns (or registers). To do this, we define the following objects: * a **query** tells us what registers, in what order, and scaled by how much, are part of a query * a **query selector** tells us which rows are using the query. It is pretty much the same as a [gate selector](). @@ -245,11 +245,11 @@ which is equivalent to checking that $h_1(g^{n-1}) = h_2(1)$. ## The sorted vector $s$ in kimchi -Since this vector is known only by the prover, and is evaluated as part of the protocol, zero-knowledge must be added to the corresponding polynomial (in case of plookup approach, to $h_1(X),h_2(X)$). To do this in kimchi, we use the same technique as with the other prover polynomials: we randomize the last evaluations (or rows, on the domain) of the polynomial. +Since this vector is known only by the prover, and is evaluated as part of the protocol, zero-knowledge must be added to the corresponding polynomial (in case of $\plookup$ approach, to $h_1(X),h_2(X)$). To do this in kimchi, we use the same technique as with the other prover polynomials: we randomize the last evaluations (or rows, on the domain) of the polynomial. This means two things for the lookup grand product argument: -1. We cannot use the wrap around trick to make sure that the list is split in two correctly (enforced by $L_{n-1}(h_1(x) - h_2(g \cdot x)) = 0$ which is equivalent to $h_1(g^{n-1}) = h_2(1)$ in the plookup paper) +1. We cannot use the wrap around trick to make sure that the list is split in two correctly (enforced by $L_{n-1}(h_1(x) - h_2(g \cdot x)) = 0$ which is equivalent to $h_1(g^{n-1}) = h_2(1)$ in the $\plookup$ paper) 2. We have even less space to store an entire query vector. Which is actually super correct, as the witness also has some zero-knowledge rows at the end that should not be part of the queries anyway. The first problem can be solved in two ways: From 8533c2902c76419b2a1b6a359e1fbdae969f36b6 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 29 Nov 2023 18:56:22 +0100 Subject: [PATCH 06/15] Fix typo --- book/src/kimchi/lookup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/kimchi/lookup.md b/book/src/kimchi/lookup.md index f3d980cde0..a17602efa4 100644 --- a/book/src/kimchi/lookup.md +++ b/book/src/kimchi/lookup.md @@ -97,7 +97,7 @@ For example, the following **query** tells us that we want to check if $r_0 \opl | :---: | :---: | :---: | | 1, $r_0$ | 1, $r_2$ | 2, $r_1$ | -The grand product argument for the lookup consraint will look like this at this point: +The grand product argument for the lookup constraint will look like this at this point: $$ \mathsf{acc}_i = \mathsf{acc}_{i-1} \cdot \frac{(1+\beta) \cdot {\color{green}(\gamma + w_0(g^i) + j \cdot w_2(g^i) + j^2 \cdot 2 \cdot w_1(g^i))} \cdot (\gamma(1 + \beta) + t_{i-1} + \beta t_i)}{(\gamma(1+\beta) + s_{i-1} + \beta s_{i})(\gamma(1+\beta) + s_{n+i-1} + \beta s_{n+i})} From 3bc6fff1a7f1403f279b0e0ef7f9b1d2d4b15b40 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 3 May 2023 18:44:59 +0200 Subject: [PATCH 07/15] Book: overview - fix equations rendering --- book/src/kimchi/overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/kimchi/overview.md b/book/src/kimchi/overview.md index 740acd763d..74b290bc7a 100644 --- a/book/src/kimchi/overview.md +++ b/book/src/kimchi/overview.md @@ -45,10 +45,10 @@ So what is the simplest way one could think of to perform this one-time check? P So instead, we can multiply each term in the sum by a random number. The reason why this trick works is the independence between random numbers. That is, if two different polynomials $f(X)$ and $g(X)$ are both equal to zero on a given $X=x$, then with very high probability the same $x$ will be a root of the random combination $\alpha\cdot f(x) + \beta\cdot g(x) = 0$. If applied to the whole statement, we could transform the $n$ equations into a single equation, -$$\bigwedge_{i_n} p_i(X) =_? 0 \iff_{w.h.p.} \sum_{i=0}^{n} \rho_i \cdot p_i(X) =_? 0 $$ +$$\bigwedge_{i_n} p_i(X) =_? 0 \Leftrightarrow_{w.h.p.} \sum_{i=0}^{n} \rho_i \cdot p_i(X) =_? 0$$ This sounds great so far. But we are forgetting about an important part of proof systems which is proof length. For the above claim to be sound, the random values used for aggregation should be verifier-chosen, or at least prover-independent. So if the verifier had to communicate with the prover to inform about the random values being used, we would get an overhead of $n$ field elements. Instead, we take advantage of another technique that is called **powers-of-alpha**. Here, we make the assumption that powers of a random value $\alpha^i$ are indistinguishable from actual random values $\rho_i$. Then, we can twist the above claim to use only one random element $\alpha$ to be agreed with the prover as: -$$\bigwedge_{i_n} p_i(X) =_? 0 \iff_{w.h.p.} \sum_{i=0}^{n} \alpha^i \cdot p_i(X) =_? 0 $$ +$$\bigwedge_{i_n} p_i(X) =_? 0 \Leftrightarrow_{w.h.p.} \sum_{i=0}^{n} \alpha^i \cdot p_i(X) =_? 0$$ From b18297a3088c613053d21ab503fb418869290bc5 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 3 May 2023 18:53:41 +0200 Subject: [PATCH 08/15] Book: replace XOR table image with markdown table --- book/src/img/xor.png | Bin 14458 -> 0 bytes book/src/plonk/plookup.md | 9 ++++++++- 2 files changed, 8 insertions(+), 1 deletion(-) delete mode 100644 book/src/img/xor.png diff --git a/book/src/img/xor.png b/book/src/img/xor.png deleted file mode 100644 index 28fb7ae536fd296f01fd1b9e4a2a80faa17ddace..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14458 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 Utvd_IV9yY;Qi_rV;)a3$120%UBLDyZ diff --git a/book/src/plonk/plookup.md b/book/src/plonk/plookup.md index a0f83e22ea..34117c2588 100644 --- a/book/src/plonk/plookup.md +++ b/book/src/plonk/plookup.md @@ -2,7 +2,14 @@ $\plookup$ allows us to check if witness values belong to a look up table. This is usualy useful for reducing the number of constraints needed for bit-wise operations. So in the rest of this document we'll use the XOR table as an example. -![XOR table](../img/xor.png) + +| A | B | Y | +| --- | --- | --- | +| 0 | 0 | 0 | +| 0 | 1 | 1 | +| 1 | 0 | 1 | +| 1 | 1 | 0 | + First, let's define some terms: From 4a346ff53fcc4a5cc5750272494c7ade5fcdba0a Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 3 May 2023 21:38:43 +0200 Subject: [PATCH 09/15] Doc: link to page Arguments in kimchi book --- kimchi/src/circuits/argument.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/kimchi/src/circuits/argument.rs b/kimchi/src/circuits/argument.rs index 9ed50a3203..17c8cb0bee 100644 --- a/kimchi/src/circuits/argument.rs +++ b/kimchi/src/circuits/argument.rs @@ -3,6 +3,7 @@ //! Both the permutation and the plookup arguments fit this type. //! Gates can be seen as filtered arguments, //! which apply only in some points (rows) of the domain. +//! For more info, read book/kimchi/src/kimchi/arguments.md use std::marker::PhantomData; From 3096d3592e21fe47d6049cb38cef41a9c4184975 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 4 May 2023 17:54:31 +0200 Subject: [PATCH 10/15] README: add documentation about rustdoc generation --- .github/workflows/gh-page.yml | 1 + README.md | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/.github/workflows/gh-page.yml b/.github/workflows/gh-page.yml index 987b27ce2a..feb789d31d 100644 --- a/.github/workflows/gh-page.yml +++ b/.github/workflows/gh-page.yml @@ -41,6 +41,7 @@ jobs: # https://github.com/ocaml/setup-ocaml/issues/211#issuecomment-1058882386 # disable-cache: true + # This must be the same than in the section "Generate rustdoc locally" in the README.md - name: Build Rust Documentation run: | eval $(opam env) diff --git a/README.md b/README.md index a2ce1f6e90..b7bd7f6dee 100644 --- a/README.md +++ b/README.md @@ -60,3 +60,24 @@ The project is organized in the following way: ## Contributing Check [CONTRIBUTING.md](CONTRIBUTING.md) if you are interested in contributing to this project. + +## Generate rustdoc locally + +An effort is made to have the documentation being self-explained, referring to the mina book for more details when necessary. +You can build the rust documentation with + +``` +rustup install nightly +RUSTDOCFLAGS="--enable-index-page -Zunstable-options" cargo +nightly doc --all --no-deps +``` + +You can visualize the documentation by opening the file `target/doc/index.html`. + +## CI + + +The CI will build different targets. +- [Deploy Specifications & Docs to GitHub Pages](.github/workflows/gh-page.yml). + When CI passes on master, the documentation built from the rust code will be + available [here](https://o1-labs.github.io/proof-systems/rustdoc) and the book + will be available [here](https://o1-labs.github.io/proof-systems). From 233c5b10fc89ead58be1161f72faf8e03bd7028d Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 4 May 2023 19:00:52 +0200 Subject: [PATCH 11/15] Book: add runtime tables in specifications --- book/specifications/kimchi/Specification.toml | 1 + book/specifications/kimchi/template.md | 6 ++++++ book/src/specs/kimchi.md | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/book/specifications/kimchi/Specification.toml b/book/specifications/kimchi/Specification.toml index 7ec3ec05fa..01b51bd184 100644 --- a/book/specifications/kimchi/Specification.toml +++ b/book/specifications/kimchi/Specification.toml @@ -32,6 +32,7 @@ table_xor = "../../../kimchi/src/circuits/lookup/tables/xor.rs" table_12bit = "../../../kimchi/src/circuits/lookup/tables/range_check.rs" lookup = "../../../kimchi/src/circuits/lookup/constraints.rs" lookup_index = "../../../kimchi/src/circuits/lookup/index.rs" +runtime_tables = "../../../kimchi/src/circuits/lookup/runtime_tables.rs" # setup constraint_system = "../../../kimchi/src/circuits/constraints.rs" diff --git a/book/specifications/kimchi/template.md b/book/specifications/kimchi/template.md index 663a498b31..d96f745b8d 100644 --- a/book/specifications/kimchi/template.md +++ b/book/specifications/kimchi/template.md @@ -213,6 +213,12 @@ Kimchi currently supports two lookup tables: {sections.table_12bit} +##### Runtime tables + +Another type of lookup tables have been suggested in the [Extended Lookup tables RFC](../rfcs/extended-lookup-tables.md). + +{sections.runtime_tables} + #### The Lookup Selectors **XorSelector**. Performs 4 queries to the XOR lookup table. diff --git a/book/src/specs/kimchi.md b/book/src/specs/kimchi.md index 842ecbb171..8a8628ba1c 100644 --- a/book/src/specs/kimchi.md +++ b/book/src/specs/kimchi.md @@ -367,6 +367,12 @@ The range check table is a single-column table containing the numbers from 0 to This is used to check that the value fits in 12 bits. +##### Runtime tables + +Another type of lookup tables have been suggested in the [Extended Lookup tables RFC](../rfcs/extended-lookup-tables.md). + + + #### The Lookup Selectors **XorSelector**. Performs 4 queries to the XOR lookup table. From a2b54ef80509903eac469225a76a4935d81739ed Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 29 Nov 2023 19:04:00 +0100 Subject: [PATCH 12/15] Fix build warning Warnings when RUSTDOCFLAGS="--enable-index-page -Zunstable-options" cargo +nightly doc --all --no-deps --- kimchi/src/circuits/argument.rs | 2 +- kimchi/src/circuits/constraints.rs | 4 ++-- kimchi/src/circuits/lookup/runtime_tables.rs | 3 +++ kimchi/src/circuits/polynomials/turshi.rs | 14 +++++++------- signer/src/pubkey.rs | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/kimchi/src/circuits/argument.rs b/kimchi/src/circuits/argument.rs index 17c8cb0bee..281468624d 100644 --- a/kimchi/src/circuits/argument.rs +++ b/kimchi/src/circuits/argument.rs @@ -33,7 +33,7 @@ pub enum ArgumentType { /// The argument environment is used to specify how the argument's constraints are /// represented when they are built. If the environment is created without ArgumentData -/// and with F = Expr, then the constraints are built as Expr expressions (e.g. for +/// and with `F = Expr`, then the constraints are built as Expr expressions (e.g. for /// use with the prover/verifier). On the other hand, if the environment is /// created with ArgumentData and F = Field or F = PrimeField, then the constraints /// are built as expressions of real field elements and can be evaluated directly on diff --git a/kimchi/src/circuits/constraints.rs b/kimchi/src/circuits/constraints.rs index 115a696965..78e1102ec1 100644 --- a/kimchi/src/circuits/constraints.rs +++ b/kimchi/src/circuits/constraints.rs @@ -229,8 +229,8 @@ pub fn selector_polynomial( } impl ConstraintSystem { - /// Initializes the [ConstraintSystem] on input `gates` and `fr_sponge_params`. - /// Returns a [Builder] + /// Initializes the [`ConstraintSystem`] on input `gates` and `fr_sponge_params`. + /// Returns a [`Builder`] /// It also defaults to the following values of the builder: /// - `public: 0` /// - `prev_challenges: 0` diff --git a/kimchi/src/circuits/lookup/runtime_tables.rs b/kimchi/src/circuits/lookup/runtime_tables.rs index f8123d75d8..ef2d9f7d15 100644 --- a/kimchi/src/circuits/lookup/runtime_tables.rs +++ b/kimchi/src/circuits/lookup/runtime_tables.rs @@ -2,7 +2,10 @@ //! The setup has to prepare for their presence using [`RuntimeTableCfg`]. //! At proving time, the prover can use [`RuntimeTable`] to specify the actual tables. +// TODO: write cargo specifications + use crate::circuits::{berkeley_columns::Column, expr::prologue::*, gate::CurrOrNext}; + use ark_ff::Field; use serde::{Deserialize, Serialize}; diff --git a/kimchi/src/circuits/polynomials/turshi.rs b/kimchi/src/circuits/polynomials/turshi.rs index 645e5649c1..16285d4793 100644 --- a/kimchi/src/circuits/polynomials/turshi.rs +++ b/kimchi/src/circuits/polynomials/turshi.rs @@ -9,15 +9,15 @@ //! · \[reg0 + off_op0\] +|* val //! · \[\[reg0 + off_op0\] + off_op1\] //! - Jumps -//! · jmp abs
// unconditional absolute jump -//! · jmp rel // unconditional relative jump -//! · jmp rel if != 0 // conditional jump +//! · jmp abs <`address`> // unconditional absolute jump +//! · jmp rel <`offset`> // unconditional relative jump +//! · jmp rel <`offset`> if <`op`> != 0 // conditional jump //! - Functions -//! · call abs
// calls a function (absolute location) -//! · call rel // calls a function (relative location) +//! · call abs <`address`> // calls a function (absolute location) +//! · call rel <`offset`> // calls a function (relative location) //! · ret // returns to execution after the call //! - Increments -//! · ap += +//! · ap += <`op`> //! · ap++ //! //! A Cairo program runs accross a number of state transitions. @@ -63,7 +63,7 @@ //! · 4 = conditional jump (jnz) with step in op1 = `fPC_JNZ` = 1 //! - `ap_update` \[10..11\]: defines the type of update for the ap //! · 0: means the new ap is the same, same free position -//! · 1: means there is an ap+= instruction = `fAP_INC` = 1 +//! · 1: means there is an ap+=<`op`> instruction = `fAP_INC` = 1 //! · 2: means there is an ap++ instruction = `fAP_ADD1` = 1 //! - opcode \[12..14\]: encodes type of assembly instruction //! · 0: jumps or increments instruction diff --git a/signer/src/pubkey.rs b/signer/src/pubkey.rs index 9a52f39494..05a84325f6 100644 --- a/signer/src/pubkey.rs +++ b/signer/src/pubkey.rs @@ -311,7 +311,7 @@ impl CompressedPubKey { } /// The empty [`CompressedPubKey`] value that is used as `public_key` in empty account - /// and [None] value for calculating the hash of [Option], etc. + /// and [None] value for calculating the hash of [`Option`], etc. pub fn empty() -> Self { Self { x: BaseField::zero(), From 1db361d3b7cc5a5eecdca985326598968948d3bc Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 4 May 2023 19:03:27 +0200 Subject: [PATCH 13/15] Book: add missing markdownlint-cli to build specifications --- book/specifications/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/book/specifications/README.md b/book/specifications/README.md index 820421c678..0afc221331 100644 --- a/book/specifications/README.md +++ b/book/specifications/README.md @@ -15,6 +15,11 @@ Install cargo-spec: $ cargo install cargo-spec ``` +You will also need markdownlint: +```console +$ npm install markdownlint-cli -g +``` + ## Render To produce a specification, simply run the following command: From b27d13b0bf8779b30bca58b7480a56ead7ea70d7 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 4 May 2023 19:05:08 +0200 Subject: [PATCH 14/15] Book: add make clean for mina book --- book/Makefile | 7 +++++++ book/README.md | 2 ++ 2 files changed, 9 insertions(+) diff --git a/book/Makefile b/book/Makefile index 893ebc857d..d2014378fc 100644 --- a/book/Makefile +++ b/book/Makefile @@ -49,3 +49,10 @@ all: check build: check mdbook build + +# +# use `make clean` to clean the generated artefacts +# + +clean: + mdbook clean diff --git a/book/README.md b/book/README.md index 63568c6b6c..335426c0dc 100644 --- a/book/README.md +++ b/book/README.md @@ -9,6 +9,8 @@ $ # install dependencies $ make deps $ # serve the page locally $ make +$ # clean +$ make clean ``` The specifications in the book are dynamically generated. Refer to the [specifications/](specifications/) directory. From ddfe1ef6a9037a52b8e30e4fd8e9ecad7d4c3462 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 30 Nov 2023 00:49:26 +0100 Subject: [PATCH 15/15] Use mathcal for PlonK as the initial paper --- book/macros.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/macros.txt b/book/macros.txt index 52977782b5..5b70331d89 100644 --- a/book/macros.txt +++ b/book/macros.txt @@ -64,5 +64,5 @@ \counter:{\mathsf{counter}} \prg:{\small \mathsf{PRG}} -\plonk:\textsf{Plonk} +\plonk:\mathcal{PlonK} \plookup:\textsf{Plookup}