From f46270cec15695da20d3aa1ac03a47bd17fd6af5 Mon Sep 17 00:00:00 2001 From: Shvier Date: Wed, 4 Dec 2024 21:15:56 +0000 Subject: [PATCH] Publishing Site plonkbook.org at 708d6b4e3f32131a3cb06cce3b09f6b69ea63969 on Wed Dec 4 21:15:56 UTC 2024 --- 404.html | 2 +- categories/index.html | 2 +- docs/background/index.html | 2 +- docs/background/index.xml | 4 ++-- docs/background/kzg/index.html | 6 ++--- docs/background/overview/index.html | 12 +++++----- docs/background/poly-iop/index.html | 24 ++++++++----------- docs/background/proofs/index.html | 2 +- docs/background/red-tape/index.html | 2 +- docs/gadgets/add1/index.html | 8 +++---- docs/gadgets/add2/index.html | 8 +++---- docs/gadgets/add3/index.html | 6 ++--- docs/gadgets/circuit/index.html | 4 ++-- docs/gadgets/concat/index.html | 4 ++-- docs/gadgets/encode/index.html | 8 +++---- docs/gadgets/folding/index.html | 2 +- docs/gadgets/index.html | 2 +- docs/gadgets/lookup1/index.html | 4 ++-- docs/gadgets/lookup2/index.html | 4 ++-- docs/gadgets/mult1/index.html | 6 ++--- docs/gadgets/mult2/index.html | 8 +++---- docs/gadgets/mult3/index.html | 8 +++---- docs/gadgets/range/index.html | 2 +- docs/gadgets/rotate/index.html | 10 ++++---- docs/gadgets/shuffle1/index.html | 8 +++---- docs/gadgets/shuffle2/index.html | 10 ++++---- docs/gadgets/zero1/index.html | 2 +- docs/gadgets/zero2/index.html | 2 +- docs/index.html | 2 +- ...615cc3f20ff8f3d6f8d5568a0c4e9a152148e.json | 1 + ...fd93ab5120cfadab575f568dd98af79163e5d.json | 1 - ...712e961b005f4a45bd23c3f3136bb08fbd20177.js | 2 +- index.html | 2 +- index.xml | 4 ++-- tags/index.html | 2 +- 35 files changed, 86 insertions(+), 90 deletions(-) create mode 100644 en.search-data.min.095fef5514cefcc621486d2d6eb615cc3f20ff8f3d6f8d5568a0c4e9a152148e.json delete mode 100644 en.search-data.min.b3da462909c11499509a5595d9bfd93ab5120cfadab575f568dd98af79163e5d.json rename en.search.min.6ec6eba6938494757b9fe5011c54cba2af69700e962f29d208fa6852b65853ab.js => en.search.min.bc63bd6cafeda2b6b745976a2712e961b005f4a45bd23c3f3136bb08fbd20177.js (90%) diff --git a/404.html b/404.html index ec354e5..c33c36d 100644 --- a/404.html +++ b/404.html @@ -1,2 +1,2 @@ 404 Page not found | Handbook -

404

Page Not Found

Handbook

\ No newline at end of file +

404

Page Not Found

Handbook

\ No newline at end of file diff --git a/categories/index.html b/categories/index.html index 14f14b8..8303440 100644 --- a/categories/index.html +++ b/categories/index.html @@ -1,5 +1,5 @@ Categories | Handbook - +
Categories
\ No newline at end of file diff --git a/docs/background/index.html b/docs/background/index.html index 380874e..a0f590d 100644 --- a/docs/background/index.html +++ b/docs/background/index.html @@ -1,5 +1,5 @@ Background | Handbook - +
Background

Select a background topic from the menu.

\ No newline at end of file diff --git a/docs/background/index.xml b/docs/background/index.xml index 466d1b3..2425eab 100644 --- a/docs/background/index.xml +++ b/docs/background/index.xml @@ -1,6 +1,6 @@ Handbookhttp://plonkbook.org/docs/background/Recent content on HandbookHugoen-usOverviewhttp://plonkbook.org/docs/background/overview/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/overview/Overview # Preliminaries # While we may add more background in future iterations, for now we punt on explaining the following concepts and assume you are already familiar with them: -Elliptic curve cryptography Hardness of the discrete logarithm problem and related problems Pairing-based cryptography at a “black-box” level (what it does, not necessarily how it works) Resources: Lecture (Boneh) Commitment schemes Properties: hiding and binding Construction: Pedersen Commitments Resources: Lecture (Boneh) Zero knowledge proofs (high level idea) Properities: completeness, soundness, zero-knowledge Resources: Lecture (Goldwasser) zk-SNARKs # Plonk is a zk-SNARK proof system.PCShttp://plonkbook.org/docs/background/kzg/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/kzg/Polynomial Commitment Schemes (PCS) # Comparing Polynomials # Say that Carol sends a polynomial to Alice and the same polynomial to Bob. Later Alice and Bob are sitting together and want to make sure their polynomials, which they got from Carol, are actually the same. How do you compare polynomials? There are many sufficient comparisons, but here are two ways to get started: -Ensure the degree $d$ is the same and each coefficient is the same, Ensure the degree $d$ is the same and check at $d+1$ unique points.Polynomialshttp://plonkbook.org/docs/background/poly-iop/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/poly-iop/Polynomials # All the gadgets in Plonkbook follow the same high level model, called a polynomial interactive proof (Poly-IOP). Each gadget is defined as an operation on one or more arrays of data. The arrays are encoded into a univariate polynomial (see below) and the polynomial is committed to (next background section) and passed to the verifier. The verifier works with commitments and sees that operations on commitments are mirroring a set of operations being done on the polynomials themselves.Proofshttp://plonkbook.org/docs/background/proofs/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/proofs/Security Proofs # To be added. +Elliptic curve cryptography Hardness of the discrete logarithm problem and related problems Pairing-based cryptography at a “black-box” level (what it does, not necessarily how it works) Resources: Lecture (Boneh) Commitment schemes Properties: hiding and binding Construction: Pedersen Commitments Resources: Lecture (Boneh) Zero knowledge proofs (high level idea) Properties: completeness, soundness, zero-knowledge Resources: Lecture (Goldwasser) zk-SNARKs # Plonk is a zk-SNARK proof system.PCShttp://plonkbook.org/docs/background/kzg/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/kzg/Polynomial Commitment Schemes (PCS) # Comparing Polynomials # Say that Carol sends a polynomial to Alice and the same polynomial to Bob. Later Alice and Bob are sitting together and want to make sure their polynomials, which they got from Carol, are actually the same. How do you compare polynomials? There are many sufficient comparisons, but here are two ways to get started: +Ensure the degree $d$ is the same and each coefficient is the same, Ensure the degree $d$ is the same and check at $d+1$ unique points.Polynomialshttp://plonkbook.org/docs/background/poly-iop/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/poly-iop/Polynomials # All the gadgets in Plonkbook follow the same high level model, called a polynomial interactive oracle proof (Poly-IOP). Each gadget is defined as an operation on one or more arrays of data. The arrays are encoded into a univariate polynomial (see below) and the polynomial is committed to (next background section) and passed to the verifier. The verifier works with commitments and sees that operations on commitments are mirroring a set of operations being done on the polynomials themselves.Proofshttp://plonkbook.org/docs/background/proofs/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/proofs/Security Proofs # To be added. Definitions # Definition 1 (Polynomial Commitment Scheme). A polynomial commitment scheme (PCS) is an interactive proof system that enables $\mathcal{P}$ to convince $\mathcal{V}$ that he knows a polynomial, without revealing the polynomial directly. $\mathcal{P}$ and $\mathcal{V}$ run the protocol in three moves: gen, com, and open. [Plonk] Definition 2 (Polynomial IOP). Let $\mathcal{R}$ be a set of the relations among polynomials $\{P_i\}$. Let $\mathcal{C}_f$ is the commitment to $f$.Red Tapehttp://plonkbook.org/docs/background/red-tape/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/red-tape/Red Tape # Generally speaking, the gadgets are quite flexible and work well as defined. However there are some subtle issues to pay attention to when using them. Max array size # Arrays can be very large but encoding points into a multiplicative domain (using roots of unity) means a root of unity must exist that is the same or larger than the array size. A domain of size $\kappa$ exists only if $\kappa$ divides $q-1$, where $q$ is the modulus that applies to exponents in the elliptic curve. \ No newline at end of file diff --git a/docs/background/kzg/index.html b/docs/background/kzg/index.html index 0105033..7d48d43 100644 --- a/docs/background/kzg/index.html +++ b/docs/background/kzg/index.html @@ -1,7 +1,7 @@ PCS | Handbook - +
PCS

Polynomial Commitment Schemes (PCS) @@ -11,7 +11,7 @@ #

Starting Point #

KZG commitments will commit to a univariate polynomial assuming it is in coefficient form. That is:

$$ P(\square)=c_0+c_1\cdot\square+c_2\cdot\square^2+c_3\cdot\square^3+c_4\cdot\square^4=\sum_{i=0}^d c_i\cdot\square^i -$$

The rough idea is that a commitment will be $K_{P(\square)}=\mathsf{Commit}(P(\square), r)=g^{P(\square)}h^r$. For simplicity, we will describe the simpler version that is not hiding: $K_{P(\square)}=\mathsf{Commit}(P(\square))=g^{P(\square)}$.

What does it mean to commit to $P(\square)$ without specifying what $\square$ is? Recall that $\square$ can take on any value (in $\mathbb{Z}_q$). Probably the most intuitive idea is to use the multi-commitment (above) to commit to the coefficients: $\mathsf{Commit}(c_0,c_1,c_2,c_3)=g_0^{c_0}g_1^{c_1}g_2^{c_2}g_3^{c_3}$. This hits a few items on our wish list: it is binding, could be hiding (with $h^r$), is additively homomorphic (sum of polynomials is the sum of their coefficients), and is succinct.

What about selective opening? The committer (prover) knows that $y_\alpha=P(\alpha)$ for some value $\alpha$ and wants to prove it. To work toward computing $P(\alpha)=c_0+c_1\cdot\alpha+c_2\cdot\alpha^2+c_3\cdot\alpha^3$, the prover can create $\langle \alpha, \alpha^2, \alpha^3\rangle$ but can the prover get them into the “right spot” in the commitment: $g_0^{c_0}g_1^{c_1\cdot\alpha}g_2^{c_2\alpha^2}g_3^{c_3\alpha^3}$? It cannot do it with exponentiation as operations like $(g_0^{c_0}g_1^{c_1}g_2^{c_2}g_3^{c_3})^\alpha$ will distribute $\alpha$ to each term: $g_0^{c_0\cdot\alpha}g_1^{c_1\cdot\alpha}g_2^{c_2\cdot\alpha}g_3^{c_3\cdot\alpha}$. Even if it got them into the right spot, the prover would have to prove they used the right values. Finally, the prover cannot “add” the terms up: $g_0^{c_0}g_1^{c_1\cdot\alpha}g_2^{c_2\alpha^2}g_3^{c_3\alpha^3}\rightarrow g_0^{c_0+c_1\cdot\alpha+c_2\alpha^2+c_3\alpha^3}$ without knowing the discrete logarithm between $g_0, g_1, g_2, g_3$ (if it did, it would break the binding property) plus it would have to get rid of the discrete logarithm terms. Anyways, there are three or four roadblocks to adding selective opening to such a commitment.

KZG takes a different approach. To commit to a polynomial, the idea is to commit to its evaluation at a set of points rather than committing to the coefficients. How many points do we need to commit to? Recall the story about Alice and Bob comparing the polynomials they received from Carol. We concluded that statistically it is sufficient for Alice and Bob to check at $1$ random point.

The idea of KZG is to commit to the evaluation of the polynomial at one random point $\tau$ and have this commitment represent a commitment to the entire polynomial. The important caveat is that no one knows what $\tau$ is (it is a secret). How do we pull this off? How can the prover figure out the evaluation of their polynomial at $\tau$ without knowing what $\tau$ is? And finally, if they can figure out what $P(\tau)$ is, can they not just reverse engineer what $\tau$ is (for example, by committing to $y=P(\tau)=\tau$)?

KZG uses a trusted setup to generate a commitment to $\tau$. It then uses homomorphic operations to let a prover compute a commimtent to $P(\tau)$ using the commiment to $\tau$ without learning what $\tau$ is or even what $P(\tau)$ is. Committing to $P(\tau)$ is considered as good as committing to the entire polynomial! We will see these details next.

Setup +$$

The rough idea is that a commitment will be $K_{P(\square)}=\mathsf{Commit}(P(\square), r)=g^{P(\square)}h^r$. For simplicity, we will describe the simpler version that is not hiding: $K_{P(\square)}=\mathsf{Commit}(P(\square))=g^{P(\square)}$.

What does it mean to commit to $P(\square)$ without specifying what $\square$ is? Recall that $\square$ can take on any value (in $\mathbb{Z}_q$). Probably the most intuitive idea is to use the multi-commitment (above) to commit to the coefficients: $\mathsf{Commit}(c_0,c_1,c_2,c_3)=g_0^{c_0}g_1^{c_1}g_2^{c_2}g_3^{c_3}$. This hits a few items on our wish list: it is binding, could be hiding (with $h^r$), is additively homomorphic (sum of polynomials is the sum of their coefficients), and is succinct.

What about selective opening? The committer (prover) knows that $y_\alpha=P(\alpha)$ for some value $\alpha$ and wants to prove it. To work toward computing $P(\alpha)=c_0+c_1\cdot\alpha+c_2\cdot\alpha^2+c_3\cdot\alpha^3$, the prover can create $\langle \alpha, \alpha^2, \alpha^3\rangle$ but can the prover get them into the “right spot” in the commitment: $g_0^{c_0}g_1^{c_1\cdot\alpha}g_2^{c_2\alpha^2}g_3^{c_3\alpha^3}$? It cannot do it with exponentiation as operations like $(g_0^{c_0}g_1^{c_1}g_2^{c_2}g_3^{c_3})^\alpha$ will distribute $\alpha$ to each term: $g_0^{c_0\cdot\alpha}g_1^{c_1\cdot\alpha}g_2^{c_2\cdot\alpha}g_3^{c_3\cdot\alpha}$. Even if it got them into the right spot, the prover would have to prove they used the right values. Finally, the prover cannot “add” the terms up: $g_0^{c_0}g_1^{c_1\cdot\alpha}g_2^{c_2\alpha^2}g_3^{c_3\alpha^3}\rightarrow g_0^{c_0+c_1\cdot\alpha+c_2\alpha^2+c_3\alpha^3}$ without knowing the discrete logarithm between $g_0, g_1, g_2, g_3$ (if it did, it would break the binding property) plus it would have to get rid of the discrete logarithm terms. Anyways, there are three or four roadblocks to adding selective opening to such a commitment.

KZG takes a different approach. To commit to a polynomial, the idea is to commit to its evaluation at a set of points rather than committing to the coefficients. How many points do we need to commit to? Recall the story about Alice and Bob comparing the polynomials they received from Carol. We concluded that statistically it is sufficient for Alice and Bob to check at $1$ random point.

The idea of KZG is to commit to the evaluation of the polynomial at one random point $\tau$ and have this commitment represent a commitment to the entire polynomial. The important caveat is that no one knows what $\tau$ is (it is a secret). How do we pull this off? How can the prover figure out the evaluation of their polynomial at $\tau$ without knowing what $\tau$ is? And finally, if they can figure out what $P(\tau)$ is, can they not just reverse engineer what $\tau$ is (for example, by committing to $y=P(\tau)=\tau$)?

KZG uses a trusted setup to generate a commitment to $\tau$. It then uses homomorphic operations to let a prover compute a commitment to $P(\tau)$ using the commitment to $\tau$ without learning what $\tau$ is or even what $P(\tau)$ is. Committing to $P(\tau)$ is considered as good as committing to the entire polynomial! We will see these details next.

Setup #

Someone trusted chooses a random value (from $\mathbb{Z}_q$) to use as $\tau$. They will also generate $d$ powers of $\tau$ which will be needed to commit to polynomials up to degree $d$. They will commit to each power of $\tau$ as follows. The output is called a structured random string (SRS) and will be available for the prover to use and the verifier to use:

$$ \langle g^{(\tau^0)}, g^{(\tau^1)}, g^{(\tau^2)}, g^{(\tau^3)}, \ldots, g^{(\tau^d)} \rangle \equiv SRS $$

What if the person generating the powers of $\tau$ is not trustworthy? What goes wrong? There are two ways the trusted party can cheat: (1) tell everyone the secret value $\tau$ (or use it for itself), and (2) generate the SRS with the wrong structure (the values are not successive powers of $\tau$). We can address both of these issues. To address (1), we can let many parties generate an SRS and combine them into a single SRS. As long as one party deletes $\tau$ without looking at it, the entire SRS is secure. Many blockchain projects have done this already with thousands of contributors. We can also address (2) through special purpose zero knowledge proofs that demonstrate each contributor’s SRS has the correct format without revealing $\tau$. We will not cover these details but you can learn more from this article (a16z crypto research).

Commitment @@ -43,6 +43,6 @@ \end{align} $$

Notice that the degree of the polynomial $P(\square)$ (and thus $Q(\square)$) has no impact on the size of the proof given to the verifier or the work that the verifier has to do. Even if the degree of $P(\square)$ is billions, the proof is the same size and time for the verifier. In a sense, this is our first special purpose SNARK and one we will leverage into making SNARKs for all the gadgets in Plonkbook.

Selective Open: Multiple Roots #

If the prover wants to open at multiple roots, it runs the exact same protocol but has the verifier set $V(\square)=(\square-r_0)\cdot(\square-r_1)\cdot(\square-r_2)\ldots$ for all the roots it wants to prove. Importantly, this does not add any complexity for the verifier once $K_{V(\tau)}$ has been created.

Selective Open: Arbitrary Point -#

Most of the time, the prover wants to prove the polynomial passes through an arbitrary point $\{x,y\}=\{x,P(x)\}$ where $y$ is some integer that is not zero (and thus $x$ is not a root). Again, this is very easy to prove once we have a protocol for proving roots. The intution is as follows: if and only if $P(\square)$ has value $y$ at point $x$, then subtracting $y$ from $P(\square)$ will create a new polynomial $\tilde{P}(\square)=P(\square)-y$ that is zero at point $x$, making $x$ a root. (Visually you can imagine a polynomial with height $y$ at a point $x$, and subtracting $y$ shifts the whole polynomial down $y$ units, moving that point down to the x-axis.) The verifier can construct $K_{\tilde{P}(\tau)}$ from $K_{P(\tau)}$ using the additive homomorphic property: $K_{\tilde{P}(\tau)}=K_{P(tau)\cdot} g^{-y}$. Then the prover shows $K_{\tilde{P}(\tau)}$ has a root at point $x$ using the protocol above for proving roots.

Selective Open: Batch of Points +#

Most of the time, the prover wants to prove the polynomial passes through an arbitrary point $\{x,y\}=\{x,P(x)\}$ where $y$ is some integer that is not zero (and thus $x$ is not a root). Again, this is very easy to prove once we have a protocol for proving roots. The intuition is as follows: if and only if $P(\square)$ has value $y$ at point $x$, then subtracting $y$ from $P(\square)$ will create a new polynomial $\tilde{P}(\square)=P(\square)-y$ that is zero at point $x$, making $x$ a root. (Visually you can imagine a polynomial with height $y$ at a point $x$, and subtracting $y$ shifts the whole polynomial down $y$ units, moving that point down to the x-axis.) The verifier can construct $K_{\tilde{P}(\tau)}$ from $K_{P(\tau)}$ using the additive homomorphic property: $K_{\tilde{P}(\tau)}=K_{P(tau)\cdot} g^{-y}$. Then the prover shows $K_{\tilde{P}(\tau)}$ has a root at point $x$ using the protocol above for proving roots.

Selective Open: Batch of Points #

If the cost of opening a set of points is roughly the same as the cost of opening a single point, it is called a batch opening. Several variants might be desired:

  • Batch open multiple points on the same polynomial: direct from KZG, shown below.
  • Batch open the same point on multiple polynomials: direct from KZG, not shown.
  • Batch open multiple points on multiple polynomials: not directly possible with KZG but possible with variants.

To batch open multiple points on the same polynomial $P(\square)$, the prover asserts the full set of points to the verifier. The verifier will interpolate a polynomial through these points $R(\square)$ and compute its commitment $K_{R(\tau)}$. Recall that when proving a single point $\{x,y\}$, it would compute $\tilde{P}(\square)=P(\square)-y$. This does not work for multiple points because the amount to “slide down” the polynomial differs. However $R(\square)$ has the right amount at every value of $x$ being opened. So the verifier computes $K_{\tilde{P}(\tau)}=K_{P(\tau)} \cdot (K_{R(\tau)})^{-1}$ where $\tilde{P}(\square)=P(\square)-R(\square)$ using the additively homomorphic property, and now all the points are roots, so the prover uses the “selective open: multiple roots” protocol above on $\tilde{P}(\square)$.

Footnotes #


  1. The result was actually pointed out earlier by DeMillo and Lipton, and thus is occasionally referred to as the DeMillo–Lipton–Schwartz–Zippel lemma ↩︎

  2. The commitment was popularized by Pedersen but Pedersen attributes it to Bos and Chaum in his paper. It appeared even earlier as a bit commitment scheme in a paper by Chaum, Damgard, and van de Graaf. ↩︎

\ No newline at end of file diff --git a/docs/background/overview/index.html b/docs/background/overview/index.html index 5753b6e..304fa81 100644 --- a/docs/background/overview/index.html +++ b/docs/background/overview/index.html @@ -1,14 +1,14 @@ Overview | Handbook - +Elliptic curve cryptography Hardness of the discrete logarithm problem and related problems Pairing-based cryptography at a “black-box” level (what it does, not necessarily how it works) Resources: Lecture (Boneh) Commitment schemes Properties: hiding and binding Construction: Pedersen Commitments Resources: Lecture (Boneh) Zero knowledge proofs (high level idea) Properties: completeness, soundness, zero-knowledge Resources: Lecture (Goldwasser) zk-SNARKs # Plonk is a zk-SNARK proof system.">Overview | Handbook +
Overview

Overview #

Preliminaries -#

While we may add more background in future iterations, for now we punt on explaining the following concepts and assume you are already familiar with them:

  1. Elliptic curve cryptography
    1. Hardness of the discrete logarithm problem and related problems
    2. Pairing-based cryptography at a “black-box” level (what it does, not necessarily how it works)
    3. Resources: Lecture (Boneh)
  2. Commitment schemes
    1. Properties: hiding and binding
    2. Construction: Pedersen Commitments
    3. Resources: Lecture (Boneh)
  3. Zero knowledge proofs (high level idea)
    1. Properities: completeness, soundness, zero-knowledge
    2. Resources: Lecture (Goldwasser)

zk-SNARKs -#

Plonk is a zk-SNARK proof system. In such a system, one entity (the prover) executes a function $f$ on a set of inputs (say $x,y$) and produces output $z=f(x,y)$. It then issues a proof $\pi$ that $z$ is correct. It can show $\pi$ to anyone and it will convince them (the verifier) that $z$ is correct.

What are the assumptions about the function, inputs, and outputs?

Function:

  • $f$ can be nearly any function.
  • $f$ must be deterministic, meaning that running $f$ on the same inputs always produces the same output. Randomness can be used but it needs to be an input to the function.
  • $f$ is disclosed to the verifier, meaning that to check $\pi$ is correct requires a copy of $f$ itself. It is possible to make a private $f$ with a hack, see below (under inputs).
  • In Plonk specifically, $f$ takes the form of a circuit with two kinds of gates: addition (takes two inputs and outputs their sum) and multiplication (takes two inputs and outputs their product). It is technically modular addition and multiplication, where the modulus is a large (for example, 256 bit) prime number. It has been proven that using only these two gates is sufficient to emulate any $f$ that can be implemented in any other kind of circuit (it just might result in a larger circuit to capture the same functionality).
  • To use Plonk in practice, you do not need to program circuits. You can use a special-purpose programming language to write $f$ and compilation tools will convert $f$ into the circuit format that Plonk expects.
  • $f$ has a (quite large) upper-bound on its “size” (for example, less than 1 trillion gates for efficiency in standard cryptographic settings).

Inputs:

  • $f$ can have any number of inputs which are typically integers (modulus the large prime).
  • Inputs can be disclosed to the verifier (public inputs), meaning that to check $\pi$ is correct, the verifier also checks that these were the inputs that were used to produce $z$.
  • Inputs can also be undisclosed (private inputs), meaning the verifier does not see them and does need them to check that $\pi$ is correct. But what does it mean to check $z$ is correct if the inputs are not disclosed? It proves that the verifier knows some input $x$ such that, given function $f$, public input $y$ and public output $z$ that $z=f(x,y)$. This called a “proof of knowledge.” The $\pi$ reveals zero information (or “zero knowledge”) about $x$ (beyond what you can learn by knowing it is a legal input to $f$ that produces $y$).
  • As inferable from the above example, inputs can be a mix of public and private.

Ouputs:

  • The output $z$ is disclosed to the verifier, meaning that to check $\pi$ is correct requires a copy of $z$.
  • $z$ does need to be a single integer, it can be a data structure.

Proof Output:

  • The output proof $\pi$ is succinct, meaning that (for Plonk) it is always the same size regardless of how many gates $f$ has.
  • Checking $\pi$ is correct is (for Plonk) constant-time, meaning it is always the same amount of time regardless of how many gates $f$ has.

So why do we need zk-SNARKs? In the case that some of the inputs are undisclosed/private, it is clear zk-SNARKs let us do something “magic,” prove things about inputs that we are not disclosing. In the case that all inputs are disclosed/public (we call this a SNARK rather than zk-SNARK), note that the verifier knows all values $x,y,f,z$ in $z=f(x,y)$. If the verifier wants to know if $z$ is correct, it does not need a proof $\pi$, it can just execute $f$ for itself on $x,y$ and see that the output is $z$.

At first glance, SNARKs (rather than zk-SNARKs) seem useless but remember that proof outputs are succinct and constant-time. For this reason, it might be cheaper (in terms of time and memory) for the verifier to check $\pi$ than to re-execute $f$. Whether it is cheaper or not basically comes down to how complex $f$ is. If $f$ is simple, re-executing it will be fastest. But once $f$ becomes sufficiently complex, it will be cheaper to verify $\pi$. What is sufficiently complex? Roughly any $f$ that would take, say, a millisecond or more to run on a normal device.

Last, it is important to recognize we are not getting something for “free” here. In order for the verifier to enjoy fast verification of $f$, someone else (the prover) had to execute $f$ and generate a proof $\pi$ for $f$ which is substantially more work than just running $f$. So the prover does extra work to save the verifier work. What are some models where this kind of trade-off makes sense for SNARKs (rather than zk-SNARKs)? There are probably many more, but the two big ones are:

  • Case 1: there is a powerful (but not trusted) computer like a cloud service and a smaller constrained device (like a phone with battery life). Additionally, the economics need to make sense for the cloud to execute on behalf of the smartphone (fees, subscription, service offered by phone manufacturer, …).
  • Case 2: there are many verifiers that want to verifier the same thing so the system scales better if one party executes and issues a proof $\pi$ and the verifiers all check the proof rather than re-executing the function.

Plonk & its gadgets -#

There are numerous ways to implement a zk-SNARK system. Plonk uses a templated called a polynomial interactive oracle proof (or poly-IOP). The next background article will go into more detail about it. Roughly, the prover stores inputs, outputs, gates, and intermediate values in one-dimensional arrays (or vectors). It will also perform a set of operations on the arrays to prove the circuit is executed correctly. Generally proving that array operations are done correctly will require proofs that are proportional (in size and time) to the length of the array.

The trick to avoiding this is two-fold: first, the array will be encoded into a polynomial (univariate meaning a single variable) and every operation that is done on the array can be “mirrored” on the polynomial representation of the array. Second, the verifier will not receive the polynomials themselves but rather a short commitment to them. Again, every operation being done on the arrays and polynomials need to be mirrored on the commitments to the polynomials so the verifier can follow along.

In order to work, Plonk establishes a set of Poly-IOP building blocks (or gadgets) and combines them into a somewhat involved protocol that proves a circuit is executed correctly. Once this is done, anyone can write any function into a circuit and have Plonk’s circuit gadget prove it is executed correctly.

flowchart LR +#

While we may add more background in future iterations, for now we punt on explaining the following concepts and assume you are already familiar with them:

  1. Elliptic curve cryptography
    1. Hardness of the discrete logarithm problem and related problems
    2. Pairing-based cryptography at a “black-box” level (what it does, not necessarily how it works)
    3. Resources: Lecture (Boneh)
  2. Commitment schemes
    1. Properties: hiding and binding
    2. Construction: Pedersen Commitments
    3. Resources: Lecture (Boneh)
  3. Zero knowledge proofs (high level idea)
    1. Properties: completeness, soundness, zero-knowledge
    2. Resources: Lecture (Goldwasser)

zk-SNARKs +#

Plonk is a zk-SNARK proof system. In such a system, one entity (the prover) executes a function $f$ on a set of inputs (say $x,y$) and produces output $z=f(x,y)$. It then issues a proof $\pi$ that $z$ is correct. It can show $\pi$ to anyone and it will convince them (the verifier) that $z$ is correct.

What are the assumptions about the function, inputs, and outputs?

Function:

  • $f$ can be nearly any function.
  • $f$ must be deterministic, meaning that running $f$ on the same inputs always produces the same output. Randomness can be used but it needs to be an input to the function.
  • $f$ is disclosed to the verifier, meaning that to check $\pi$ is correct requires a copy of $f$ itself. It is possible to make a private $f$ with a hack, see below (under inputs).
  • In Plonk specifically, $f$ takes the form of a circuit with two kinds of gates: addition (takes two inputs and outputs their sum) and multiplication (takes two inputs and outputs their product). It is technically modular addition and multiplication, where the modulus is a large (for example, 256 bit) prime number. It has been proven that using only these two gates is sufficient to emulate any $f$ that can be implemented in any other kind of circuit (it just might result in a larger circuit to capture the same functionality).
  • To use Plonk in practice, you do not need to program circuits. You can use a special-purpose programming language to write $f$ and compilation tools will convert $f$ into the circuit format that Plonk expects.
  • $f$ has a (quite large) upper-bound on its “size” (for example, less than 1 trillion gates for efficiency in standard cryptographic settings).

Inputs:

  • $f$ can have any number of inputs which are typically integers (modulus the large prime).
  • Inputs can be disclosed to the verifier (public inputs), meaning that to check $\pi$ is correct, the verifier also checks that these were the inputs that were used to produce $z$.
  • Inputs can also be undisclosed (private inputs), meaning the verifier does not see them and does need them to check that $\pi$ is correct. But what does it mean to check $z$ is correct if the inputs are not disclosed? It proves that the verifier knows some input $x$ such that, given function $f$, public input $y$ and public output $z$ that $z=f(x,y)$. This called a “proof of knowledge.” The $\pi$ reveals zero information (or “zero knowledge”) about $x$ (beyond what you can learn by knowing it is a legal input to $f$ that produces $y$).
  • As inferable from the above example, inputs can be a mix of public and private.

Outputs:

  • The output $z$ is disclosed to the verifier, meaning that to check $\pi$ is correct requires a copy of $z$.
  • $z$ does need to be a single integer, it can be a data structure.

Proof Output:

  • The output proof $\pi$ is succinct, meaning that (for Plonk) it is always the same size regardless of how many gates $f$ has.
  • Checking $\pi$ is correct is (for Plonk) constant-time, meaning it is always the same amount of time regardless of how many gates $f$ has.

So why do we need zk-SNARKs? In the case that some of the inputs are undisclosed/private, it is clear zk-SNARKs let us do something “magic,” prove things about inputs that we are not disclosing. In the case that all inputs are disclosed/public (we call this a SNARK rather than zk-SNARK), note that the verifier knows all values $x,y,f,z$ in $z=f(x,y)$. If the verifier wants to know if $z$ is correct, it does not need a proof $\pi$, it can just execute $f$ for itself on $x,y$ and see that the output is $z$.

At first glance, SNARKs (rather than zk-SNARKs) seem useless but remember that proof outputs are succinct and constant-time. For this reason, it might be cheaper (in terms of time and memory) for the verifier to check $\pi$ than to re-execute $f$. Whether it is cheaper or not basically comes down to how complex $f$ is. If $f$ is simple, re-executing it will be fastest. But once $f$ becomes sufficiently complex, it will be cheaper to verify $\pi$. What is sufficiently complex? Roughly any $f$ that would take, say, a millisecond or more to run on a normal device.

Last, it is important to recognize we are not getting something for “free” here. In order for the verifier to enjoy fast verification of $f$, someone else (the prover) had to execute $f$ and generate a proof $\pi$ for $f$ which is substantially more work than just running $f$. So the prover does extra work to save the verifier work. What are some models where this kind of trade-off makes sense for SNARKs (rather than zk-SNARKs)? There are probably many more, but the two big ones are:

  • Case 1: there is a powerful (but not trusted) computer like a cloud service and a smaller constrained device (like a phone with battery life). Additionally, the economics need to make sense for the cloud to execute on behalf of the smartphone (fees, subscription, service offered by phone manufacturer, …).
  • Case 2: there are many verifiers that want to verify the same thing so the system scales better if one party executes and issues a proof $\pi$ and the verifiers all check the proof rather than re-executing the function.

Plonk & its gadgets +#

There are numerous ways to implement a zk-SNARK system. Plonk uses a templated called a polynomial interactive oracle proof (or Poly-IOP). The next background article will go into more detail about it. Roughly, the prover stores inputs, outputs, gates, and intermediate values in one-dimensional arrays (or vectors). It will also perform a set of operations on the arrays to prove the circuit is executed correctly. Generally proving that array operations are done correctly will require proofs that are proportional (in size and time) to the length of the array.

The trick to avoiding this is two-fold: first, the array will be encoded into a polynomial (univariate meaning a single variable) and every operation that is done on the array can be “mirrored” on the polynomial representation of the array. Second, the verifier will not receive the polynomials themselves but rather a short commitment to them. Again, every operation being done on the arrays and polynomials need to be mirrored on the commitments to the polynomials so the verifier can follow along.

In order to work, Plonk establishes a set of Poly-IOP building blocks (or gadgets) and combines them into a somewhat involved protocol that proves a circuit is executed correctly. Once this is done, anyone can write any function into a circuit and have Plonk’s circuit gadget prove it is executed correctly.

flowchart LR Succinctness --> Poly-IOP Poly-IOP --> Univariate Univariate --> Gadgets diff --git a/docs/background/poly-iop/index.html b/docs/background/poly-iop/index.html index f4a93ee..a8615e4 100644 --- a/docs/background/poly-iop/index.html +++ b/docs/background/poly-iop/index.html @@ -1,12 +1,12 @@ -Polynomials | Handbook - +Polynomials | Handbook +

Polynomials

Polynomials -#

All the gadgets in Plonkbook follow the same high level model, called a polynomial interactive proof (Poly-IOP). Each gadget is defined as an operation on one or more arrays of data. The arrays are encoded into a univariate polynomial (see below) and the polynomial is committed to (next background section) and passed to the verifier. The verifier works with commitments and sees that operations on commitments are mirroring a set of operations being done on the polynomials themselves. And the operations on the polynomials are mirroring operations on the data encoded into them as an array.

Each gadget description will begin with the array and show the operation being done on the array. It will then show how to manipulate a polynomial holding the array so that the operation is performed on the underlying array. It will then show how the verifier can use only commitments to the polynomials, rather than the full polynomials, to follow along and check every step.

Encoding Arrays of Data into Polynomials +#

All the gadgets in Plonkbook follow the same high level model, called a polynomial interactive oracle proof (Poly-IOP). Each gadget is defined as an operation on one or more arrays of data. The arrays are encoded into a univariate polynomial (see below) and the polynomial is committed to (next background section) and passed to the verifier. The verifier works with commitments and sees that operations on commitments are mirroring a set of operations being done on the polynomials themselves. And the operations on the polynomials are mirroring operations on the data encoded into them as an array.

Each gadget description will begin with the array and show the operation being done on the array. It will then show how to manipulate a polynomial holding the array so that the operation is performed on the underlying array. It will then show how the verifier can use only commitments to the polynomials, rather than the full polynomials, to follow along and check every step.

Encoding Arrays of Data into Polynomials #

In the Poly-IOP model, data starts as an array (or vector) of integers and gadgets are defined in terms of operations on arrays. In the proof stage, the arrays are encoded into a polynomial. Array slots contain integers between 0 and $q-1$, where $q$ is a large (generally 256 bit) prime number. Recall that we call this set of integers $\mathbb{Z}_q$.

$\mathsf{data}_0$$\mathsf{data}_1$$\mathsf{data}_2$$\mathsf{data}_3$$\mathsf{data}_4$

It is common to denote a polynomial like $P(X)$ where $X$ is the variable of the polynomial. We are going denote the variable with an empty box $\square$ which can be interpreted as a place where you can put any integer in $\mathbb{Z}_q$ you want evaluated (or equivalent, where you place an x-coordinate to learn what the y-coordinate is).

A polynomial in this notation looks like:

  • $P(\square)=c_0+c_1\cdot\square+c_2\cdot\square^2+c_3\cdot\square^3+c_4\cdot\square^4=\sum_{i=0}^d c_i\cdot\square^i$

The values $c_i$ are called coefficients. Different arrays of data will (depending on how data is encoded, next) result in different coefficients and thus different polynomials. The degree of the polynomial is the largest exponent. So the polynomial above has degree 4 and thus will have 5 coefficients and 5 terms of the form $c_i\cdot\square^i$ (including $i=0$). Sometimes the coefficient will be zero: the term is thus not written down but in a list of coefficients, it will be included as a 0.

The main question to tackle is how to “encode” an array of integers into a polynomial. This is generally done one of three ways:

  1. Coefficients
  2. Evaluation Points
  3. Roots

Each has its advantages and disadvantages, which we discuss next.

Fast forwarding a bit, once the polynomial is created, it is not shared directly with anyone. Instead, a commitment to it is shared. The commitment does two things: (1) it makes it succinct: e.g., constant size regardless of how long the array is; and (2) it can hide the data in the array as necessary. We will discuss one specific polynomial commitment scheme called KZG. KZG needs the polynomial in the format of a list of its coefficients. If we have the polynomial in a different form, we will have to convert it to coefficients. Thus this needs to be considered when weighing the pros/cons of the three encoding methods.

Encoding 1: Coefficients #

Create polynomial as: $P_1(\square)=\mathsf{data}_0+\square+\mathsf{data}_2\cdot\square^2+\mathsf{data}_3\cdot\square^3+\mathsf{data}_4\cdot\square^4=\sum_{i=0}^d \mathsf{data}_i\cdot\square^i$

Properties:

  • Fast 👍: fastest path to commitment as the output is already in coefficient form.
  • Addition 👍: two arrays can be added together (slot-by-slot) by simply adding the polynomials together
  • Multiplication 👎: no support for multiplication of arrays (Remark: multiplying the polynomials does not multiply the coefficients. It results in a cross multiplication of every term in the first polynomial with every term in the second polynomial. Further the degree of the resulting polynomial will double that of the starting polynomials).
  • Opening 🤷🏻: proving the value of the $i$th element in the array is $\mathsf{data}_i$ doing polynomial math on $P_1(\square)$ is not possible. However $\Sigma$-protocols done directly on KZG may enable this kind of proof. In any case, this is not particularly well explored.
  • Other useful properties 👍: the sum of all values in a array can be computed by evaluating the polynomial at $P_1(\boxed{1})$! $\sum_{i=0}^d \mathsf{data}_i\cdot\boxed{1}^i=\sum_{i=0}^d \mathsf{data}_i$ . You can also show two arrays have the same sum (called a “sum check”) by subtracting them and showing $P(\boxed{1})=0$.
  • Other useful properties 👍: when all coefficients are 0, the polynomial will be the zero polynomial ($P_1(\square)=0$). Coefficients can be entire polynomials, not just integers. A common optimization in Poly-IOP systems is taking a set of equations of polynomials that should equal 0, placing each into the coefficient of a super-polynomial, and showing the super-polynomial is the zero polynomial (which can be proven overwhelmingly by showing it is 0 at a randomly selected point).

Encoding 2: Evaluation Points -#

Create a list of points $\{x,y\}$ for the data: $\langle\{0,\mathsf{data}_0\},\{1,\mathsf{data}_1\},\{2,\mathsf{data}_2\},\{3,\mathsf{data}_3\},\{4,\mathsf{data}_4\}\rangle$ and interpolate a polynomial $P_2(\square)$ through these points.

Properties:

  • Slow (or moderate) 👎: converting a set of points into a set of coefficients is called interpolation and is $O(n^2)$ time generally. A certain optimization allows $O(n\log n)$ time by chosing $x$ coordinates with a mathematical relationship (more on this later).
  • Addition 👍: two arrays can be added together (slot-by-slot) by simply adding the polynomials together
  • Multiplication 👍: two arrays can be multiplied together (slot-by-slot) by simply multiplying the polynomials together
  • Opening 👍: proving the value of the $i$th element in the array is $\mathsf{data}_i$ is possible with polynomial math by showing $P_2(\boxed{i})=\mathsf{data}_i$ and KZG has a precise algorithm for this.

Encoding 3: Roots +#

Create a list of points $\{x,y\}$ for the data: $\langle\{0,\mathsf{data}_0\},\{1,\mathsf{data}_1\},\{2,\mathsf{data}_2\},\{3,\mathsf{data}_3\},\{4,\mathsf{data}_4\}\rangle$ and interpolate a polynomial $P_2(\square)$ through these points.

Properties:

  • Slow (or moderate) 👎: converting a set of points into a set of coefficients is called interpolation and is $O(n^2)$ time generally. A certain optimization allows $O(n\log n)$ time by choosing $x$ coordinates with a mathematical relationship (more on this later).
  • Addition 👍: two arrays can be added together (slot-by-slot) by simply adding the polynomials together
  • Multiplication 👍: two arrays can be multiplied together (slot-by-slot) by simply multiplying the polynomials together
  • Opening 👍: proving the value of the $i$th element in the array is $\mathsf{data}_i$ is possible with polynomial math by showing $P_2(\boxed{i})=\mathsf{data}_i$ and KZG has a precise algorithm for this.

Encoding 3: Roots #

Create polynomial as: $P_3(\square)=(\square-\mathsf{data}_0)(\square-\mathsf{data}_1)(\square-\mathsf{data}_2)(\square-\mathsf{data}_3)(\square-\mathsf{data}_4)$

Alternatively, create a list of roots $\{x,0\}$ for the data: $\langle\{\mathsf{data}_0,0\},\{\mathsf{data}_1,0\},\{\mathsf{data}_2,0\},\{\mathsf{data}_3,0\},\{\mathsf{data}_4,0\}\rangle$ and interpolate a polynomial $P_3(\square)$ through these points.

Properties:

  • Slow 👎 (or moderate): multiplying out naively requires $O(n^2)$ time. Treating as a set of points and interpolating also requires $O(n^2)$ time (because the x-coordinates are the data, they cannot be chosen freely to optimize interpolation). Applying divide and conquer can provide $O(n \log^2 n)$.^[1]
  • Addition 👎: two arrays cannot be added from adding (or otherwise manipulating) the polynomials.
  • Multiplication 👎: two arrays cannot be multiplied from multiplying (or otherwise manipulating) the polynomials (but you can do a “union” operation below).
  • Opening 👍: proving that a value is in the array somewhere is easy and KZG as a precise algorithm for this (opening a root is the same as opening a point, where the y-coordinate is 0). However you cannot show a value is specifically the $i$th value in the array because the polynomial loses the order of the data in the array (see next property).
  • Other useful properties 👍: the order of the data in the array does not matter. The same polynomial will be produced even if the order is changed. This is useful when the array represents a “bag” of unordered data. You can easily prove two “bags” of data are the same because the polynomials will be the same. One use-case of this is proving the output of a shuffle/permutation is the same data as the input (just in a different order).
  • Other useful properties 👍: multiplying two polynomials results in a concatenation of the data in the arrays (or conjunction/union of the data in both bags). This might be useful in some protocols.

Decision Tree for Encoding #

Basically we decide if we specifically need unordered “bags” of data. If so, encoding as roots is the only option. If not, we consider if we need to ever get the data back from the polynomial. Generally we do and encoding as evaluation points is the most common encoding technique. When do we encode the data and never want it back? Usually when (1) the coefficients are all supposed to be zero so we are just showing that property, or (2) we want back the sum of the data and not the data itself. In these cases, you can still work with evaluation point encoding but it will be faster to just do coefficient encoding.

flowchart LR; A[Array to Polynomial] --> B{Is the data unordered?}; @@ -16,15 +16,11 @@ D -- No --> F[Coefficients];

The short answer is to start with evaluation point encoding until you realize you need something different.

Roots of Unity #

Moving forward, we will assume we are using Encoding 2: Evaluation Points. In short, this means placing the elements of our array into the $y$-coordinates ($\mathsf{data}_i=P(\boxed{x_i})$) of points on the polynomial. Before commiting to $P(\square)$, we need to use interpolation to find the coefficients of the polynomial that is fitted to these points. General interpolation algorithms are $O(n^2)$ work for $n$ evaluation points but this can be reduced to $O(n\log n)$ with an optimization.

The optimization we will explore enables interpolation via the fast Fourier transform (FFT). It concerns how to choose the $x$-coordinates, which will serve as the index for accessing the data: evaluating $P(X)$ at $x_i$ will reveal $\mathsf{data}_i$. First note, $x$-coordinates are from the exponent group ($Z_q$) and the choices exceed what is feasible to use ($2^{255}$ values in bls). Any subset can be used and interpolated. The optimization is to chose them with a mathematical structure. Specifically, instead an additive sequence (e.g., $0,1,2,3,\ldots$), we use a multiplicative sequence $1,\omega,\omega\cdot\omega,\omega\cdot\omega\cdot\omega,\ldots$ or equivalently: $\omega^0,\omega^1,\omega^2,\ldots,\omega^{\kappa-1}$. Further, the sequence is closed under multiplication which means that next index after $\omega^{\kappa-1}$ wraps back to the first index: $\omega^{k-1} \cdot \omega = \omega^\kappa = \omega^0=1$ (this property is also useful in proving relationships between data in the array and its neighbouring values).

Roots of Unity

For terminology, we say $\omega$ is a generator with multiplicative order $\kappa$ in $\mathbb{Z}_q$ (or $\omega \in \mathbb{G}_\kappa$). This implies $\omega^\kappa=1$. Rearranging, $\omega=\sqrt[\kappa]{1}$. Thus we can equivalently describe $\omega$ as a $\kappa$-th root of 1. Finally, as 1 is the unity element in $Z_q$, $\omega$ is commonly called a $\kappa$-th root of unity.

For practical purposes, $\kappa$ represents the length of the longest array of data we can use in our protocol. Where does $\kappa$ come from? Different elements of $Z_q$ will have different multiplicative orders but every order must be a divisor of $q-1$. Thus $\kappa$ is the largest divisor of the exact value of $q$ used in an elliptic curve standard. BLS12-384 has $\kappa=2^{32}$ (for terminology, this called a $2$-adicity of $32$). In summary, we can only encode data arrays of length up to $2^{32}=4,294,967,296$.

Interpolation via FFT #

Background -#

FFT is a fast algorithm for transitions between coefficients (Encoding 1) and evaluation points (Encoding 2) .

flowchart LR
-    co[coefficients]
-    points[points]
-
-    co --evaluation--> points
-    points --interpolation--> co
-    
-  
-

Polynomials, interpolation, and Fourier transforms are all big topics that have general theories and applications. This article will not try to explain anything in its full generality. Instead we will simplify as much as possible, limiting ourselves to only what we need for many cryptographic applications.

Here are the simplifications:

  1. We only use integers. No real numbers. No imaginary numbers.
  2. Integers are from a bounded range: $[0,q-1]$ or $\mathbb{Z}_q$ for a large (e.g., 256 bit) prime $q$.
  3. Polynomials are univariate (only one variable).

Worked Example: Evaluation +#

FFT is a fast algorithm for transitions between coefficients (Encoding 1) and evaluation points (Encoding 2) .

flowchart LR +co[coefficients] +points[points] +co --evaluation--> points +points --interpolation--> co

Polynomials, interpolation, and Fourier transforms are all big topics that have general theories and applications. This article will not try to explain anything in its full generality. Instead we will simplify as much as possible, limiting ourselves to only what we need for many cryptographic applications.

Here are the simplifications:

  1. We only use integers. No real numbers. No imaginary numbers.
  2. Integers are from a bounded range: $[0,q-1]$ or $\mathbb{Z}_q$ for a large (e.g., 256 bit) prime $q$.
  3. Polynomials are univariate (only one variable).

Worked Example: Evaluation #

Assume $q=97$.

We will start with the more intuitive direction: going from a polynomial in coefficient form to a set of points on the polynomial. Consider the following polynomial in coefficient form:

$$ P(\square)=81 \square^7+57 \square^6+11 \square^5+59 \square^4+60 \square^3+83 \square^2+45 \square+44 $$

In this case, the list of coefficients (from least to greatest) is $\{44,45,83,60,59,11,57,81\}$. The degree of the polynomial is 7 and the number of coefficients is 8. Our goal is determine 8 unique points of form ($x_i, y_i=P(x_i))$. Why 8? We need 8 points to fully determine a degree 7 polynomial, so this will let us reverse the process (go from points to coefficients) in the future if need to.

(Remark: Think of a straight line. It is of form $P(\square)=c_1\square+c_0$ which is degree $1$ with $2$ coefficients. You need $2$ points to figure out what the line should be. Generalizing, for a degree $d$ polynomial, $d+1$ coefficients or $d+1$ points are needed to fully determine it.)

So the goal is to find $8$ points on the polynomial $P(\square)$. The points can be at any x-coordinates so we will chose $\{1,2,3,4,5,6,7,8\}$ for now. We call this the domain. Finding the points is a simple as plugging the x-coordinates into the $P(\square)$ equation:

$$ @@ -352,7 +348,7 @@ 65 \\ \end{array} \right) -$$

Next, we need some way to combine $\{38,73,24,57\}$ and $\{24, 79, 60, 65\}$ to generate $\{52,59,69,81,12,15,92,36\}$ (that does not add a bunch more work). Assume we can pull this off, then we can recurse using this trick. Instead of directly computing the above two equations (involving two 4x4 matricies), we can split each of them into 2x2 matrices (for a total of four) using the same process. There is just one problem: there isn’t a simple algorithm for the combine step (faster than just computing the entire original matrix) that is going to work for us.

One parameter we can change +$$

Next, we need some way to combine $\{38,73,24,57\}$ and $\{24, 79, 60, 65\}$ to generate $\{52,59,69,81,12,15,92,36\}$ (that does not add a bunch more work). Assume we can pull this off, then we can recurse using this trick. Instead of directly computing the above two equations (involving two 4x4 matrices), we can split each of them into 2x2 matrices (for a total of four) using the same process. There is just one problem: there isn’t a simple algorithm for the combine step (faster than just computing the entire original matrix) that is going to work for us.

One parameter we can change #

Reconsider the original problem, moving between coefficients (left) and evaluation points (right):

$$ \left( \begin{array}{cccccccc} diff --git a/docs/background/proofs/index.html b/docs/background/proofs/index.html index dcb878b..ade373a 100644 --- a/docs/background/proofs/index.html +++ b/docs/background/proofs/index.html @@ -3,7 +3,7 @@ Definition 2 (Polynomial IOP). Let $\mathcal{R}$ be a set of the relations among polynomials $\{P_i\}$. Let $\mathcal{C}_f$ is the commitment to $f$.">Proofs | Handbook - +
Proofs

Security Proofs diff --git a/docs/background/red-tape/index.html b/docs/background/red-tape/index.html index aee1357..d040a3d 100644 --- a/docs/background/red-tape/index.html +++ b/docs/background/red-tape/index.html @@ -1,7 +1,7 @@ Red Tape | Handbook - +
Red Tape

Red Tape diff --git a/docs/gadgets/add1/index.html b/docs/gadgets/add1/index.html index 98a324e..dead59a 100644 --- a/docs/gadgets/add1/index.html +++ b/docs/gadgets/add1/index.html @@ -1,18 +1,18 @@ Add1 | Handbook - +
Add1

Addition (Type 1) #

Recap of types #

TypeDescriptionRecapThis
add1$\mathsf{Arr}_3=\mathsf{Arr}_1 + \mathsf{Arr}_2$$\mathsf{Arr}_3$ is the element-wise addition of $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$.
add2$\mathsf{Sum}_\mathsf{Arr}=\sum_{i = 0}^{n-1} \mathsf{Arr}[i]$$\mathsf{Sum}_\mathsf{Arr}$ is the disclosed sum of all the elements in $\mathsf{Arr}$.
add3$\sum_{i = 0}^{n-1} \mathsf{Arr}_1[i]=\sum_{i = 0}^{n-1} \mathsf{Arr}_2[i]$$\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ have the same undisclosed sum.

Relation #

$ \mathcal{R}_{\mathtt{add1}} := \left\{ \begin{array}{l} (K_\mathsf{Arr_1},K_\mathsf{Arr_2},K_\mathsf{Arr_3}) \end{array} \middle | \begin{array}{l} \mathsf{Arr_3}[i]=\mathsf{Arr_1}[i]+\mathsf{Arr_2}[i], 0\leq i \leq n, \\ \mathsf{Poly}_\mathsf{Arr_j}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr_j}), 1\leq j \leq 3, \\ K_\mathsf{Arr_j}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_j}), 1\leq j \leq 3, \end{array} \right\} $

Intuition -#

The prover ($\mathcal{P}$) holds two arrays $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ of $n$ integers from $\mathbb{Z}_q$: $[a_0, a_1, a_2, \dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that $\mathsf{Arr_3}$ is the element-wise sum of all the elements in the array: $\mathsf{Arr_3}[i]=\mathsf{Arr_1}[i]+\mathsf{Arr_2}[i]$. The prover will encode the three arrays into three polynomials: $\mathsf{Poly}_\mathsf{Arr_1}$, $\mathsf{Poly}_\mathsf{Arr_2}$, and $\mathsf{Poly}_\mathsf{Arr_3}$ (using evaluation points on the domain $\mathcal{H}_\kappa$). It will commit to each polynomial: $K_\mathsf{Arr_1}$,$K_\mathsf{Arr_2}$, and $K_\mathsf{Arr_3}$. The verifier ($\mathcal{V}$) cannot check any of the $\mathsf{Arr_i}$ or $\mathsf{Poly}_\mathsf{Arr_i}$ values directly (they may contain secret information, and even if they do not, they are too long to check) so the verifier only sees $K_\mathsf{Arr_1}$,$K_\mathsf{Arr_2}$, and $K_\mathsf{Arr_3}$.

In order to prove $K_\mathsf{Arr_1}$,$K_\mathsf{Arr_2}$, and $K_\mathsf{Arr_3}$ are consistent, the prover can use one of two methods.

The most straight-forward method is to use the additive homomorphic property of the KZG polynomial commitment scheme which states that for equal-sized polynomials on the same domain:

  • $K_\mathsf{Arr_1}\otimes K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}\oplus \mathsf{Poly}_\mathsf{Arr_2})$

Here $\otimes$ is multiplication in the KZG group (e.g., $\mathbb{G}_1$ in BLS12-381) while $\oplus$ is addition in $\mathbb{Z}_q$ of each evaluation point in $ \mathsf{Poly}_\mathsf{Arr_1}$ with each evaluation point in $\mathsf{Poly}_\mathsf{Arr_2}$. If the prover ($\mathcal{P}$) can set $K_\mathsf{Arr_3}\leftarrow K_\mathsf{Arr_1}\otimes K_\mathsf{Arr_2}$, then the verifier can check $K_\mathsf{Arr_3}\stackrel{?}{=}K_\mathsf{Arr_1}\otimes K_\mathsf{Arr_2}$.

However a second method is needed in other cases. Note that there are many different polynomials that interpolate $\mathsf{Arr_3}$ on the domain $\mathcal{H}_\kappa$ (but are different elsewhere in the polynomial outside of $\mathcal{H}_\kappa)$. Each of these polynomials will have a unique commitment value. So it is possible that $K_\mathsf{Arr_3}\neq K_\mathsf{Arr_1}\otimes K_\mathsf{Arr_2}$, and yet $\mathsf{Arr_3}[i]=\mathsf{Arr_1}[i]+\mathsf{Arr_2}[i]$ for all $i$. This arrises when $\mathsf{Poly}_\mathsf{Arr_3}$ comes from a different part of the protocol than $\mathsf{Poly}_\mathsf{Arr_1}$ and $\mathsf{Poly}_\mathsf{Arr_2}$.

The second method is more general so it can be used in place of the first method (but is more expensive), as well as covering all cases where $\mathsf{Arr_3}[i]=\mathsf{Arr_1}[i]+\mathsf{Arr_2}[i]$. The idea is to show $\mathsf{Arr_3}[i]-\mathsf{Arr_1}[i]+\mathsf{Arr_2}[i]=0$ for each evaluation point in the domain $\mathcal{H}_\kappa$. Showing a polynomial is zero on the domain (a “vanishing polynomial”) is a common sub-protocol used by many gadgets.

Protocol Details +#

The prover ($\mathcal{P}$) holds two arrays $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ of $n$ integers from $\mathbb{Z}_q$: $[a_0, a_1, a_2, \dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that $\mathsf{Arr_3}$ is the element-wise sum of all the elements in the array: $\mathsf{Arr_3}[i]=\mathsf{Arr_1}[i]+\mathsf{Arr_2}[i]$. The prover will encode the three arrays into three polynomials: $\mathsf{Poly}_\mathsf{Arr_1}$, $\mathsf{Poly}_\mathsf{Arr_2}$, and $\mathsf{Poly}_\mathsf{Arr_3}$ (using evaluation points on the domain $\mathcal{H}_\kappa$). It will commit to each polynomial: $K_\mathsf{Arr_1}$,$K_\mathsf{Arr_2}$, and $K_\mathsf{Arr_3}$. The verifier ($\mathcal{V}$) cannot check any of the $\mathsf{Arr_i}$ or $\mathsf{Poly}_\mathsf{Arr_i}$ values directly (they may contain secret information, and even if they do not, they are too long to check) so the verifier only sees $K_\mathsf{Arr_1}$,$K_\mathsf{Arr_2}$, and $K_\mathsf{Arr_3}$.

In order to prove $K_\mathsf{Arr_1}$,$K_\mathsf{Arr_2}$, and $K_\mathsf{Arr_3}$ are consistent, the prover can use one of two methods.

The most straight-forward method is to use the additive homomorphic property of the KZG polynomial commitment scheme which states that for equal-sized polynomials on the same domain:

  • $K_\mathsf{Arr_1}\otimes K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}\oplus \mathsf{Poly}_\mathsf{Arr_2})$

Here $\otimes$ is multiplication in the KZG group (e.g., $\mathbb{G}_1$ in BLS12-381) while $\oplus$ is addition in $\mathbb{Z}_q$ of each evaluation point in $ \mathsf{Poly}_\mathsf{Arr_1}$ with each evaluation point in $\mathsf{Poly}_\mathsf{Arr_2}$. If the prover ($\mathcal{P}$) can set $K_\mathsf{Arr_3}\leftarrow K_\mathsf{Arr_1}\otimes K_\mathsf{Arr_2}$, then the verifier can check $K_\mathsf{Arr_3}\stackrel{?}{=}K_\mathsf{Arr_1}\otimes K_\mathsf{Arr_2}$.

However a second method is needed in other cases. Note that there are many different polynomials that interpolate $\mathsf{Arr_3}$ on the domain $\mathcal{H}_\kappa$ (but are different elsewhere in the polynomial outside of $\mathcal{H}_\kappa)$. Each of these polynomials will have a unique commitment value. So it is possible that $K_\mathsf{Arr_3}\neq K_\mathsf{Arr_1}\otimes K_\mathsf{Arr_2}$, and yet $\mathsf{Arr_3}[i]=\mathsf{Arr_1}[i]+\mathsf{Arr_2}[i]$ for all $i$. This arises when $\mathsf{Poly}_\mathsf{Arr_3}$ comes from a different part of the protocol than $\mathsf{Poly}_\mathsf{Arr_1}$ and $\mathsf{Poly}_\mathsf{Arr_2}$.

The second method is more general so it can be used in place of the first method (but is more expensive), as well as covering all cases where $\mathsf{Arr_3}[i]=\mathsf{Arr_1}[i]+\mathsf{Arr_2}[i]$. The idea is to show $\mathsf{Arr_3}[i]-\mathsf{Arr_1}[i]+\mathsf{Arr_2}[i]=0$ for each evaluation point in the domain $\mathcal{H}_\kappa$. Showing a polynomial is zero on the domain (a “vanishing polynomial”) is a common sub-protocol used by many gadgets.

Protocol Details #

Array Level #

  • $\mathcal{P}$ holds an array $\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \in \mathbb{Z}_q$)
  • $\mathcal{P}$ holds an array $\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \in \mathbb{Z}_q$)
  • $\mathcal{P}$ computes or holds an array $\mathsf{Arr_3} = [a_{(3,0)}, a_{(3,1)}, a_{(3,2)}, \dots, a_{(3,n-1)}]$ of $n$ integers ($a_{(3,i)} \in \mathbb{Z}_q$) such that:
    • $\mathsf{Arr_3}[i]=\mathsf{Arr_1}[i]+\mathsf{Arr_2}[i]$ for $i$ from 0 to $n-1$

Polynomial Level #

We assume the three arrays $\mathsf{Arr_1}$, $\mathsf{Arr_2}$, and $\mathsf{Arr_3}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\mathcal{H}_\kappa$) are chosen as the multiplicative group of order $\kappa$ with generator $\omega\in\mathbb{G}_\kappa$ (see Background for more). In short, $\omega^0$ is the first element and $\omega^{\kappa-1}$ is the last element of $\mathcal{H}_\kappa$. If $\kappa$ is larger than the length of the array, the array can be padded with elements of value 0 (which will not change the sum).

Recall the constraint we want to prove:

  1. $\mathsf{Arr_3}[i]=\mathsf{Arr_1}[i]+\mathsf{Arr_2}[i]$ for $i$ from 0 to $n-1$

In polynomial form, the constraint is:

  1. For all $X$ from $\omega^0$ to $\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Arr_3}(X)=\mathsf{Poly}_\mathsf{Arr_1}(X)+\mathsf{Poly}_\mathsf{Arr_2}(X)$

We adjust the constraints to show an equality with 0 and label it:

  1. For all $X$ from $\omega^0$ to $\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Vanish}(X)= \mathsf{Poly}_\mathsf{Arr_1}(X)+\mathsf{Poly}_\mathsf{Arr_2}(X) - \mathsf{Poly}_\mathsf{Arr_3}(X)=0$

This equation is true for every value of $X \in \mathcal{H}_\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\kappa - 1$, which is a minimal vanishing polynomial for $\mathcal{H}_\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\mathsf{Poly}_\mathsf{Vanish}(X)$ must be vanishing on $\mathcal{H}_\kappa$ too. Specifically, the prover computes:

  1. $Q(X) = \frac{\mathsf{Poly}_\mathsf{Vanish}(X)}{X^\kappa - 1}$

By rearranging, we can get $\mathsf{Poly}_\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\mathcal{H}_\kappa$ and outside of it):

  1. $\mathsf{Poly}_\mathsf{Zero}(X)=\mathsf{Poly}_\mathsf{Vanish}(X) - Q(X)\cdot (X^\kappa - 1)=0$

Ultimately the add1 argument will satisfy the following constraints at the Commitment Level:

  1. Show $Q(X)$ exists (as a polynomial that evenly divides the divisor)
  2. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is correctly constructed from $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, and $\mathsf{Poly}_\mathsf{Arr_3}(X)$.
  3. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is the zero polynomial

Commitment Level #

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) are too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}(X))$

  • $K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}(X))$

  • $K_\mathsf{Arr_3}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_3}(X))$

  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$

  • $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1},\zeta)$

  • $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2},\zeta)$

  • $\mathsf{Poly}_\mathsf{Arr_3}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_3},\zeta)$

  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish}=\mathsf{Poly}_\mathsf{Arr_1}(\zeta)+\mathsf{Poly}_\mathsf{Arr_2}(\zeta)-\mathsf{Poly}_\mathsf{Arr_3}( \zeta)$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish1} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Implementations #

Security Proof #

Completeness -#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr_1}, \mathsf{Arr_2}$ and $\mathsf{Arr_3}$ such that $\mathsf{Arr_1}[i] + \mathsf{Arr_2}[i] - \mathsf{Arr_3}[i] = 0 \space \forall i \in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$ = Y_\mathsf{Vanish} - Q(\zeta)(\zeta^\kappa - 1)$

$ = \mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}( \zeta) - Q(\zeta)(\zeta^\kappa - 1)$

$= \mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}( \zeta) - \frac{\mathsf{Poly_{Vanish}}(\zeta)}{\zeta^\kappa - 1}\cdot(\zeta^\kappa - 1)$

$= \mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}( \zeta) - (\mathsf{Poly}_\mathsf{Arr_1}(\zeta)+\mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}(\zeta))$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish}}(X)$ is vanishing on $\mathcal{H_\kappa}$, i.e. if $\mathsf{Poly}_\mathsf{Arr_1}(X)+\mathsf{Poly}_\mathsf{Arr_2}(X) - \mathsf{Poly}_\mathsf{Arr_3}(X) =0 \space \forall X \in \mathcal{H}_\kappa$. This is true if if $\mathsf{Arr_1}[i] + \mathsf{Arr_2}[i] - \mathsf{Arr_3}[i] = 0 \space \forall i \in [0, \kappa - 1]$, since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$. But $\mathsf{Arr_1}[i] + \mathsf{Arr_2}[i] - \mathsf{Arr_3}[i] = 0 \space \forall i \in [0, \kappa - 1]$ is precisely the relation tnat we assumed held for our prover (if $\kappa \gt n$ then the arrays get padded such that this relation still holds), thus the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.

Soundness -#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr1}(X)$, $\mathsf{Poly}_\mathsf{Arr2}(X)$, $\mathsf{Poly}_\mathsf{Arr3}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr1}(X)$, $\mathsf{Poly}_\mathsf{Arr2}(X)$, $\mathsf{Poly}_\mathsf{Arr3}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{\mathcal{V}}$ accepts at the end of the protocol

    ii) $\mathsf{Arr}_3\neq \mathsf{Arr}_1 + \mathsf{Arr}_2$

Our proof is as follows:

For the second win condition to be fulfilled, the constraint must not hold for at least one index of the arrays. But then $\mathsf{Poly}_\mathsf{Vanish}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calculate the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Arr1}(X)$, $\mathsf{Poly}_\mathsf{Arr2}(X)$, and $\mathsf{Poly}_\mathsf{Arr3}(X)$. Each commitment $\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr1}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr2}(\zeta)$, and $\mathsf{Poly}_\mathsf{Arr3}(\zeta)$ can only feasibliy be opened to one value each. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish}}{(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge +#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr_1}, \mathsf{Arr_2}$ and $\mathsf{Arr_3}$ such that $\mathsf{Arr_1}[i] + \mathsf{Arr_2}[i] - \mathsf{Arr_3}[i] = 0 \space \forall i \in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$ = Y_\mathsf{Vanish} - Q(\zeta)(\zeta^\kappa - 1)$

$ = \mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}( \zeta) - Q(\zeta)(\zeta^\kappa - 1)$

$= \mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}( \zeta) - \frac{\mathsf{Poly_{Vanish}}(\zeta)}{\zeta^\kappa - 1}\cdot(\zeta^\kappa - 1)$

$= \mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}( \zeta) - (\mathsf{Poly}_\mathsf{Arr_1}(\zeta)+\mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}(\zeta))$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish}}(X)$ is vanishing on $\mathcal{H_\kappa}$, i.e. if $\mathsf{Poly}_\mathsf{Arr_1}(X)+\mathsf{Poly}_\mathsf{Arr_2}(X) - \mathsf{Poly}_\mathsf{Arr_3}(X) =0 \space \forall X \in \mathcal{H}_\kappa$. This is true if if $\mathsf{Arr_1}[i] + \mathsf{Arr_2}[i] - \mathsf{Arr_3}[i] = 0 \space \forall i \in [0, \kappa - 1]$, since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$. But $\mathsf{Arr_1}[i] + \mathsf{Arr_2}[i] - \mathsf{Arr_3}[i] = 0 \space \forall i \in [0, \kappa - 1]$ is precisely the relation tnat we assumed held for our prover (if $\kappa \gt n$ then the arrays get padded such that this relation still holds), thus the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.

Soundness +#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr1}(X)$, $\mathsf{Poly}_\mathsf{Arr2}(X)$, $\mathsf{Poly}_\mathsf{Arr3}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr1}(X)$, $\mathsf{Poly}_\mathsf{Arr2}(X)$, $\mathsf{Poly}_\mathsf{Arr3}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{\mathcal{V}}$ accepts at the end of the protocol

    ii) $\mathsf{Arr}_3\neq \mathsf{Arr}_1 + \mathsf{Arr}_2$

Our proof is as follows:

For the second win condition to be fulfilled, the constraint must not hold for at least one index of the arrays. But then $\mathsf{Poly}_\mathsf{Vanish}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calculate the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Arr1}(X)$, $\mathsf{Poly}_\mathsf{Arr2}(X)$, and $\mathsf{Poly}_\mathsf{Arr3}(X)$. Each commitment $\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr1}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr2}(\zeta)$, and $\mathsf{Poly}_\mathsf{Arr3}(\zeta)$ can only feasibly be opened to one value each. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish}}{(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge #

We prove that the above protocol is zero-knowledge when $\mathsf{PolyCommit}_\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ that knows the trapdoor $\tau$, which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ chooses arbitrary values for ${\mathsf{Poly}_\mathsf{Arr1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr2}(\tau)}$, and $\mathsf{Poly}_\mathsf{Arr3}(\tau)$, then computes $g^{\mathsf{Poly}_\mathsf{Arr1}(\tau)}$, $g^{\mathsf{Poly}_\mathsf{Arr2}(\tau)}$, and $g^{\mathsf{Poly}_\mathsf{Arr3}(\tau)}$ to write as the commitments $K_\mathsf{Arr1}$, $ K_\mathsf{Arr2}$, and $ K_\mathsf{Arr3}$. $\mathcal{S}$ then generates the challenge evaluation point $\rho$ (by strong Fiat-Shamir) and computes $Q(\tau)$ using $\rho$ and the values it chose for ${\mathsf{Poly}_\mathsf{Arr1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr2}(\tau)}$, and $\mathsf{Poly}_\mathsf{Arr3}(\tau)$. $\mathcal{S}$ writes the commitment $K_Q = g^{Q(\tau)}$ to the transcript.

Now, $\mathcal{S}$ generates the second random challenge point $\zeta$ (which we assume is not in $\mathcal{H}_\kappa$; if it is in $\mathcal{H}_\kappa$, $\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\mathcal{S}$ then create fake opening proofs for ${\mathsf{Poly}_\mathsf{Arr1}(\zeta)}$, ${\mathsf{Poly}_\mathsf{Arr2}(\zeta)}$, and $\mathsf{Poly}_\mathsf{Arr3}(\zeta)$, to arbitrary values. This is done using the knowledge of $\tau$, calculating the respective witness $q(\tau) = \frac{{f(\tau) - f(\zeta)}}{\tau - \zeta}$ for each of the polynomials.

Finally, $\mathcal{S}$ creates a fake opening proof for $Q(\zeta) = \frac{Y_\mathsf{Vanish}}{(\zeta^\kappa - 1)}$. This is done using knowledge of $\tau$ to calculate an accepting witness $q(\tau)$, as above. This means that $Y_\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generated from a real execution, since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

  • For add2, the proof is written with a simulator that doesn’t know the trapdoor; however, with small alterations the proof for add2 should apply here and vice versa
\ No newline at end of file diff --git a/docs/gadgets/add2/index.html b/docs/gadgets/add2/index.html index 4f88395..e97d682 100644 --- a/docs/gadgets/add2/index.html +++ b/docs/gadgets/add2/index.html @@ -1,18 +1,18 @@ Add2 | Handbook - +
Add2

Addition (Type 2) #

Recap of types #

TypeDescriptionRecapThis
add1$\mathsf{Arr}_3=\mathsf{Arr}_1 + \mathsf{Arr}_2$$\mathsf{Arr}_3$ is the element-wise addition of $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$.
add2$\mathsf{Sum}_\mathsf{Arr}=\sum_{i = 0}^{n-1} \mathsf{Arr}[i]$$\mathsf{Sum}_\mathsf{Arr}$ is the disclosed sum of all the elements in $\mathsf{Arr}$.
add3$\sum_{i = 0}^{n-1} \mathsf{Arr}_1[i]=\sum_{i = 0}^{n-1} \mathsf{Arr}_2[i]$$\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ have the same undisclosed sum.

Relation #

$ \mathcal{R}_{\mathtt{add2}} := \left\{ \begin{array}{l} (K_\mathsf{Arr},\mathsf{Sum}_\mathsf{Arr}) \end{array} \middle | \begin{array}{l} \mathsf{Arr} = [a_0, a_1, a_2, \dots, a_{n-1}], \\ \mathsf{Sum}_\mathsf{Arr} = \sum_{i = 0}^{n-1} a_i, \\ \mathsf{Poly}_\mathsf{Arr}(X)=\mathsf{FFT.Interp}(\omega,\mathsf{Arr}), \\ K_\mathsf{Arr}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr}(X)) \end{array} \right\} $

Intuition -#

The prover ($\mathcal{P}$) holds an array $\mathsf{Arr} = [a_0, a_1, a_2, \dots, a_{n-1}]$ of $n$ integers (from $\mathbb{Z}_q$) and a disclosed integer $\mathsf{Sum}_\mathsf{Arr}$. It will produce a succinct (independent of $n$) proof that $\mathsf{Sum}_\mathsf{Arr}$ is the sum of all the elements in the array. The prover will encode the array into a polynomial $\mathsf{Poly}_\mathsf{Arr}$ (using evaluation points on the domain $\mathcal{H}_\kappa$) and commit to the polynomial $K_\mathsf{Arr}$. The verifier ($\mathcal{V}$) cannot check $\textsf{Arr}$ or $\mathsf{Poly}_\mathsf{Arr}$ directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\mathsf{Arr}$ and the asserted value $\mathsf{Sum_\mathsf{Arr}}$.

In order to prove $K_\mathsf{Arr}$ and $\mathsf{Sum}_\mathsf{Arr}$ are consistent, the prover will build a helper array $\mathsf{Acc}_\mathsf{Arr}$ called an accumulator (or accumulating array or incremental array). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\mathsf{Arr}$, the prover will also encode $\mathsf{Acc}$ as a polynomial and provide a commitment of it to the verifier. The idea is that the prover will prove a relation between $\mathsf{Arr}$ and $\mathsf{Acc}$; and a relation between $\mathsf{Acc}$ and $\mathsf{Sum_\mathsf{Arr}}$. Put together, it will imply the correct relation between $\mathsf{Arr}$ and $\mathsf{Sum_\mathsf{Arr}}$.

Consider a small numeric example in $\mathbb{Z}_{97}$ where $\mathsf{Arr}= [84,67,11,92,36,67]$ and $\mathsf{Sum}_\mathsf{Arr}=66$. The first idea is to get $\mathsf{Sum}_\mathsf{Arr}$ into an array. Say, we just append it: $\mathsf{Arr}''= [84,67,11,92,36,67,66] $. How does the prover show $\mathsf{Arr}''$ is correct? The last value of the array depends on every single element that precedes it, which will be a complex constraint to prove.

An alternative idea is to create a new array that starts the same as $\mathsf{Arr}$ and ends up at $\mathsf{Sum}_\mathsf{Arr}$ by folding in the integers from $\mathsf{Arr}$ one-by-one with addition. Then each value in the new array will depend on only two values, as below.

The first value in $\mathsf{Acc}$ will be a copy of the first value from $\mathsf{Arr}$:

  • $\mathsf{Arr}= [84,67,11,92,36,67]$

  • $\mathsf{Acc}= [84, \bot,\bot,\bot,\bot,\bot] $

The next value will be the addition (mod 97) of: 67 (the value at the same index in $\mathsf{Arr}$) and 84 (the previous value in $\mathsf{Acc}$):

  • $\mathsf{Arr}= [84,67,11,92,36,67]$

  • $ \mathsf{Acc} = [84, (67+84),\bot,\bot,\bot,\bot] = [84, 54,\bot,\bot,\bot,\bot]$

The next value will be the addition of: 11 (the value at the same index in $\mathsf{Arr}$) and 54 (the previous value in $\mathsf{Acc}$):

  • $\mathsf{Arr}= [84,67,11,92,36,67]$
  • $ \mathsf{Acc} = [84, 54,(11+54),\bot,\bot,\bot] = [84,54,65,\bot,\bot,\bot]$
  • $ \mathsf{Acc} = [84, 54, 65,(92+65),\bot,\bot] = [84,54,65, 60,\bot,\bot]$
  • $ \mathsf{Acc} = [84,54,65, 60,(36 + 60),\bot] = [84,54,65, 60, 96,\bot]$
  • $ \mathsf{Acc} = [84,54,65, 60, 96, (67+96)] = [84,54,65, 60, 96, 66]$
  • $\mathsf{Sum}_\mathsf{Arr}=66$

Notice the last value in $\mathsf{Acc}$ is $\mathsf{Sum_\mathsf{Arr}}$. The prover wants to show three constraints:

  1. The first value in $\mathsf{Acc}$ matches the first value in $\mathsf{Arr}$,
  2. The rest of the values in $\mathsf{Acc}$ are of the form $\mathsf{Acc}[i]=\mathsf{Arr}[i]+\mathsf{Acc}[i-1]$,
  3. The last value in $\mathsf{Acc}$ matches $\mathsf{Sum}_\mathsf{Arr}$.

If all three constraints are true, then $\mathsf{Sum}_\mathsf{Arr}$ is the sum of the elements of $\mathsf{Arr}$.

Last, while it is not necessary to do, it is often convenient to hold the the value $\mathsf{Sum}_\mathsf{Arr}$ at the start of the array $\mathsf{Acc}$ instead of the end. For this reason, the mathematical explaination below will construct $\mathsf{Acc}$ “backwards” (or right-to-left) from the above example, where the last value of $\mathsf{Acc}$ matches the last value of $\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\mathsf{Acc}$ is $\mathsf{Sum}_\mathsf{Arr}$:

  • $\mathsf{Arr}= [84,67,11,92,36,67]$
  • $ \mathsf{Acc} = [\bot, \bot, \bot, \bot, \bot, 67]$
  • $ \mathsf{Acc} = [\bot, \bot, \bot, \bot, 6, 67]$
  • $\ldots$
  • $ \mathsf{Acc} = [66, 79, 12, 1, 6, 67]$
  • $\mathsf{Sum}_\mathsf{Arr}=66$

Protocol Details +#

The prover ($\mathcal{P}$) holds an array $\mathsf{Arr} = [a_0, a_1, a_2, \dots, a_{n-1}]$ of $n$ integers (from $\mathbb{Z}_q$) and a disclosed integer $\mathsf{Sum}_\mathsf{Arr}$. It will produce a succinct (independent of $n$) proof that $\mathsf{Sum}_\mathsf{Arr}$ is the sum of all the elements in the array. The prover will encode the array into a polynomial $\mathsf{Poly}_\mathsf{Arr}$ (using evaluation points on the domain $\mathcal{H}_\kappa$) and commit to the polynomial $K_\mathsf{Arr}$. The verifier ($\mathcal{V}$) cannot check $\textsf{Arr}$ or $\mathsf{Poly}_\mathsf{Arr}$ directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\mathsf{Arr}$ and the asserted value $\mathsf{Sum_\mathsf{Arr}}$.

In order to prove $K_\mathsf{Arr}$ and $\mathsf{Sum}_\mathsf{Arr}$ are consistent, the prover will build a helper array $\mathsf{Acc}_\mathsf{Arr}$ called an accumulator (or accumulating array or incremental array). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\mathsf{Arr}$, the prover will also encode $\mathsf{Acc}$ as a polynomial and provide a commitment of it to the verifier. The idea is that the prover will prove a relation between $\mathsf{Arr}$ and $\mathsf{Acc}$; and a relation between $\mathsf{Acc}$ and $\mathsf{Sum_\mathsf{Arr}}$. Put together, it will imply the correct relation between $\mathsf{Arr}$ and $\mathsf{Sum_\mathsf{Arr}}$.

Consider a small numeric example in $\mathbb{Z}_{97}$ where $\mathsf{Arr}= [84,67,11,92,36,67]$ and $\mathsf{Sum}_\mathsf{Arr}=66$. The first idea is to get $\mathsf{Sum}_\mathsf{Arr}$ into an array. Say, we just append it: $\mathsf{Arr}''= [84,67,11,92,36,67,66] $. How does the prover show $\mathsf{Arr}''$ is correct? The last value of the array depends on every single element that precedes it, which will be a complex constraint to prove.

An alternative idea is to create a new array that starts the same as $\mathsf{Arr}$ and ends up at $\mathsf{Sum}_\mathsf{Arr}$ by folding in the integers from $\mathsf{Arr}$ one-by-one with addition. Then each value in the new array will depend on only two values, as below.

The first value in $\mathsf{Acc}$ will be a copy of the first value from $\mathsf{Arr}$:

  • $\mathsf{Arr}= [84,67,11,92,36,67]$

  • $\mathsf{Acc}= [84, \bot,\bot,\bot,\bot,\bot] $

The next value will be the addition (mod 97) of: 67 (the value at the same index in $\mathsf{Arr}$) and 84 (the previous value in $\mathsf{Acc}$):

  • $\mathsf{Arr}= [84,67,11,92,36,67]$

  • $ \mathsf{Acc} = [84, (67+84),\bot,\bot,\bot,\bot] = [84, 54,\bot,\bot,\bot,\bot]$

The next value will be the addition of: 11 (the value at the same index in $\mathsf{Arr}$) and 54 (the previous value in $\mathsf{Acc}$):

  • $\mathsf{Arr}= [84,67,11,92,36,67]$
  • $ \mathsf{Acc} = [84, 54,(11+54),\bot,\bot,\bot] = [84,54,65,\bot,\bot,\bot]$
  • $ \mathsf{Acc} = [84, 54, 65,(92+65),\bot,\bot] = [84,54,65, 60,\bot,\bot]$
  • $ \mathsf{Acc} = [84,54,65, 60,(36 + 60),\bot] = [84,54,65, 60, 96,\bot]$
  • $ \mathsf{Acc} = [84,54,65, 60, 96, (67+96)] = [84,54,65, 60, 96, 66]$
  • $\mathsf{Sum}_\mathsf{Arr}=66$

Notice the last value in $\mathsf{Acc}$ is $\mathsf{Sum_\mathsf{Arr}}$. The prover wants to show three constraints:

  1. The first value in $\mathsf{Acc}$ matches the first value in $\mathsf{Arr}$,
  2. The rest of the values in $\mathsf{Acc}$ are of the form $\mathsf{Acc}[i]=\mathsf{Arr}[i]+\mathsf{Acc}[i-1]$,
  3. The last value in $\mathsf{Acc}$ matches $\mathsf{Sum}_\mathsf{Arr}$.

If all three constraints are true, then $\mathsf{Sum}_\mathsf{Arr}$ is the sum of the elements of $\mathsf{Arr}$.

Last, while it is not necessary to do, it is often convenient to hold the the value $\mathsf{Sum}_\mathsf{Arr}$ at the start of the array $\mathsf{Acc}$ instead of the end. For this reason, the mathematical explanation below will construct $\mathsf{Acc}$ “backwards” (or right-to-left) from the above example, where the last value of $\mathsf{Acc}$ matches the last value of $\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\mathsf{Acc}$ is $\mathsf{Sum}_\mathsf{Arr}$:

  • $\mathsf{Arr}= [84,67,11,92,36,67]$
  • $ \mathsf{Acc} = [\bot, \bot, \bot, \bot, \bot, 67]$
  • $ \mathsf{Acc} = [\bot, \bot, \bot, \bot, 6, 67]$
  • $\ldots$
  • $ \mathsf{Acc} = [66, 79, 12, 1, 6, 67]$
  • $\mathsf{Sum}_\mathsf{Arr}=66$

Protocol Details #

Array Level #

  • $\mathcal{P}$ holds an array $\mathsf{Arr} = [a_0, a_1, a_2, \dots, a_{n-1}]$ of $n$ integers ($a_i \in \mathbb{Z}_q$)
  • $\mathcal{P}$ computes array $\mathsf{Acc}$ as follows:
    • $\mathsf{Acc}[n-1]\leftarrow\mathsf{Arr}[n-1]$
    • $\mathsf{Acc}[i]\leftarrow\mathsf{Arr}[i]+\mathsf{Acc}[i+1]$ for $i$ from $n-2$ to 0
  • $\mathcal{P}$ computes $\mathsf{Sum}_\mathsf{Arr}\leftarrow\mathsf{Acc}[0]$

Polynomial Level #

We assume arrays $\mathsf{Arr}$ and $\mathsf{Acc}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\mathcal{H}_\kappa$) are chosen as the multiplicative group of order $\kappa$ with generator $\omega\in\mathbb{G}_\kappa$ (see Background for more). In short, $\omega^0$ is the first element and $\omega^{\kappa-1}$ is the last element of $\mathcal{H}_\kappa$. If $\kappa$ is larger than the length of the array, the array can be padded with elements of value 0 (which will not change the sum).

Recall the three constraints we want to prove (now adjusted to fit with an $\mathsf{Acc}$ that is constructed “backwards,” as noted above):

  1. The last value in $\mathsf{Acc}$ matches the last value in $\mathsf{Arr}$,
  2. The rest of the values in $\mathsf{Acc}$ are of the form $\mathsf{Acc}[i]=\mathsf{Arr}[i]+\mathsf{Acc}[i-1]$,
  3. The first value in $\mathsf{Acc}$ matches $\mathsf{Sum}_\mathsf{Arr}$.

In polynomial form, the constraints are:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Poly}_\mathsf{Arr}(X)$,
  2. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Poly}_\mathsf{Arr}(X)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X)$
  3. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Sum}_\mathsf{Arr}$

In constraint 2, $\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X)$ can also be conceptualized as rotate applied to $\mathsf{Poly}_\mathsf{Acc}(X)$ by one element (rightward in the array view). Also note that constraint 2 does not hold at $X=\omega^{\kappa-1}$ because this value is defined by constraint 1 (for the last value of $X$, the “next” value, $\omega X$, wraps back to the first element of the array which is a boundary condition).

We adjust each of these constraints to show an equality with 0:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X)=0$,
  2. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X)=0$
  3. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Sum}_\mathsf{Arr}=0$

Next we take care of the “for $X$” conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.

  1. $\mathsf{Poly}_\mathsf{Vanish1}(X)=(\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$,
  2. $\mathsf{Poly}_\mathsf{Vanish2}(X)=(\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X))\cdot(X-\omega^{\kappa-1})=0$
  3. $\mathsf{Poly}_\mathsf{Vanish3}(X)=(\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(X^\kappa-1)}{(X-\omega^0)}=0$

These equations are true for every value of $X \in \mathcal{H}_\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\kappa - 1$, which is a minimal vanishing polynomial for $\mathcal{H}_\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\mathsf{Poly}_\mathsf{Vanish1}(X)$, $\mathsf{Poly}_\mathsf{Vanish2}(X)$, and $\mathsf{Poly}_\mathsf{Vanish3}(X)$ must be vanishing on $\mathcal{H}_\kappa$ too. Specifically, the prove computes,

  1. $Q_1(X) = \frac{\mathsf{Poly}_\mathsf{Vanish1}(X)}{X^\kappa - 1}$
  2. $Q_2(X) = \frac{\mathsf{Poly}_\mathsf{Vanish2}(X)}{X^\kappa - 1}$
  3. $Q_3(X) = \frac{\mathsf{Poly}_\mathsf{Vanish3}(X)}{X^\kappa - 1}$

We can replace polynomials $Q_1(X)$, $Q_2(X)$, and $Q_3(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\mathsf{Poly}_\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all three $\mathsf{Poly}_\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all three are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\rho$ selected after the commitments to the earlier polynomials are fixed.

$Q(X) = \frac{\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho + \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2}{X^\kappa - 1}$

By rearranging, we can get $\mathsf{Poly}_\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\mathcal{H}_\kappa$ and outside of it):

$\mathsf{Poly}_\mathsf{Zero}(X)=\mathsf{Poly}_\mathsf{Vanish1}(X) + \rho \mathsf{Poly}_\mathsf{Vanish2}(X) + \rho^2 \mathsf{Poly}_\mathsf{Vanish3}(X) - Q(X)\cdot (X^\kappa - 1)=0$

Ultimately the add2 argument will satisfy the following constraints at the Commitment Level:

  1. Show $Q(X)$ exists (as a polynomial that evenly divides the divisor)
  2. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is correctly constructed from $\mathsf{Poly}_\mathsf{Acc}(X)$, $\mathsf{Poly}_\mathsf{Acc}(\omega X)$, $\mathsf{Poly}_\mathsf{Arr}(X)$, and $\mathsf{Sum}_\mathsf{Arr}$
  3. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is the zero polynomial

Commitment Level #

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr}(X))$
  • $K_\mathsf{Acc}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Acc}(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:

  • $\rho$
  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$
  • $\mathsf{Poly}_\mathsf{Arr}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr}(\zeta\omega)=\mathsf{KZG.Open}(K_\mathsf{Arr},\zeta\omega)$
  • $\mathsf{Poly}_\mathsf{Acc}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Acc},\zeta)$
  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish1}=(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}$
  • $Y_\mathsf{Vanish2}=(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1})$
  • $Y_\mathsf{Vanish3}=(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)}$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\rho$ and $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Implementations #

Security Proof #

Completeness -#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr}$ such that $\mathsf{Sum}_\mathsf{Arr}=\sum_{i = 0}^{n-1} \mathsf{Arr}[i] \space \forall i \in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)} \newline - \frac{\mathsf{Poly}_\mathsf{Vanish1}(\zeta) + \mathsf{Poly}_\mathsf{Vanish2}(\zeta) \rho + \mathsf{Poly}_\mathsf{Vanish3}(\zeta)\rho^2}{\zeta^\kappa - 1} \cdot(\zeta^\kappa - 1)$

$= (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)} \newline - ((\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) \newline + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)})$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly}_\mathsf{Vanish1}(\zeta) + \mathsf{Poly}_\mathsf{Vanish2}(\zeta) \rho + \mathsf{Poly}_\mathsf{Vanish3}(\zeta)\rho^2$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish_1}}(X), \mathsf{Poly_{Vanish_2}}(X)$ and $\mathsf{Poly_{Vanish_3}}(X),$ are all vanishing on $\mathcal{H_\kappa}$, i.e. if all three of the following conditions hold for all $X \in \mathcal{H}_\kappa$:

  1. $(\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$
  2. $ (\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X))\cdot(X-\omega^{\kappa-1})=0$
  3. $ (\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(X^\kappa-1)}{(X-\omega^0)}=0$

These conditions, in turn, hold if:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Poly}_\mathsf{Arr}(X)$
  2. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Poly}_\mathsf{Arr}(X)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X)$
  3. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Sum}_\mathsf{Arr}$

Where we get the “For $X$” due to zeroing parts of the polynomials (see zero1). Since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$, the above conditions are true if:

  1. The last value in $\mathsf{Acc}$ matches the last value in $\mathsf{Arr}$
  2. The rest of the values in $\mathsf{Acc}$ are of the form $\mathsf{Acc}[i]=\mathsf{Arr}[i]+\mathsf{Acc}[i-1]$
  3. The first value in $\mathsf{Acc}$ matches $\mathsf{Sum}_\mathsf{Arr}$

Which are precisely the conditions the Intuitions sections explains will hold if the prover contructs their Accumulator by following the protocol and using $\mathsf{Arr}$ such that $\mathsf{Sum}_\mathsf{Arr}=\sum_{i = 0}^{n-1} \mathsf{Arr}[i] \space \forall i \in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.

Soundness -#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Acc}(X)$, $\mathsf{Poly}_\mathsf{Arr}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Acc}(X)$, $\mathsf{Poly}_\mathsf{Arr}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_\mathsf{Zero}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Sum}_\mathsf{Arr}\neq\sum_{i = 0}^{n-1} \mathsf{Arr}[i]$

Our proof is as follows:

For the second win condition to be fulfilled, one of the three constraints must be false. But then the $\mathsf{Poly}_\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Acc}(X)$, and $\mathsf{Poly}_\mathsf{Arr}(X)$. Each commitment $\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Acc}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr}(\zeta)$, and $\mathsf{Poly}_\mathsf{Acc}(\zeta \cdot \omega)$ can only feasibliy be opened to one value each. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2Y_\mathsf{Vanish3}}{\zeta^\kappa - 1}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2Y_\mathsf{Vanish3}}{\zeta^\kappa - 1}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $A$’s probability of success is negligible.

Zero-Knowledge +#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr}$ such that $\mathsf{Sum}_\mathsf{Arr}=\sum_{i = 0}^{n-1} \mathsf{Arr}[i] \space \forall i \in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)} \newline - \frac{\mathsf{Poly}_\mathsf{Vanish1}(\zeta) + \mathsf{Poly}_\mathsf{Vanish2}(\zeta) \rho + \mathsf{Poly}_\mathsf{Vanish3}(\zeta)\rho^2}{\zeta^\kappa - 1} \cdot(\zeta^\kappa - 1)$

$= (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)} \newline - ((\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) \newline + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)})$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly}_\mathsf{Vanish1}(\zeta) + \mathsf{Poly}_\mathsf{Vanish2}(\zeta) \rho + \mathsf{Poly}_\mathsf{Vanish3}(\zeta)\rho^2$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish_1}}(X), \mathsf{Poly_{Vanish_2}}(X)$ and $\mathsf{Poly_{Vanish_3}}(X),$ are all vanishing on $\mathcal{H_\kappa}$, i.e. if all three of the following conditions hold for all $X \in \mathcal{H}_\kappa$:

  1. $(\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$
  2. $ (\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X))\cdot(X-\omega^{\kappa-1})=0$
  3. $ (\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(X^\kappa-1)}{(X-\omega^0)}=0$

These conditions, in turn, hold if:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Poly}_\mathsf{Arr}(X)$
  2. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Poly}_\mathsf{Arr}(X)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X)$
  3. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Sum}_\mathsf{Arr}$

Where we get the “For $X$” due to zeroing parts of the polynomials (see zero1). Since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$, the above conditions are true if:

  1. The last value in $\mathsf{Acc}$ matches the last value in $\mathsf{Arr}$
  2. The rest of the values in $\mathsf{Acc}$ are of the form $\mathsf{Acc}[i]=\mathsf{Arr}[i]+\mathsf{Acc}[i-1]$
  3. The first value in $\mathsf{Acc}$ matches $\mathsf{Sum}_\mathsf{Arr}$

Which are precisely the conditions the Intuitions sections explains will hold if the prover contructs their Accumulator by following the protocol and using $\mathsf{Arr}$ such that $\mathsf{Sum}_\mathsf{Arr}=\sum_{i = 0}^{n-1} \mathsf{Arr}[i] \space \forall i \in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.

Soundness +#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Acc}(X)$, $\mathsf{Poly}_\mathsf{Arr}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Acc}(X)$, $\mathsf{Poly}_\mathsf{Arr}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_\mathsf{Zero}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Sum}_\mathsf{Arr}\neq\sum_{i = 0}^{n-1} \mathsf{Arr}[i]$

Our proof is as follows:

For the second win condition to be fulfilled, one of the three constraints must be false. But then the $\mathsf{Poly}_\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Acc}(X)$, and $\mathsf{Poly}_\mathsf{Arr}(X)$. Each commitment $\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Acc}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr}(\zeta)$, and $\mathsf{Poly}_\mathsf{Acc}(\zeta \cdot \omega)$ can only feasibly be opened to one value each. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2Y_\mathsf{Vanish3}}{\zeta^\kappa - 1}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2Y_\mathsf{Vanish3}}{\zeta^\kappa - 1}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $A$’s probability of success is negligible.

Zero-Knowledge #

We prove that the above protocol is zero-knowledge when $\mathsf{PolyCommit}_\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ generates an array $\mathsf{Arr'}$ whose product is equal to the disclosed value $\mathsf{Sum}_\mathsf{Arr}$ (this array could just have $\mathsf{Prod}_\mathsf{Sum}$ in one entry, and $0$’s elsewhere), then follows the same steps a prover would to prove the sum of this array. So, $\mathcal{S}$ computes the accumulator $\mathsf{Acc'}$ and interpolates the two arrays into their respective polynomials, $\mathsf{Poly}_\mathsf{Acc'}(X)$ and $\mathsf{Poly}_\mathsf{Arr'}(X)$. It computes $Q(X)'$ using $\mathsf{Poly}_\mathsf{Acc'}(X)$ and $\mathsf{Poly}_\mathsf{Arr'}(X)$ and the random challenge point $\rho'$ (by strong Fiat-Shamir). $\mathcal{S}$ commits to each of these three polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\zeta'$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\mathsf{Poly}_\mathsf{Acc'}(\zeta'), \space \mathsf{Poly}_\mathsf{Arr'}(\zeta'), \space Q(\zeta')'$, and $\mathsf{Poly}_\mathsf{Acc'}(\zeta' \cdot \omega)$, and writes these to the transcript as well. Since $\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution, since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

  • This proof could also be done by defining a simulator that knows the trapdoor $\tau$ and can thus create a passing witness for any commitment. The proof for add1 is done in this style, but with small alterations would work here as well (and vice versa with this style of proof working for add1)
\ No newline at end of file diff --git a/docs/gadgets/add3/index.html b/docs/gadgets/add3/index.html index fc6de64..7681495 100644 --- a/docs/gadgets/add3/index.html +++ b/docs/gadgets/add3/index.html @@ -1,5 +1,5 @@ Add3 | Handbook - +
Add3

Addition (Type 3) @@ -13,6 +13,6 @@ #

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}(X))$
  • $K_\mathsf{Acc_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Acc_1}(X))$
  • $K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}(X))$
  • $K_\mathsf{Acc_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Acc_2}(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:

  • $\rho$
  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$
  • $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1},\zeta)$
  • $\mathsf{Poly}_\mathsf{Acc_1}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1},\zeta)$
  • $\mathsf{Poly}_\mathsf{Acc_1}(\zeta\omega)=\mathsf{KZG.Open}(K_\mathsf{Acc_1},\zeta\omega)$
  • $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2},\zeta)$
  • $\mathsf{Poly}_\mathsf{Acc_2}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2},\zeta)$
  • $\mathsf{Poly}_\mathsf{Acc_2}(\zeta\omega)=\mathsf{KZG.Open}(K_\mathsf{Acc_2},\zeta\omega)$
  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish1}= (\mathsf{Poly}_\mathsf{Acc_1}(\zeta)-\mathsf{Poly}_\mathsf{Arr_1}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}$
  • $Y_\mathsf{Vanish2}= (\mathsf{Poly}_\mathsf{Acc_2}(\zeta)-\mathsf{Poly}_\mathsf{Arr_2}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}$
  • $Y_\mathsf{Vanish3}=(\mathsf{Poly}_\mathsf{Acc_1}(\zeta)-(\mathsf{Poly}_\mathsf{Arr_1}(\zeta)+\mathsf{Poly}_\mathsf{Acc_1}(\omega\cdot \zeta)))\cdot(\zeta-\omega^{\kappa-1})$
  • $Y_\mathsf{Vanish4}= (\mathsf{Poly}_\mathsf{Acc_2}(\zeta)-(\mathsf{Poly}_\mathsf{Arr_2}(\zeta)+\mathsf{Poly}_\mathsf{Acc_2}(\omega\cdot \zeta)))\cdot(\zeta-\omega^{\kappa-1})$
  • $Y_\mathsf{Vanish5}= (\mathsf{Poly}_\mathsf{Acc_1}(\zeta)-\mathsf{Poly}_\mathsf{Acc_2}(\zeta)\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)}$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5}- Q(\zeta)\cdot (\zeta^\kappa - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\rho$ and $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Implementations #

Security Proof #

Completeness -#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ such that $\sum_{i = 0}^{n-1} \mathsf{Arr}_1[i]=\sum_{i = 0}^{n-1} \mathsf{Arr}_2[i] \space \forall i \in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$ = Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5}- Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5} - (\frac{\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho + \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 + \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 + \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4}{X^\kappa - 1})(\zeta^\kappa - 1)$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5} - {\mathsf{Poly}_\mathsf{Vanish1}(X) - \mathsf{Poly}_\mathsf{Vanish2}(X) \rho - \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 - \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 - \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4}$

$= 0$

Where the finally equality holds becaue $Y_{\mathsf{Vanish_j}}=\mathsf{Poly_{Vanish_j}}(\zeta)$.

Note also that the second equality relies on the fact that $\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho + \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 + \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 + \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish_1}}(X), \mathsf{Poly_{Vanish_2}}(X)$, $\mathsf{Poly_{Vanish_3}}(X),$ $\mathsf{Poly_{Vanish_4}}(X)$, and $\mathsf{Poly_{Vanish_5}}(X),$ are all vanishing on $\mathcal{H_\kappa}$, i.e. if all three of the following conditions hold for all $X \in \mathcal{H}_\kappa$:

  1. $ (\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Arr_1}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$
  2. $ (\mathsf{Poly}_\mathsf{Acc_2}(X)-\mathsf{Poly}_\mathsf{Arr_2}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$
  3. $(\mathsf{Poly}_\mathsf{Acc_1}(X)-(\mathsf{Poly}_\mathsf{Arr_1}(X)+\mathsf{Poly}_\mathsf{Acc_1}(\omega\cdot X)))\cdot(X-\omega^{\kappa-1})=0$
  4. $ (\mathsf{Poly}_\mathsf{Acc_2}(X)-(\mathsf{Poly}_\mathsf{Arr_2}(X)+\mathsf{Poly}_\mathsf{Acc_2}(\omega\cdot X)))\cdot(X-\omega^{\kappa-1})=0$
  5. $ (\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Acc_2}(X)\cdot\frac{(X^\kappa-1)}{(X-\omega^0)}=0$

These conditions, in turn, hold if:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Arr_1}(X)$
  2. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_2}(X)=\mathsf{Poly}_\mathsf{Arr_2}(X)$
  3. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Arr_1}(X)+\mathsf{Poly}_\mathsf{Acc_1}(\omega\cdot X)$
  4. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_2}(X)=\mathsf{Poly}_\mathsf{Arr_2}(X)+\mathsf{Poly}_\mathsf{Acc_2}(\omega\cdot X)$
  5. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Acc_2}(X)$

Where we get the “For $X$” due to zeroing parts of the polynomials (see zero1). Since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$, the above conditions are true if:

  1. The last value in $\mathsf{Acc_1}$ matches the last value in $\mathsf{Arr_1}$
  2. The last value in $\mathsf{Acc_2}$ matches the last value in $\mathsf{Arr_2}$
  3. The rest of the values in $\mathsf{Acc}_1$ are of the form $\mathsf{Acc_1}[i]=\mathsf{Arr_1}[i]+\mathsf{Acc_1}[i-1]$
  4. The rest of the values in $\mathsf{Acc}_2$ are of the form $\mathsf{Acc_2}[i]=\mathsf{Arr_2}[i]+\mathsf{Acc_2}[i-1]$
  5. The first value in $\mathsf{Acc_1}$ matches the first value in $\mathsf{Acc_2}$

Which are precisely the conditions the Intuitions sections explains will hold if the prover contructs their Accumulators by following the protocol and using $\mathsf{Arr}_1$ and $\mathsf{Arr_2}$ such that $\sum_{i = 0}^{n-1} \mathsf{Arr}_1[i] =\sum_{i = 0}^{n-1} \mathsf{Arr}_2[i] \space \forall i \in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.

Soundness -#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_{2}}(X)$, $\mathsf{Poly}_\mathsf{Arr_{2}}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_{2}}(X)$, $\mathsf{Poly}_\mathsf{Arr_{2}}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_\mathsf{Zero}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\sum_{i = 0}^{n-1} \mathsf{Arr_1}[i]\neq\sum_{i = 0}^{n-1} \mathsf{Arr_2}[i]$

Our proof is as follows:

For the second win condition to be fulfilled, one of the five constraints must be false. But then the $\mathsf{Poly}_\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_2}(X)$, and $\mathsf{Poly}_\mathsf{Arr_2}(X)$. Each commitment $\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_1}(\zeta \cdot \omega)$, $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_2}(\zeta)$, and $\mathsf{Poly}_\mathsf{Acc_2}(\zeta \cdot \omega)$ can each only feasibliy be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4Y_\mathsf{Vanish5}}{(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4Y_\mathsf{Vanish5}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge +#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ such that $\sum_{i = 0}^{n-1} \mathsf{Arr}_1[i]=\sum_{i = 0}^{n-1} \mathsf{Arr}_2[i] \space \forall i \in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$ = Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5}- Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5} - (\frac{\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho + \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 + \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 + \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4}{X^\kappa - 1})(\zeta^\kappa - 1)$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5} - {\mathsf{Poly}_\mathsf{Vanish1}(X) - \mathsf{Poly}_\mathsf{Vanish2}(X) \rho - \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 - \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 - \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4}$

$= 0$

Where the finally equality holds because $Y_{\mathsf{Vanish_j}}=\mathsf{Poly_{Vanish_j}}(\zeta)$.

Note also that the second equality relies on the fact that $\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho + \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 + \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 + \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish_1}}(X), \mathsf{Poly_{Vanish_2}}(X)$, $\mathsf{Poly_{Vanish_3}}(X),$ $\mathsf{Poly_{Vanish_4}}(X)$, and $\mathsf{Poly_{Vanish_5}}(X),$ are all vanishing on $\mathcal{H_\kappa}$, i.e. if all three of the following conditions hold for all $X \in \mathcal{H}_\kappa$:

  1. $ (\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Arr_1}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$
  2. $ (\mathsf{Poly}_\mathsf{Acc_2}(X)-\mathsf{Poly}_\mathsf{Arr_2}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$
  3. $(\mathsf{Poly}_\mathsf{Acc_1}(X)-(\mathsf{Poly}_\mathsf{Arr_1}(X)+\mathsf{Poly}_\mathsf{Acc_1}(\omega\cdot X)))\cdot(X-\omega^{\kappa-1})=0$
  4. $ (\mathsf{Poly}_\mathsf{Acc_2}(X)-(\mathsf{Poly}_\mathsf{Arr_2}(X)+\mathsf{Poly}_\mathsf{Acc_2}(\omega\cdot X)))\cdot(X-\omega^{\kappa-1})=0$
  5. $ (\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Acc_2}(X)\cdot\frac{(X^\kappa-1)}{(X-\omega^0)}=0$

These conditions, in turn, hold if:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Arr_1}(X)$
  2. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_2}(X)=\mathsf{Poly}_\mathsf{Arr_2}(X)$
  3. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Arr_1}(X)+\mathsf{Poly}_\mathsf{Acc_1}(\omega\cdot X)$
  4. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_2}(X)=\mathsf{Poly}_\mathsf{Arr_2}(X)+\mathsf{Poly}_\mathsf{Acc_2}(\omega\cdot X)$
  5. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Acc_2}(X)$

Where we get the “For $X$” due to zeroing parts of the polynomials (see zero1). Since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$, the above conditions are true if:

  1. The last value in $\mathsf{Acc_1}$ matches the last value in $\mathsf{Arr_1}$
  2. The last value in $\mathsf{Acc_2}$ matches the last value in $\mathsf{Arr_2}$
  3. The rest of the values in $\mathsf{Acc}_1$ are of the form $\mathsf{Acc_1}[i]=\mathsf{Arr_1}[i]+\mathsf{Acc_1}[i-1]$
  4. The rest of the values in $\mathsf{Acc}_2$ are of the form $\mathsf{Acc_2}[i]=\mathsf{Arr_2}[i]+\mathsf{Acc_2}[i-1]$
  5. The first value in $\mathsf{Acc_1}$ matches the first value in $\mathsf{Acc_2}$

Which are precisely the conditions the Intuitions sections explains will hold if the prover constructs their Accumulators by following the protocol and using $\mathsf{Arr}_1$ and $\mathsf{Arr_2}$ such that $\sum_{i = 0}^{n-1} \mathsf{Arr}_1[i] =\sum_{i = 0}^{n-1} \mathsf{Arr}_2[i] \space \forall i \in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.

Soundness +#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_{2}}(X)$, $\mathsf{Poly}_\mathsf{Arr_{2}}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_{2}}(X)$, $\mathsf{Poly}_\mathsf{Arr_{2}}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_\mathsf{Zero}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\sum_{i = 0}^{n-1} \mathsf{Arr_1}[i]\neq\sum_{i = 0}^{n-1} \mathsf{Arr_2}[i]$

Our proof is as follows:

For the second win condition to be fulfilled, one of the five constraints must be false. But then the $\mathsf{Poly}_\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_2}(X)$, and $\mathsf{Poly}_\mathsf{Arr_2}(X)$. Each commitment $\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_1}(\zeta \cdot \omega)$, $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_2}(\zeta)$, and $\mathsf{Poly}_\mathsf{Acc_2}(\zeta \cdot \omega)$ can each only feasibly be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4Y_\mathsf{Vanish5}}{(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4Y_\mathsf{Vanish5}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge #

We prove that the above protocol is zero-knowledge when $\mathsf{PolyCommit}_\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ that knows the trapdoor $\tau$, which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ chooses arbitrary values for ${\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Acc_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$ and $\mathsf{Poly}_\mathsf{Acc_2}(\tau)$, then computes $g^{\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, $g^{\mathsf{Poly}_\mathsf{Acc_1}(\tau)}$, $g^{\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$, and $g^{\mathsf{Poly}_\mathsf{Acc_2}(\tau)}$ to write as the commitments $K_\mathsf{Arr_1}$, $ K_\mathsf{Acc_1}$, $K_\mathsf{Arr_2}$, and $ K_\mathsf{Acc_2}$. $\mathcal{S}$ then generates the challenge evaluation point $\rho$ (by strong Fiat-Shamir) and computes $Q(\tau)$ using $\rho$ and the values it chose for ${\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Acc_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$ and $\mathsf{Poly}_\mathsf{Acc_2}(\tau)$. $\mathcal{S}$ writes the commitment $K_Q = g^{Q(\tau)}$.

Now, $\mathcal{S}$ generates the second random challenge point $\zeta$ (which we assume is not in $\mathcal{H}_\kappa$; if it is in $\mathcal{H}_\kappa$, $\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\mathcal{S}$ then create fake opening proofs for ${\mathsf{Poly}_\mathsf{Arr_1}(\zeta)}$, ${\mathsf{Poly}_\mathsf{Acc_1}(\zeta)}$, ${\mathsf{Poly}_\mathsf{Acc_1}(\zeta \cdot \omega)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\zeta)}$, ${\mathsf{Poly}_\mathsf{Acc_2}(\zeta)}$, and $\mathsf{Poly}_\mathsf{Acc_2}(\zeta\cdot\omega)$, to arbitrary values. This is done using the knowledge of $\tau$, calculating the respective witness $q(\tau) = \frac{{f(\tau) - f(\zeta)}}{\tau - \zeta}$ for each of the polynomials.

Finally, $\mathcal{S}$ creates a fake opening proof for $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4Y_\mathsf{Vanish5}}{(\zeta^\kappa - 1)}$. This is done using knowledge of $\tau$ to calculate an accepting witness $q(\tau)$, as above. This means that $Y_\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

  • For mult2, the proof is written with a simulator that doesn’t know the trapdoor; however, with small alterations the proof for mult2 should apply here and vice versa
\ No newline at end of file diff --git a/docs/gadgets/circuit/index.html b/docs/gadgets/circuit/index.html index 64d5c78..183a9c2 100644 --- a/docs/gadgets/circuit/index.html +++ b/docs/gadgets/circuit/index.html @@ -1,7 +1,7 @@ Circuit | Handbook - +
Circuit

Circuit @@ -27,6 +27,6 @@ \displaylines{Y_\mathsf{Vanish}=[\mathsf{Poly}_\mathsf{T}(\zeta\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{T}(\zeta)+\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega))\\+(1-\mathsf{Poly}_\mathsf{T}(\zeta\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega^2))+\\\mathsf{Poly}_\mathsf{In}(\zeta\omega^2)-\mathsf{Poly}_\mathsf{In}(\zeta\omega^3)]\cdot\frac{\zeta^\kappa-1}{\zeta-\omega^0}} $$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\rho$ and $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Security Proof #

Completeness -#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{In}$ that satisfies the circuit $\mathsf{T}$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$= \mathsf{Poly}_\mathsf{Vanish}(\zeta)-Q(\zeta)\cdot(\zeta^{\kappa}-1)$

$= [\mathsf{Poly}_\mathsf{T}(\zeta\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{T}(\zeta)+\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega))+(1-\mathsf{Poly}_\mathsf{T}(\zeta\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega^2))+\\\mathsf{Poly}_\mathsf{In}(\zeta\omega^2)-\mathsf{Poly}_\mathsf{In}(\zeta\omega^3)]\cdot\frac{\zeta^\kappa-1}{\zeta-\omega^0} -Q(\zeta)\cdot(\zeta^\kappa-1)$

$= [\mathsf{Poly}_\mathsf{T}(\zeta\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{T}(\zeta)+\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega))+(1-\mathsf{Poly}_\mathsf{T}(\zeta\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega^2))+\\\mathsf{Poly}_\mathsf{In}(\zeta\omega^2)-\mathsf{Poly}_\mathsf{In}(\zeta\omega^3)]\cdot\frac{\zeta^\kappa-1}{\zeta-\omega^0} - \frac{\mathsf{Poly}_\mathsf{Vanish}(\zeta)}{\zeta^\kappa-1} \cdot(\zeta^\kappa-1)$

$= [\mathsf{Poly}_\mathsf{T}(\zeta\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{T}(\zeta)+\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega))+(1-\mathsf{Poly}_\mathsf{T}(\zeta\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega^2))+\\\mathsf{Poly}_\mathsf{In}(\zeta\omega^2)-\mathsf{Poly}_\mathsf{In}(\zeta\omega^3)]\cdot\frac{\zeta^\kappa-1}{\zeta-\omega^0} \newline - [[\mathsf{Poly}_\mathsf{T}(\zeta\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{T}(\zeta)+\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega))+(1-\mathsf{Poly}_\mathsf{T}(\zeta\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega^2))+\\\mathsf{Poly}_\mathsf{In}(\zeta\omega^2)-\mathsf{Poly}_\mathsf{In}(\zeta\omega^3)]\cdot\frac{\zeta^\kappa-1}{\zeta-\omega^0} \cdot(\zeta^\kappa-1)]$

$=0$

Where the third equality relies on the fact that $\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\kappa -1$. This is true if $\mathsf{Poly_{Vanish}}(\zeta)$ is vanishing on $\mathcal{H}_\kappa$, i.e. if:

$\mathsf{Poly}_\mathsf{T}(\zeta\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{T}(\zeta)+\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega))+(1-\mathsf{Poly}_\mathsf{T}(\zeta\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega^2))\\+\mathsf{Poly}_\mathsf{In}(\zeta\omega^2)-\mathsf{Poly}_\mathsf{In}(\zeta\omega^3)]\cdot\frac{\zeta^\kappa-1}{\zeta-\omega^0} = 0$

Which hold if, for $X=\omega^0$:

$ \mathsf{Poly}_\mathsf{T}(X\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(X)\cdot\mathsf{Poly}_\mathsf{T}(X)+\mathsf{Poly}_\mathsf{In}(X\omega)\cdot\mathsf{Poly}_\mathsf{T}(X\omega))+(1-\mathsf{Poly}_\mathsf{T}(X\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(X)\cdot\mathsf{Poly}_\mathsf{In}(X\omega)\cdot\mathsf{Poly}_\mathsf{T}(X\omega^2))\\+\mathsf{Poly}_\mathsf{In}(X\omega^2)=\mathsf{Poly}_\mathsf{In}(X\omega^3)$

Where we get the “for $X = \omega^0$” due to zeroing parts of the polynomials (see zero1). Since $\mathsf{Poly_T}(\omega^i) = \mathsf{T}[i]$ and $\mathsf{Poly_{In}}(\omega^i) = \mathsf{In}[i]$, $\forall i \in [0, \kappa - 1]$, the above conditions are true if:

$\mathsf{T}[3]\cdot(\mathsf{In}[0]\cdot\mathsf{T}[0]+\mathsf{In}[1]\cdot\mathsf{T}[1])+(1-\mathsf{T}[3])\cdot(\mathsf{In}[0]\cdot\mathsf{In}[1]\cdot\mathsf{T}[2])+\mathsf{In}[2]=\mathsf{In}[3]$

But this means precisely that $\mathsf{In}$ satisfies the circuit $\mathsf{T}$, which was the condition we assumed about the prover. Thus, the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.

Soundness +#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{In}$ that satisfies the circuit $\mathsf{T}$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$= \mathsf{Poly}_\mathsf{Vanish}(\zeta)-Q(\zeta)\cdot(\zeta^{\kappa}-1)$

$= [\mathsf{Poly}_\mathsf{T}(\zeta\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{T}(\zeta)+\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega))+(1-\mathsf{Poly}_\mathsf{T}(\zeta\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega^2))+\\\mathsf{Poly}_\mathsf{In}(\zeta\omega^2)-\mathsf{Poly}_\mathsf{In}(\zeta\omega^3)]\cdot\frac{\zeta^\kappa-1}{\zeta-\omega^0} -Q(\zeta)\cdot(\zeta^\kappa-1)$

$= [\mathsf{Poly}_\mathsf{T}(\zeta\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{T}(\zeta)+\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega))+(1-\mathsf{Poly}_\mathsf{T}(\zeta\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega^2))+\\\mathsf{Poly}_\mathsf{In}(\zeta\omega^2)-\mathsf{Poly}_\mathsf{In}(\zeta\omega^3)]\cdot\frac{\zeta^\kappa-1}{\zeta-\omega^0} - \frac{\mathsf{Poly}_\mathsf{Vanish}(\zeta)}{\zeta^\kappa-1} \cdot(\zeta^\kappa-1)$

$= [\mathsf{Poly}_\mathsf{T}(\zeta\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{T}(\zeta)+\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega))+(1-\mathsf{Poly}_\mathsf{T}(\zeta\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega^2))+\\\mathsf{Poly}_\mathsf{In}(\zeta\omega^2)-\mathsf{Poly}_\mathsf{In}(\zeta\omega^3)]\cdot\frac{\zeta^\kappa-1}{\zeta-\omega^0} \newline - [[\mathsf{Poly}_\mathsf{T}(\zeta\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{T}(\zeta)+\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega))+(1-\mathsf{Poly}_\mathsf{T}(\zeta\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega^2))+\\\mathsf{Poly}_\mathsf{In}(\zeta\omega^2)-\mathsf{Poly}_\mathsf{In}(\zeta\omega^3)]\cdot\frac{\zeta^\kappa-1}{\zeta-\omega^0} \cdot(\zeta^\kappa-1)]$

$=0$

Where the third equality relies on the fact that $\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\kappa -1$. This is true if $\mathsf{Poly_{Vanish}}(\zeta)$ is vanishing on $\mathcal{H}_\kappa$, i.e. if:

$\mathsf{Poly}_\mathsf{T}(\zeta\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{T}(\zeta)+\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega))+(1-\mathsf{Poly}_\mathsf{T}(\zeta\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(\zeta)\cdot\mathsf{Poly}_\mathsf{In}(\zeta\omega)\cdot\mathsf{Poly}_\mathsf{T}(\zeta\omega^2))\\+\mathsf{Poly}_\mathsf{In}(\zeta\omega^2)-\mathsf{Poly}_\mathsf{In}(\zeta\omega^3)]\cdot\frac{\zeta^\kappa-1}{\zeta-\omega^0} = 0$

Which hold if, for $X=\omega^0$:

$ \mathsf{Poly}_\mathsf{T}(X\omega^3)\cdot(\mathsf{Poly}_\mathsf{In}(X)\cdot\mathsf{Poly}_\mathsf{T}(X)+\mathsf{Poly}_\mathsf{In}(X\omega)\cdot\mathsf{Poly}_\mathsf{T}(X\omega))+(1-\mathsf{Poly}_\mathsf{T}(X\omega^3))\cdot(\mathsf{Poly}_\mathsf{In}(X)\cdot\mathsf{Poly}_\mathsf{In}(X\omega)\cdot\mathsf{Poly}_\mathsf{T}(X\omega^2))\\+\mathsf{Poly}_\mathsf{In}(X\omega^2)=\mathsf{Poly}_\mathsf{In}(X\omega^3)$

Where we get the “for $X = \omega^0$” due to zeroing parts of the polynomials (see zero1). Since $\mathsf{Poly_T}(\omega^i) = \mathsf{T}[i]$ and $\mathsf{Poly_{In}}(\omega^i) = \mathsf{In}[i]$, $\forall i \in [0, \kappa - 1]$, the above conditions are true if:

$\mathsf{T}[3]\cdot(\mathsf{In}[0]\cdot\mathsf{T}[0]+\mathsf{In}[1]\cdot\mathsf{T}[1])+(1-\mathsf{T}[3])\cdot(\mathsf{In}[0]\cdot\mathsf{In}[1]\cdot\mathsf{T}[2])+\mathsf{In}[2]=\mathsf{In}[3]$

But this means precisely that $\mathsf{In}$ satisfies the circuit $\mathsf{T}$, which was the condition we assumed about the prover. Thus, the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.

Soundness #

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g,g^\tau,g^{\tau^2},\dots,g^{\tau^{n-1}}]$, $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{In}(X)$ and $Q$
  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{In}(X)$ and $Q$
  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_\mathsf{Zero}$ is zero at a random challenge $\zeta$
  4. $\mathcal{A}$ wins if
    • $\mathcal{V}$ accepts at the end of the protocol
    • the values in $\mathsf{In}$ do not satisfy the circuit

The proof is trivial: to make $\mathsf{Poly}_\mathsf{Vanish}$ exist, the values in $\mathsf{In}$ have to satisfy the circuit. By the Schwartz-Zippel lemma, the soundness error is $\kappa/|\mathbb{F}|$, which is negligible since $\kappa=4$ and $\mathbb{F}$ is enormous for any widely used elliptic curve.

Zero-Knowledge #

To prove the above protocol is zero-knowledge, we do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ randomly generates $a$ and $b$ as the inputs of the circuit, and runs the circuit to compute the output $c$. Then $\mathcal{S}$ follows the same steps a prover would prove the lookup argument. $\mathcal{S}$ interpolates $\mathsf{Poly}_\mathsf{In^*}$ from $\mathsf{In^*}$. It computes $Q^*(X)$ and finally outputs the commitments to each of these polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\zeta^*$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\mathsf{Poly}_\mathsf{T^*}$ and $\mathsf{Poly}_\mathsf{In^*}$ at $\zeta^*,\zeta^*\omega,\zeta^*\omega^2,\zeta^*\omega^3$ respectively, and $Q^*(\zeta^*)$, and writes these to the transcript as well. Since $\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

\ No newline at end of file diff --git a/docs/gadgets/concat/index.html b/docs/gadgets/concat/index.html index e6691e4..e8971fd 100644 --- a/docs/gadgets/concat/index.html +++ b/docs/gadgets/concat/index.html @@ -1,5 +1,5 @@ Concat | Handbook - +
Concat

Concatenation @@ -19,5 +19,5 @@ #

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) are too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.

The prover will write the following commitments to the transcript:

  • $K_{\mathsf{Arr}_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_{\mathsf{Arr}_1}(X))$
  • $K_{\mathsf{Arr}_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_{\mathsf{Arr}_2}(X))$
  • $K_{\mathsf{Arr}_3}=\mathsf{KZG.Commit}(\mathsf{Poly}_{\mathsf{Arr}_3}(X))$
  • $K_{\mathsf{Arr}_2^\prime}=\mathsf{KZG.Commit}(\mathsf{Poly}_{\mathsf{Arr}_2^\prime}(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:

  • $\rho$
  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$
  • $\mathsf{Poly}_{\mathsf{Arr}_1}(\zeta)=\mathsf{KZG.Open}(K_{\mathsf{Arr}_1},\zeta)$
  • $\mathsf{Poly}_{\mathsf{Arr}_2}(\zeta)=\mathsf{KZG.Open}(K_{\mathsf{Arr}_2},\zeta)$
  • $\mathsf{Poly}_{\mathsf{Arr}_3}(\zeta)=\mathsf{KZG.Open}(K_{\mathsf{Arr}_3},\zeta)$
  • $\mathsf{Poly}_{\mathsf{Arr}_2^\prime}(\zeta\omega^{n_1})=\mathsf{KZG.Open}(K_{\mathsf{Arr}_2^\prime},\zeta\omega^{n_1})$
  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish1}=\mathsf{Poly}_{\mathsf{Arr}_3}(\zeta)-\mathsf{Poly}_{\mathsf{Arr}_1}(\zeta)-\mathsf{Poly}_{\mathsf{Arr}_2^\prime}(\zeta)$
  • $Y_\mathsf{Vanish2}=\mathsf{Poly}_{\mathsf{Arr}_2}(\zeta)-\mathsf{Poly}_{\mathsf{Arr}_2^\prime}(\zeta\omega^{n_1})$
  • $Y_\mathsf{Vanish3}=\mathsf{Poly}_{\mathsf{Arr}_1}(\zeta)\cdot\frac{\zeta^\kappa-1}{\prod_{i=n_1}^{n_1+n_2-1}(\zeta-\omega^i)}$
  • $Y_\mathsf{Vanish4}=\mathsf{Poly}_{\mathsf{Arr}_2}(\zeta)\cdot\frac{\zeta^\kappa-1}{\prod_{i=n_2}^{n_1+n_2-1}(\zeta-\omega^i)}$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish1}+\rho\cdot{Y_\mathsf{Vanish2}}+\rho^2\cdot{Y_\mathsf{Vanish3}}+\rho^3\cdot{Y_\mathsf{Vanish4}}-Q(\zeta)\cdot(\zeta^n-1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\rho$ and $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Security Proof #

Completeness #

Any honest prover can do the computations explained above and create an accepting proof.

Soundness -#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g,g^\tau,g^{\tau^2},\dots,g^{\tau^{n-1}}]$, $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_{\mathsf{Arr}_1}(X)$, $\mathsf{Poly}_{\mathsf{Arr}_2}(X)$, $\mathsf{Poly}_{\mathsf{Arr}_3}(X)$, $\mathsf{Poly}_{\mathsf{Arr}_2^\prime}(X)$, and $Q$
  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_{\mathsf{Arr}_1}(X)$, $\mathsf{Poly}_{\mathsf{Arr}_2}(X)$, $\mathsf{Poly}_{\mathsf{Arr}_3}(X)$, $\mathsf{Poly}_{\mathsf{Arr}_2^\prime}(X)$, and $Q$
  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_\mathsf{Zero}$ is zero at a random challenge $\zeta$
  4. $\mathcal{A}$ wins if
    • $\mathcal{V}$ accepts at the end of the protocol
    • $\mathsf{Arr}_3$ is not the concatenation of $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$

Our proof is as follows:

When $\mathsf{Arr}_3$ is not the concatenation of $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$, there are three cases: some elemnets in $\mathsf{Arr}_1$ do not appear in $\mathsf{Arr}_3$, or some elements in $\mathsf{Arr}_2$ do not appear in $\mathsf{Arr}_3$, or both of the previous situations. Since $\mathcal{A}$ has to win the KS game in the first and the second cases if $\mathcal{A}$ wants to win the game in the last case, it suffices to check any one of the first two situations. Now assume there are some elements in $\mathsf{Arr}_1$ do not exist in $\mathsf{Arr}_3$. Because the first $n_1$ elements in $\mathsf{Arr}_2^\prime$ are zero, we know that the equation $\mathsf{Arr}_3[i]=\mathsf{Arr}_1[i]+\mathsf{Arr}_2^\prime[i]$ does not hold for some $i\in[0,n_1)$. Thus, for $\mathsf{Poly}_\mathsf{Vanish1}$, $Q_1$ does not exist (it is a rational function, not a polynomial), which means the probability that $Y_\mathsf{Zero}$ is a zero polynomial is negligible.

Zero-Knowledge +#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g,g^\tau,g^{\tau^2},\dots,g^{\tau^{n-1}}]$, $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_{\mathsf{Arr}_1}(X)$, $\mathsf{Poly}_{\mathsf{Arr}_2}(X)$, $\mathsf{Poly}_{\mathsf{Arr}_3}(X)$, $\mathsf{Poly}_{\mathsf{Arr}_2^\prime}(X)$, and $Q$
  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_{\mathsf{Arr}_1}(X)$, $\mathsf{Poly}_{\mathsf{Arr}_2}(X)$, $\mathsf{Poly}_{\mathsf{Arr}_3}(X)$, $\mathsf{Poly}_{\mathsf{Arr}_2^\prime}(X)$, and $Q$
  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_\mathsf{Zero}$ is zero at a random challenge $\zeta$
  4. $\mathcal{A}$ wins if
    • $\mathcal{V}$ accepts at the end of the protocol
    • $\mathsf{Arr}_3$ is not the concatenation of $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$

Our proof is as follows:

When $\mathsf{Arr}_3$ is not the concatenation of $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$, there are three cases: some elements in $\mathsf{Arr}_1$ do not appear in $\mathsf{Arr}_3$, or some elements in $\mathsf{Arr}_2$ do not appear in $\mathsf{Arr}_3$, or both of the previous situations. Since $\mathcal{A}$ has to win the KS game in the first and the second cases if $\mathcal{A}$ wants to win the game in the last case, it suffices to check any one of the first two situations. Now assume there are some elements in $\mathsf{Arr}_1$ do not exist in $\mathsf{Arr}_3$. Because the first $n_1$ elements in $\mathsf{Arr}_2^\prime$ are zero, we know that the equation $\mathsf{Arr}_3[i]=\mathsf{Arr}_1[i]+\mathsf{Arr}_2^\prime[i]$ does not hold for some $i\in[0,n_1)$. Thus, for $\mathsf{Poly}_\mathsf{Vanish1}$, $Q_1$ does not exist (it is a rational function, not a polynomial), which means the probability that $Y_\mathsf{Zero}$ is a zero polynomial is negligible.

Zero-Knowledge #

To prove the above protocol is zero-knowledge, we do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ randomly generates $\mathsf{Arr}_1^*$ and $\mathsf{Arr}_2^*$ and computes $\mathsf{Arr}_3^*$, then follows the same steps a prover would prove the concatenation. $\mathcal{S}$ computes $\mathsf{Arr}_2^{\prime*}$ and interpolates $\mathsf{Poly}_{\mathsf{Arr}_1^*}$, $\mathsf{Poly}_{\mathsf{Arr}_2^*}$, $\mathsf{Poly}_{\mathsf{Arr}_3^*}$, and $\mathsf{Poly}_{\mathsf{Arr}_2^{\prime*}}$. It computes $Q^*(X)$ and finally outputs the commitments to each of these polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\zeta^*$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\mathsf{Poly}_{\mathsf{Arr}_1^*}(\zeta^*)$, $\mathsf{Poly}_{\mathsf{Arr}_2^*}(\zeta^*)$, $\mathsf{Poly}_{\mathsf{Arr}_3^*}(\zeta^*)$, and $\mathsf{Poly}_{\mathsf{Arr}_2^{\prime*}}(\zeta^*\omega^{n_1})$, and $Q^*(\zeta^*)$, and writes these to the transcript as well. Since $\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

\ No newline at end of file diff --git a/docs/gadgets/encode/index.html b/docs/gadgets/encode/index.html index 5d0f8a9..2f4d7fa 100644 --- a/docs/gadgets/encode/index.html +++ b/docs/gadgets/encode/index.html @@ -1,19 +1,19 @@ Encode | Handbook - +
Encode

Encode #

Relation #

$ \mathcal{R}_{\mathtt{mult3}} := \left\{ \begin{array}{l} (K_\mathsf{Arr_1},K_\mathsf{Arr2}, \end{array} \middle | \begin{array}{l} \mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \dots, a_{(1,n-1)}],\\ \mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \dots, a_{(2,n-1)}], \\ \mathsf{Poly}_\mathsf{Arr_1}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr_1}), \\ \mathsf{Poly}_\mathsf{Arr_2}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr_2}), \\ K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}),\\ K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}), \end{array} \right\} $

Intuition -#

The prover ($\mathcal{P}$) holds two arrays $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ of $n$ integers from $\mathbb{Z}_q$: $[a_0, a_1, a_2, \dots, a_{n-1}]$. It wishes to map the pairs of elements, $\{ \mathsf{Arr_1[i], \mathsf{Arr_2[i]}}\}$ into a single element, $\mathsf{Arr_3}[i]$ without collisions. It will produce a succinct (independent of $n$) proof that $\mathsf{Arr_3}$ contains the encoding of $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ according to this mapping.

For the mapping scheme, we use random linear combinations, since it is both collision resistant and it can be proven in zero knowledge. To do so, the prover defines $f_i(X) = \mathsf{Arr_1}[i] + \mathsf{Arr_2}[i] \cdot X$ for $i \in [0, n-1]$. Then, the the prover calculates $\mathsf{Arr_3}[i] = f_i(r)$ for a random field element $r$. Assuming $f_i$ is commited to before $r$ is know, this scheme is collision resistant by the Schwartz-Zippel lemma; if two polynomials are equal at $r$ then with overwhelming probability they are the same polynomial. However, to ensure negligible probabilty of collisions, $n$ may need to be smaller relative to the field size than initially thought. This is due to the birthday paradox. We are not evaluating the probability that a single one of the $n$ polynomials collides with one of the other $n-1$ polynomials, but rather the probability than any one polynomial out of $n$ collides with any other of the $n-1$ polynomials. The value of the latter is significantly larger, since it compares every possible pair of the $n$ polynomials, instead of just comparing one of the polynomials with the $n-1$ other polynomials. The probability of collisions can, however, still be made sufficiently small by bounding how large $n$ can be relative to the field size.

In order to prove the relation, the prover will encode the three arrays into three polynomials: $\mathsf{Poly}_\mathsf{Arr_1}$, $\mathsf{Poly}_\mathsf{Arr_2}$, and $\mathsf{Poly}_\mathsf{Arr_3}$ (using evaluation points on the domain $\mathcal{H}_\kappa$). It will commit to each polynomial: $K_\mathsf{Arr_1}$, $K_\mathsf{Arr_2}$, and $K_\mathsf{Arr_3}$. The verifier ($\mathcal{V}$) cannot check any of the $\mathsf{Arr_i}$ or $\mathsf{Poly}_\mathsf{Arr_i}$ values directly (they may contain secret information, and even if they do not, they are too long to check) so the verifier only sees $K_\mathsf{Arr_1}$,$K_\mathsf{Arr_2}$, and $K_\mathsf{Arr_3}$. It will use these commitments to verified the constraint $\mathsf{Arr_3}[i] = \mathsf{Arr_1}[i] + \mathsf{Arr_2}[i]\cdot r$.

Protocol Details +#

The prover ($\mathcal{P}$) holds two arrays $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ of $n$ integers from $\mathbb{Z}_q$: $[a_0, a_1, a_2, \dots, a_{n-1}]$. It wishes to map the pairs of elements, $\{ \mathsf{Arr_1[i], \mathsf{Arr_2[i]}}\}$ into a single element, $\mathsf{Arr_3}[i]$ without collisions. It will produce a succinct (independent of $n$) proof that $\mathsf{Arr_3}$ contains the encoding of $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ according to this mapping.

For the mapping scheme, we use random linear combinations, since it is both collision resistant and it can be proven in zero knowledge. To do so, the prover defines $f_i(X) = \mathsf{Arr_1}[i] + \mathsf{Arr_2}[i] \cdot X$ for $i \in [0, n-1]$. Then, the the prover calculates $\mathsf{Arr_3}[i] = f_i(r)$ for a random field element $r$. Assuming $f_i$ is committed to before $r$ is know, this scheme is collision resistant by the Schwartz-Zippel lemma; if two polynomials are equal at $r$ then with overwhelming probability they are the same polynomial. However, to ensure negligible probability of collisions, $n$ may need to be smaller relative to the field size than initially thought. This is due to the birthday paradox. We are not evaluating the probability that a single one of the $n$ polynomials collides with one of the other $n-1$ polynomials, but rather the probability than any one polynomial out of $n$ collides with any other of the $n-1$ polynomials. The value of the latter is significantly larger, since it compares every possible pair of the $n$ polynomials, instead of just comparing one of the polynomials with the $n-1$ other polynomials. The probability of collisions can, however, still be made sufficiently small by bounding how large $n$ can be relative to the field size.

In order to prove the relation, the prover will encode the three arrays into three polynomials: $\mathsf{Poly}_\mathsf{Arr_1}$, $\mathsf{Poly}_\mathsf{Arr_2}$, and $\mathsf{Poly}_\mathsf{Arr_3}$ (using evaluation points on the domain $\mathcal{H}_\kappa$). It will commit to each polynomial: $K_\mathsf{Arr_1}$, $K_\mathsf{Arr_2}$, and $K_\mathsf{Arr_3}$. The verifier ($\mathcal{V}$) cannot check any of the $\mathsf{Arr_i}$ or $\mathsf{Poly}_\mathsf{Arr_i}$ values directly (they may contain secret information, and even if they do not, they are too long to check) so the verifier only sees $K_\mathsf{Arr_1}$,$K_\mathsf{Arr_2}$, and $K_\mathsf{Arr_3}$. It will use these commitments to verified the constraint $\mathsf{Arr_3}[i] = \mathsf{Arr_1}[i] + \mathsf{Arr_2}[i]\cdot r$.

Protocol Details #

Array Level #

  • $\mathcal{P}$ holds an array $\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \dots, a_{(1,n-1)}]$
  • $\mathcal{P}$ holds an array $\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \dots, a_{(2, n-1)}]$
  • $\mathcal{P}$ generates the random challenge $r$, then computes $\mathsf{Arr_3}$ as follows:
    • $\mathsf{Arr_3}[i] = \mathsf{Arr_1}[i] + \mathsf{Arr_2}[i]\cdot r$

Polynomial Level #

We assume that $\mathsf{Arr1}$, $\mathsf{Arr_2}$, and $\mathsf{Arr_3}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\mathcal{H}_\kappa$) are chosen as the multiplicative group of order $\kappa$ with generator $\omega\in\mathbb{G}_\kappa$ (see Background for more). In short, $\omega^0$ is the first element and $\omega^{\kappa-1}$ is the last element of $\mathcal{H}_\kappa$. If $\kappa$ is larger than the length of the arrays, the arrays can be padded with zeros.

Recall the constraint we want to prove:

  1. $\mathsf{Arr_3}[i] = f_i(X) =\mathsf{Arr_1}[i] + \mathsf{Arr_2}[i]\cdot r$

We write the constraint in polynomial form:

  1. For all $X$ from $\omega^0$ to $\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Arr_3}(X) = \mathsf{Poly}_\mathsf{Arr_1}(X) + \mathsf{Poly_{Arr_2}}(X)\cdot r$

We adjust the constraint to show an equality with 0 and label it:

  1. $\mathsf{Poly}_\mathsf{Vanish}(X)= \mathsf{Poly}_\mathsf{Arr_3}(X) - (\mathsf{Poly}_\mathsf{Arr_1}(X) + \mathsf{Poly_{Arr_2}}(X)\cdot r)= 0$

This equation is true for every value of $X \in \mathcal{H}_\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\kappa - 1$, which is a minimal vanishing polynomial for $\mathcal{H}_\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\mathsf{Poly}_\mathsf{Vanish}(X)$ must be vanishing on $\mathcal{H}_\kappa$ too. Specifically, the prover computes:

  1. $Q(X) = \frac{\mathsf{Poly}_\mathsf{Vanish}(X)}{X^\kappa - 1}$

By rearranging, we can get $\mathsf{Poly}_\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\mathcal{H}_\kappa$ and outside of it):

$\mathsf{Poly}_\mathsf{Zero}(X)=\mathsf{Poly}_\mathsf{Vanish}(X) - Q(X)\cdot (X^\kappa - 1)=0$

Ultimately the rotate argument will satisfy the following constraints at the Commitment Level:

  1. Show $Q(X)$ exists (as a polynomial that evenly divides the divisor)
  2. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is correctly constructed from $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly_{Arr_2}}$, and $\mathsf{Poly}_\mathsf{Arr_3}(X)$
  3. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is the zero polynomial

Commitment Level -#

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}(X))$
  • $K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}(X))$​

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call this point $r$. We note that since $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ were commited to before $r$ was know, $fi$ is commited to before $r$ is known. This is important for the collision resistance of our encoding scheme. Now, using $r$, the prover can compute and commit to the following polynomials:

  • $K_\mathsf{Arr_3}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_3}(X))$
  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$
  • $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_3}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_3},\zeta)$
  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish}= \mathsf{Poly}_\mathsf{Arr_3}(\zeta) - (\mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly_{Arr_2}}(\zeta)\cdot r)$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Implementations +#

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}(X))$
  • $K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}(X))$​

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call this point $r$. We note that since $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ were committed to before $r$ was know, $fi$ is committed to before $r$ is known. This is important for the collision resistance of our encoding scheme. Now, using $r$, the prover can compute and commit to the following polynomials:

  • $K_\mathsf{Arr_3}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_3}(X))$
  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$
  • $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_3}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_3},\zeta)$
  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish}= \mathsf{Poly}_\mathsf{Arr_3}(\zeta) - (\mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly_{Arr_2}}(\zeta)\cdot r)$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Implementations #

Security Proof #

Completeness #

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr}_3$ that is a random linear combination of $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ using $r$, can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$= Y_\mathsf{Vanish} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= \mathsf{Poly}_\mathsf{Arr_3}(\zeta) - (\mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly_{Arr_2}}(\zeta)\cdot r) - Q(\zeta)(\zeta^\kappa - 1)$

$= \mathsf{Poly}_\mathsf{Arr_3}(\zeta) - (\mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly_{Arr_2}}(\zeta)\cdot r) - \frac{\mathsf{Poly}_\mathsf{Vanish}(\zeta)}{\zeta^\kappa - 1}(\zeta^\kappa - 1)$

$= \mathsf{Poly}_\mathsf{Arr_3}(\zeta) - (\mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly_{Arr_2}}(\zeta)\cdot r) - (\mathsf{Poly}_\mathsf{Arr_3}(\zeta) - (\mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly_{Arr_2}}(\zeta)) \cdot r)$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\kappa -1$. This is true if $\mathsf{Poly_{Vanish}}(\zeta)$ is vanishing on $\mathcal{H}_\kappa$, i.e. if $(\mathsf{Poly}_\mathsf{Arr_3}(X) - (\mathsf{Poly}_\mathsf{Arr_1}(X) + \mathsf{Poly_{Arr_2}}(X)) \cdot r) = 0 \space \forall X \in \mathcal{H}_\kappa$. This is true if if $\mathsf{Arr}_3 - (\mathsf{Arr}_1 + \mathsf{Arr}_2 \cdot r) = 0 \space \forall i \in [0, \kappa - 1]$, since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$. But this is precisely the condition we assumed held for our prover, so the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and the transcript will be accepted.

Soundness -#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$, the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly}_\mathsf{Arr_3}(X)$ , $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly}_\mathsf{Arr_3}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Arr_3}[i] \neq \mathsf{Arr_1}[i] + \mathsf{Arr_1}[i]\cdot r$ for some $i \in [0, n-1]$

Our proof is as follows:

For the second win condition to be fulfilled, there must be some $i \in [0, n-1]$ such that $\mathsf{Arr_3}[i] \neq \mathsf{Arr_1}[i] + \mathsf{Arr_1}[i]\cdot r$. But then $\mathsf{Poly}_\mathsf{Vanish}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly_{Arr_2}}(X)$, and $\mathsf{Poly}_\mathsf{Arr_3}(X)$. All commitments $\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)$, $\mathsf{Poly_{Arr_2}}(\zeta)$, and $\mathsf{Poly}_\mathsf{Arr_3}(\zeta)$ can each only feasibliy be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish}} {(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge +#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$, the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly}_\mathsf{Arr_3}(X)$ , $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly}_\mathsf{Arr_3}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Arr_3}[i] \neq \mathsf{Arr_1}[i] + \mathsf{Arr_1}[i]\cdot r$ for some $i \in [0, n-1]$

Our proof is as follows:

For the second win condition to be fulfilled, there must be some $i \in [0, n-1]$ such that $\mathsf{Arr_3}[i] \neq \mathsf{Arr_1}[i] + \mathsf{Arr_1}[i]\cdot r$. But then $\mathsf{Poly}_\mathsf{Vanish}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly_{Arr_2}}(X)$, and $\mathsf{Poly}_\mathsf{Arr_3}(X)$. All commitments $\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)$, $\mathsf{Poly_{Arr_2}}(\zeta)$, and $\mathsf{Poly}_\mathsf{Arr_3}(\zeta)$ can each only feasibly be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish}} {(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge #

We prove that the above protocol is zero-knowledge when $\mathsf{PolyCommit}_\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ that knows the trapdoor $\tau$, which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ chooses arbitrary values for ${\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, $\mathsf{Poly_{Arr_2}}(\tau)$, and ${\mathsf{Poly}_\mathsf{Arr_3}(\tau)}$, then computes $g^{\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, $g^{\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$, and $g^{\mathsf{Poly}_\mathsf{Arr_3}(\tau)}$ to write as the commitments $ K_\mathsf{Arr_1}$, $ K_\mathsf{Arr_2}$ and $K_\mathsf{Arr_3}$. $\mathcal{S}$ computes $Q(\tau)$ using the values it chose for ${\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$, and ${\mathsf{Poly}_\mathsf{Arr_3}(\tau)}$. $\mathcal{S}$ writes the commitment $K_Q = g^{Q(\tau)}$.

Now, $\mathcal{S}$ generates the random challenge point $\zeta$ (which we assume is not in $\mathcal{H}_\kappa$; if it is in $\mathcal{H}_\kappa$, $\mathcal{S}$ simply restarts and runs from the beginning). This is by strong Fiat-Shamir. $\mathcal{S}$ then create fake opening proofs for ${\mathsf{Poly}_\mathsf{Arr_1}(\zeta)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\zeta)}$, and ${\mathsf{Poly}_\mathsf{Arr_3}(\zeta)}$, to arbitrary values. This is done using the knowledge of $\tau$, calculating the respective witness $q(\tau) = \frac{{f(\tau) - f(\zeta)}}{\tau - \zeta}$ for each of the polynomials.

Finally, $\mathcal{S}$ creates a fake opening proof for $Q(\zeta) = \frac{Y_\mathsf{Vanish}}{(\zeta^\kappa - 1)}$. This is done using knowledge of $\tau$ to calculate an accepting witness $q(\tau)$, as above. This means that $Y_\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

\ No newline at end of file diff --git a/docs/gadgets/folding/index.html b/docs/gadgets/folding/index.html index 09e5ebf..484c3a6 100644 --- a/docs/gadgets/folding/index.html +++ b/docs/gadgets/folding/index.html @@ -1,7 +1,7 @@ Folding | Handbook - +
Folding

Folding (Sangria) diff --git a/docs/gadgets/index.html b/docs/gadgets/index.html index 3de490c..9dbc629 100644 --- a/docs/gadgets/index.html +++ b/docs/gadgets/index.html @@ -1,5 +1,5 @@ Gadgets | Handbook - +
Gadgets

Select a gadget from the menu.

\ No newline at end of file diff --git a/docs/gadgets/lookup1/index.html b/docs/gadgets/lookup1/index.html index ea085f9..3348a2b 100644 --- a/docs/gadgets/lookup1/index.html +++ b/docs/gadgets/lookup1/index.html @@ -1,5 +1,5 @@ Lookup1 | Handbook - +
Lookup1

Lookup (Type 1) @@ -14,5 +14,5 @@ #

Security Proof #

Completeness #

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr}$ such that $\mathsf{Arr}[i] \in \{0, 1\} \forall 0 \leq i \leq n$, can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$= Y_\mathsf{Vanish} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$ = \mathsf{Poly}_\mathsf{Arr}(\zeta) \cdot (\mathsf{Poly}_\mathsf{Arr}(\zeta) - 1) - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$ = \mathsf{Poly}_\mathsf{Arr}(\zeta) \cdot (\mathsf{Poly}_\mathsf{Arr}(\zeta) - 1) - \frac{\mathsf{Poly}_\mathsf{Vanish}(\zeta)}{\zeta^\kappa - 1}\cdot (\zeta^\kappa - 1)$

$ = \mathsf{Poly}_\mathsf{Arr}(\zeta) \cdot (\mathsf{Poly}_\mathsf{Arr}(\zeta) - 1) - [\mathsf{Poly}_\mathsf{Arr}(\zeta) \cdot (\mathsf{Poly}_\mathsf{Arr}(\zeta) - 1)]$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\kappa -1$. This is true if $\mathsf{Poly_{Vanish}}(\zeta)$ is vanishing on $\mathcal{H}_\kappa$, i.e. if $\mathsf{Poly}_\mathsf{Arr}(X) \cdot (\mathsf{Poly}_\mathsf{Arr}(X) - 1) = 0 \space \forall X \in \mathcal{H}_\kappa$. This is true if $\mathsf{Arr}[i] \cdot (\mathsf{Arr}[i] - 1) = 0 \space \forall i \in [0, \kappa -1]$, since $\mathsf{Poly}(\omega^i) = \mathsf{Arr}[i] \space \forall i \in [0, \kappa - 1]$. But this is precisely the condition we assumed held for the prover (since the array gets padded with $1$’s or $0$’s if $n \lt \kappa$), so the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and the transcript will be accepted.

Soundness -#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr}(X)$, $Q(X)$.

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Arr}[i]\neq 0$ and $\mathsf{Arr}[i]\neq 1$ for some $i \in [0, n-1]$

Our proof is as follows:

For the second win condition to be fulfilled, there must be at least one entry is $\mathsf{Arr}$ that is not 0 or 1. But then $\mathsf{Poly}_\mathsf{Vanish}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes a commitment to $\mathsf{Poly}_\mathsf{Arr}(X)$. Both commitments $\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr}(\zeta)$, can only feasibliy be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1}}{(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge +#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr}(X)$, $Q(X)$.

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Arr}[i]\neq 0$ and $\mathsf{Arr}[i]\neq 1$ for some $i \in [0, n-1]$

Our proof is as follows:

For the second win condition to be fulfilled, there must be at least one entry is $\mathsf{Arr}$ that is not 0 or 1. But then $\mathsf{Poly}_\mathsf{Vanish}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes a commitment to $\mathsf{Poly}_\mathsf{Arr}(X)$. Both commitments $\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr}(\zeta)$, can only feasibly be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1}}{(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge #

We prove that the above protocol is zero-knowledge when $\mathsf{PolyCommit}_\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ that knows the trapdoor $\tau$, which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ chooses an arbitrary value for ${\mathsf{Poly}_\mathsf{Arr}(\tau)}$, then computes $g^{\mathsf{Poly}_\mathsf{Arr}(\tau)}$ to write as the commitment $ K_\mathsf{Arr}$. $\mathcal{S}$ then generates the challenge evaluation point $\rho$ (by strong Fiat-Shamir) and computes $Q(\tau)$ using $\rho$ and the value it chose for ${\mathsf{Poly}_\mathsf{Arr}(\tau)}$. $\mathcal{S}$ writes the commitment $K_Q = g^{Q(\tau)}$.

Now, $\mathcal{S}$ generates the second random challenge point $\zeta$ (which we assume is not in $\mathcal{H}_\kappa$; if it is in $\mathcal{H}_\kappa$, $\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\mathcal{S}$ then create fake opening proofs for ${\mathsf{Poly}_\mathsf{Arr}(\zeta)}$, to an arbitrary value. This is done using the knowledge of $\tau$, calculating the witness polynomial $q(\tau) = \frac{{f(\tau) - f(\zeta)}}{\tau - \zeta}$.

Finally, $\mathcal{S}$ creates a fake opening proof for $Q(\zeta) = \frac{Y_\mathsf{Vanish1}}{(\zeta^\kappa - 1)}$. This is done using knowledge of $\tau$ to calculate an accepting witness $q(\tau)$, as above. This means that $Y_\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

\ No newline at end of file diff --git a/docs/gadgets/lookup2/index.html b/docs/gadgets/lookup2/index.html index 008034b..00bb69a 100644 --- a/docs/gadgets/lookup2/index.html +++ b/docs/gadgets/lookup2/index.html @@ -1,5 +1,5 @@ Lookup2 | Handbook - +
Lookup2

Lookup (Type 2) @@ -13,7 +13,7 @@ $$ \mathsf{T}^\prime=\{0,1,7,2,3,4,5,6\} $$

We can observe that $\mathsf{Arr}^\prime[i]$ is equal to $\mathsf{T}^\prime[i]$ or $\mathsf{Arr}^\prime[i-1]$. Since $\mathsf{Arr}^\prime[i-1]$ does not exist when $i=0$, we have to enforce the other rule, $\mathsf{Arr}^\prime[0]=\mathsf{T}^\prime[0]$. With these two constraints and the proof that $\mathsf{Arr}^\prime$ is the permutation of $\mathsf{Arr}$ and $\mathsf{T}^\prime$ is the permutation of $\mathsf{T}$, the prover can prove each element in $\mathsf{Arr}$ exists in $\mathsf{T}$.

Plookup -#

We start with an unoptimized version of Plookup that is conceptually simpler than the final version and is still fully succinct. The inputs are: an array containing the values of the lookup table $\mathsf{T}$ of size $n_1$; and an array of length $n_2$ (typically longer than $n_1$ but not necessarily) that will be proven to contain only values from somewhere in $\mathsf{T}$.

The prover will create 5 helper arrays ($\mathsf{Acc_1}$ to $\mathsf{Acc_5}$) to demonstrate this overall property ($\mathsf{Arr}[i]\in\mathsf{T}$ for all $i$). The helper arrays will each be of size $n_1+n_2$ with the exception of $\mathsf{Acc_4}$ which is $n_2$. They are as follows:

  1. $\mathsf{Acc_1}=\mathsf{Arr}||\mathsf{T}$
  2. $\mathsf{Acc_2}=\mathtt{Sort}(\mathsf{Acc_1})$
  3. $\mathsf{Acc_3}[i]=\mathsf{Acc_2}[i+1]-\mathsf{Acc_2}[i]$
  4. $\mathsf{Acc_4}[i]=\mathsf{T}[i+1]-\mathsf{T}[i]$
  5. $\mathsf{Acc_5}=\mathsf{Acc_4}||\{0\}^{n_2}$ where $n_1=|\mathsf{Arr}|$

It is probably worth an example at this point.

  • $\mathsf{T}=[7,0,15,3]$
  • $\mathsf{Arr}=[7,0,15,15,7,7,15,0,0,7,15,7]$
  • $\mathsf{Acc_1}=[7,0,15,15,7,7,15,0,0,7,15,7,7,0,15,3]$
  • $\mathsf{Acc_2}=[7,7,7,7,7,7,0,0,0,0,15,15,15,15,15,3]$
  • $\mathsf{Acc_3}=[0,0,0,0,0,-7,0,0,0,15,0,0,0,0,-12,\bot]$
  • $\mathsf{Acc_4}=[-7,15,-12,\bot]$
  • $\mathsf{Acc_5}=[-7,15,-12,\bot,0,0,0,0,0,0,0,0,0,0,0,0]$

The first array $\mathsf{Acc_1}$ is the concatination for $\mathsf{Arr}$ and $\mathsf{T}$. The intuition for this is as follows. Every element of $\mathsf{Arr}$ is in $\mathsf{T}$ (what is being proven) but the converse is not true, not every element of $\mathsf{T}$ is necessarily in $\mathsf{Arr}$. By constructing $\mathsf{Acc_1}$, the prover has an array where every element of $\mathsf{T}$ appears at least once. This will be convenient later. Additionally, if the prover can show every element in $\mathsf{Acc_1}$ is in $\mathsf{T}$, it implies every element in the original $\mathsf{Arr}$ is in $\mathsf{T}$ so it can now move forward with $\mathsf{Acc_1}$.

How does $\mathsf{Acc_1}$ compare to $\mathsf{T}$? They both have the same elements but $\mathsf{Acc_1}$ has a bunch of extra duplicates of values. Also the appearance of elements in $\mathsf{Acc_1}$ are in a different (arbitrary) order. Next the prover will sort the values of $\mathsf{Acc_1}$, grouping all duplicates together, and having them appear in the same order as the original $\mathsf{T}$ (which does not have to be sorted).

Now how does $\mathsf{Acc_2}$ compare to $\mathsf{T}$? They have the same elements in the same order (including 3 which is not in the original $\mathsf{Arr}$) however $\mathsf{Acc_2}$ has a bunch of duplicates of some of the elements. Next we want to “flag” all the elements that are duplicates. The way we do this is to take the difference between each neighbouring elements. If the neighbouring elements are the same (duplicates), this is will place a 0 in that position. If they are not, a non-zero number will appear instead.

This is straight-forward until we hit the last element in $\mathsf{Acc_2}$ and $\mathsf{Acc_3}$ which has no “next” element in the array. We will leave it for now as an arbitrary integer $\bot$.

We have marked the duplicates elements but have some other integers when neighbouring elements are not the same. The idea is do the same thing with $\mathsf{T}$ and we create $\mathsf{Acc_4}$, which we then pad with $n_2$ zeros.

  • $\mathsf{Acc_5}=[-7,15,-12,\bot,0,0,0,0,0,0,0,0,0,0,0,0]$

If $\mathsf{Acc_5}$ is a permutation of $\mathsf{Acc_3}$ and everything else is correctly constructed, then all elements in $\mathsf{Arr}$ are from $\mathsf{T}$.

The prover will show that $\mathsf{Acc_1}$ is constructed correctly with the $\mathtt{concat}$ gadget. It will not prove that $\mathsf{Acc_2}$ is sorted correctly (if it does not sort it correctly, the protocol will not work) but it will prove that $\mathsf{Acc_2}$ is a permutation of $\mathsf{Acc_1}$ using $\mathtt{shuffle1}(\mathsf{Acc_1},\mathsf{Acc_2})$. It will prove $\mathsf{Acc_3}$ is constructed correctly by $\mathsf{add1}(\mathsf{Acc_2}[i+1],-\mathsf{Acc_2}[i])$ and $\mathsf{Acc_3}$ is $\mathsf{add1}(\mathsf{T}[i+1],-\mathsf{T}[i])$. Last, it will prove that $\mathsf{Acc_5}$ is correctly formed with $\mathtt{concat}$ and finally, that it is a permutation of $\mathsf{Acc_3}$ with $\mathtt{shuffle1}(\mathsf{Acc_5},\mathsf{Acc_3})$.

$\mathsf{T}$ to the end of $\mathsf{Arr}$ does not change anything about the arguement

In fact, the only difference betweeen $\mathsf{Acc_1}$ and $\mathsf{T}$ itself is that there are serveral duplicates

With these arrays, the following constraints are demonstrated:

  1. Uses $\mathtt{concat}$ gadget
  2. Uses $\mathtt{shuffle1}(\mathsf{Acc_1},\mathsf{Acc_2})$
  3. Uses $\mathsf{add1}(\mathsf{Acc_2}[i+1],-\mathsf{Acc_2}[i])$
  4. Uses $\mathsf{add1}(\mathsf{T}[i+1],-\mathsf{T}[i])$
  5. Uses $\mathtt{concat}$ and then $\mathtt{shuffle1}(\mathsf{Acc_5},\mathsf{Acc_3})$

Unlike halo2, Plookup requires only one auxiliary vector, $\mathsf{S}$, where $\mathsf{S}$ is the union set of $\mathsf{Arr}$ and $\mathsf{T}$, and sorted by $\mathsf{T}$. The prover encodes $\mathsf{Arr}$, $\mathsf{T}$, and $\mathsf{S}$ into polynomials: $\mathsf{Poly}_\mathsf{Arr}$, $\mathsf{Poly}_\mathsf{T}$, and $\mathsf{Poly}_\mathsf{S}$, and computes $\prod{\mathsf{Poly}_\mathsf{Arr}\cdot\prod\mathsf{Poly}_\mathsf{T}}$ and $\prod{\mathsf{Poly}_\mathsf{S}}$ with some random challenges. The theorem tells us the two products are equal if and only if: $\mathsf{Arr}\subset\mathsf{T}$, and $\mathsf{S}=(\mathsf{Arr},\mathsf{T})$ and sorted by $\mathsf{T}$.

Protocol Details +#

We start with an unoptimized version of Plookup that is conceptually simpler than the final version and is still fully succinct. The inputs are: an array containing the values of the lookup table $\mathsf{T}$ of size $n_1$; and an array of length $n_2$ (typically longer than $n_1$ but not necessarily) that will be proven to contain only values from somewhere in $\mathsf{T}$.

The prover will create 5 helper arrays ($\mathsf{Acc_1}$ to $\mathsf{Acc_5}$) to demonstrate this overall property ($\mathsf{Arr}[i]\in\mathsf{T}$ for all $i$). The helper arrays will each be of size $n_1+n_2$ with the exception of $\mathsf{Acc_4}$ which is $n_2$. They are as follows:

  1. $\mathsf{Acc_1}=\mathsf{Arr}||\mathsf{T}$
  2. $\mathsf{Acc_2}=\mathtt{Sort}(\mathsf{Acc_1})$
  3. $\mathsf{Acc_3}[i]=\mathsf{Acc_2}[i+1]-\mathsf{Acc_2}[i]$
  4. $\mathsf{Acc_4}[i]=\mathsf{T}[i+1]-\mathsf{T}[i]$
  5. $\mathsf{Acc_5}=\mathsf{Acc_4}||\{0\}^{n_2}$ where $n_1=|\mathsf{Arr}|$

It is probably worth an example at this point.

  • $\mathsf{T}=[7,0,15,3]$
  • $\mathsf{Arr}=[7,0,15,15,7,7,15,0,0,7,15,7]$
  • $\mathsf{Acc_1}=[7,0,15,15,7,7,15,0,0,7,15,7,7,0,15,3]$
  • $\mathsf{Acc_2}=[7,7,7,7,7,7,0,0,0,0,15,15,15,15,15,3]$
  • $\mathsf{Acc_3}=[0,0,0,0,0,-7,0,0,0,15,0,0,0,0,-12,\bot]$
  • $\mathsf{Acc_4}=[-7,15,-12,\bot]$
  • $\mathsf{Acc_5}=[-7,15,-12,\bot,0,0,0,0,0,0,0,0,0,0,0,0]$

The first array $\mathsf{Acc_1}$ is the concatenation for $\mathsf{Arr}$ and $\mathsf{T}$. The intuition for this is as follows. Every element of $\mathsf{Arr}$ is in $\mathsf{T}$ (what is being proven) but the converse is not true, not every element of $\mathsf{T}$ is necessarily in $\mathsf{Arr}$. By constructing $\mathsf{Acc_1}$, the prover has an array where every element of $\mathsf{T}$ appears at least once. This will be convenient later. Additionally, if the prover can show every element in $\mathsf{Acc_1}$ is in $\mathsf{T}$, it implies every element in the original $\mathsf{Arr}$ is in $\mathsf{T}$ so it can now move forward with $\mathsf{Acc_1}$.

How does $\mathsf{Acc_1}$ compare to $\mathsf{T}$? They both have the same elements but $\mathsf{Acc_1}$ has a bunch of extra duplicates of values. Also the appearance of elements in $\mathsf{Acc_1}$ are in a different (arbitrary) order. Next the prover will sort the values of $\mathsf{Acc_1}$, grouping all duplicates together, and having them appear in the same order as the original $\mathsf{T}$ (which does not have to be sorted).

Now how does $\mathsf{Acc_2}$ compare to $\mathsf{T}$? They have the same elements in the same order (including 3 which is not in the original $\mathsf{Arr}$) however $\mathsf{Acc_2}$ has a bunch of duplicates of some of the elements. Next we want to “flag” all the elements that are duplicates. The way we do this is to take the difference between each neighbouring elements. If the neighbouring elements are the same (duplicates), this is will place a 0 in that position. If they are not, a non-zero number will appear instead.

This is straight-forward until we hit the last element in $\mathsf{Acc_2}$ and $\mathsf{Acc_3}$ which has no “next” element in the array. We will leave it for now as an arbitrary integer $\bot$.

We have marked the duplicates elements but have some other integers when neighbouring elements are not the same. The idea is do the same thing with $\mathsf{T}$ and we create $\mathsf{Acc_4}$, which we then pad with $n_2$ zeros.

  • $\mathsf{Acc_5}=[-7,15,-12,\bot,0,0,0,0,0,0,0,0,0,0,0,0]$

If $\mathsf{Acc_5}$ is a permutation of $\mathsf{Acc_3}$ and everything else is correctly constructed, then all elements in $\mathsf{Arr}$ are from $\mathsf{T}$.

The prover will show that $\mathsf{Acc_1}$ is constructed correctly with the $\mathtt{concat}$ gadget. It will not prove that $\mathsf{Acc_2}$ is sorted correctly (if it does not sort it correctly, the protocol will not work) but it will prove that $\mathsf{Acc_2}$ is a permutation of $\mathsf{Acc_1}$ using $\mathtt{shuffle1}(\mathsf{Acc_1},\mathsf{Acc_2})$. It will prove $\mathsf{Acc_3}$ is constructed correctly by $\mathsf{add1}(\mathsf{Acc_2}[i+1],-\mathsf{Acc_2}[i])$ and $\mathsf{Acc_3}$ is $\mathsf{add1}(\mathsf{T}[i+1],-\mathsf{T}[i])$. Last, it will prove that $\mathsf{Acc_5}$ is correctly formed with $\mathtt{concat}$ and finally, that it is a permutation of $\mathsf{Acc_3}$ with $\mathtt{shuffle1}(\mathsf{Acc_5},\mathsf{Acc_3})$.

$\mathsf{T}$ to the end of $\mathsf{Arr}$ does not change anything about the argument

In fact, the only difference between $\mathsf{Acc_1}$ and $\mathsf{T}$ itself is that there are several duplicates

With these arrays, the following constraints are demonstrated:

  1. Uses $\mathtt{concat}$ gadget
  2. Uses $\mathtt{shuffle1}(\mathsf{Acc_1},\mathsf{Acc_2})$
  3. Uses $\mathsf{add1}(\mathsf{Acc_2}[i+1],-\mathsf{Acc_2}[i])$
  4. Uses $\mathsf{add1}(\mathsf{T}[i+1],-\mathsf{T}[i])$
  5. Uses $\mathtt{concat}$ and then $\mathtt{shuffle1}(\mathsf{Acc_5},\mathsf{Acc_3})$

Unlike halo2, Plookup requires only one auxiliary vector, $\mathsf{S}$, where $\mathsf{S}$ is the union set of $\mathsf{Arr}$ and $\mathsf{T}$, and sorted by $\mathsf{T}$. The prover encodes $\mathsf{Arr}$, $\mathsf{T}$, and $\mathsf{S}$ into polynomials: $\mathsf{Poly}_\mathsf{Arr}$, $\mathsf{Poly}_\mathsf{T}$, and $\mathsf{Poly}_\mathsf{S}$, and computes $\prod{\mathsf{Poly}_\mathsf{Arr}\cdot\prod\mathsf{Poly}_\mathsf{T}}$ and $\prod{\mathsf{Poly}_\mathsf{S}}$ with some random challenges. The theorem tells us the two products are equal if and only if: $\mathsf{Arr}\subset\mathsf{T}$, and $\mathsf{S}=(\mathsf{Arr},\mathsf{T})$ and sorted by $\mathsf{T}$.

Protocol Details #

halo2 #

Array Level #

  • $\mathcal{P}$ and $\mathcal{V}$ are given a public table $\mathsf{T}$
  • $\mathcal{P}$ holds an array $\mathsf{Arr}=[a_0,a_1,a_2,\dots,a_{n-1}]$ of $n$ integers ($a_i\in\mathbb{Z}_q$)
  • $\mathcal{P}$ computes an array $\mathsf{Arr}^\prime=[a_0^\prime,a_1^\prime,a_2^\prime,\dots,a_{n-1}^\prime]$ of $n$ integers ($a_i^\prime\in\mathbb{Z}_q$) such that:
    • $\mathsf{Arr}^\prime$ is a permutation of $\mathsf{Arr}$ and sorted in ascending or descending
  • $\mathcal{P}$ computes an array $\mathsf{T}^\prime$ such that:
    • $\mathsf{T}^\prime$ is a permutation of $\mathsf{T}$ and sorted by $\mathsf{Arr}^\prime$
  • $\mathsf{Arr}^\prime$ and $\mathsf{T}^\prime$ have the following relations:
    • $\mathsf{Arr}^\prime[0]=\mathsf{T}^\prime[0]$
    • $\mathsf{Arr}^\prime[i]=\mathsf{T}^\prime[i]\mid\mathsf{Arr}^\prime[i-1],i\ne{0}$

Polynomial Level diff --git a/docs/gadgets/mult1/index.html b/docs/gadgets/mult1/index.html index 20eea54..c22d22a 100644 --- a/docs/gadgets/mult1/index.html +++ b/docs/gadgets/mult1/index.html @@ -1,5 +1,5 @@ Mult1 | Handbook - +
Mult1

Multiplication (Type 1) @@ -13,6 +13,6 @@ #

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}(X))$

  • $K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}(X))$

  • $K_\mathsf{Arr_3}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_3}(X))$

  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$

  • $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1},\zeta)$

  • $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2},\zeta)$

  • $\mathsf{Poly}_\mathsf{Arr_3}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_3},\zeta)$

  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish}=\mathsf{Poly}_\mathsf{Arr_1}(\zeta)-\mathsf{Poly}_\mathsf{Arr_2}(\zeta)\cdot\mathsf{Poly}_\mathsf{Arr_3}( \zeta)$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish1} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Implementations #

Security Proof #

Completeness -#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr_1}, \mathsf{Arr_2}$ and $\mathsf{Arr_3}$ such that $\mathsf{Arr_1}[i] \cdot \mathsf{Arr_2}[i] - \mathsf{Arr_3}[i] = 0 \space \forall i \in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$ = Y_\mathsf{Vanish} - Q(\zeta)(\zeta^\kappa - 1)$

$ = \mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}( \zeta) - Q(\zeta)(\zeta^\kappa - 1)$

$= \mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}( \zeta) - \frac{\mathsf{Poly_{Vanish}}(\zeta)}{\zeta^\kappa - 1}\cdot(\zeta^\kappa - 1)$

$= \mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}( \zeta) - (\mathsf{Poly}_\mathsf{Arr_1}(\zeta)+\mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}(\zeta))$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish}}(X)$ is vanishing on $\mathcal{H_\kappa}$, i.e. if $\mathsf{Poly}_\mathsf{Arr_1}(X) \cdot \mathsf{Poly}_\mathsf{Arr_2}(X) - \mathsf{Poly}_\mathsf{Arr_3}(X) =0 \space \forall X \in \mathcal{H}_\kappa$. This is true if if $\mathsf{Arr_1}[i] \cdot \mathsf{Arr_2}[i] - \mathsf{Arr_3}[i] = 0 \space \forall i \in [0, \kappa - 1]$, since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$. But $\mathsf{Arr_1}[i] \cdot \mathsf{Arr_2}[i] - \mathsf{Arr_3}[i] = 0 \space \forall i \in [0, \kappa - 1]$ is precisely the relation tnat we assumed held for our prover (if $\kappa \gt n$ then the arrays get padded such that this relation still holds), thus the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.

Soundness -#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr1}(X)$, $\mathsf{Poly}_\mathsf{Arr2}(X)$, $\mathsf{Poly}_\mathsf{Arr3}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr1}(X)$, $\mathsf{Poly}_\mathsf{Arr2}(X)$, $\mathsf{Poly}_\mathsf{Arr3}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Arr}_3\neq \mathsf{Arr}_1 \cdot \mathsf{Arr}_2$

Our proof is as follows:

For the second win condition to be fulfilled, the constraint must not hold for at least one index of the arrays. But then $\mathsf{Poly}_\mathsf{Vanish}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and sends $K_Q = g^{Q(\tau)}$. It also sends commitments to $\mathsf{Poly}_\mathsf{Arr1}(X)$, $\mathsf{Poly}_\mathsf{Arr2}(X)$, and $\mathsf{Poly}_\mathsf{Arr3}(X)$. Each commitment $\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr1}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr2}(\zeta)$, and $\mathsf{Poly}_\mathsf{Arr3}(\zeta)$ can only feasibliy be opened to one value each. For $\mathcal{A}$ to have the verifier accept, they must send a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1}}{(\zeta^\kappa - 1)}$. This means being able to send $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge +#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr_1}, \mathsf{Arr_2}$ and $\mathsf{Arr_3}$ such that $\mathsf{Arr_1}[i] \cdot \mathsf{Arr_2}[i] - \mathsf{Arr_3}[i] = 0 \space \forall i \in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$ = Y_\mathsf{Vanish} - Q(\zeta)(\zeta^\kappa - 1)$

$ = \mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}( \zeta) - Q(\zeta)(\zeta^\kappa - 1)$

$= \mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}( \zeta) - \frac{\mathsf{Poly_{Vanish}}(\zeta)}{\zeta^\kappa - 1}\cdot(\zeta^\kappa - 1)$

$= \mathsf{Poly}_\mathsf{Arr_1}(\zeta) + \mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}( \zeta) - (\mathsf{Poly}_\mathsf{Arr_1}(\zeta)+\mathsf{Poly}_\mathsf{Arr_2}(\zeta) - \mathsf{Poly}_\mathsf{Arr_3}(\zeta))$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish}}(X)$ is vanishing on $\mathcal{H_\kappa}$, i.e. if $\mathsf{Poly}_\mathsf{Arr_1}(X) \cdot \mathsf{Poly}_\mathsf{Arr_2}(X) - \mathsf{Poly}_\mathsf{Arr_3}(X) =0 \space \forall X \in \mathcal{H}_\kappa$. This is true if if $\mathsf{Arr_1}[i] \cdot \mathsf{Arr_2}[i] - \mathsf{Arr_3}[i] = 0 \space \forall i \in [0, \kappa - 1]$, since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$. But $\mathsf{Arr_1}[i] \cdot \mathsf{Arr_2}[i] - \mathsf{Arr_3}[i] = 0 \space \forall i \in [0, \kappa - 1]$ is precisely the relation that we assumed held for our prover (if $\kappa \gt n$ then the arrays get padded such that this relation still holds), thus the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.

Soundness +#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr1}(X)$, $\mathsf{Poly}_\mathsf{Arr2}(X)$, $\mathsf{Poly}_\mathsf{Arr3}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr1}(X)$, $\mathsf{Poly}_\mathsf{Arr2}(X)$, $\mathsf{Poly}_\mathsf{Arr3}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Arr}_3\neq \mathsf{Arr}_1 \cdot \mathsf{Arr}_2$

Our proof is as follows:

For the second win condition to be fulfilled, the constraint must not hold for at least one index of the arrays. But then $\mathsf{Poly}_\mathsf{Vanish}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and sends $K_Q = g^{Q(\tau)}$. It also sends commitments to $\mathsf{Poly}_\mathsf{Arr1}(X)$, $\mathsf{Poly}_\mathsf{Arr2}(X)$, and $\mathsf{Poly}_\mathsf{Arr3}(X)$. Each commitment $\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr1}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr2}(\zeta)$, and $\mathsf{Poly}_\mathsf{Arr3}(\zeta)$ can only feasibly be opened to one value each. For $\mathcal{A}$ to have the verifier accept, they must send a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1}}{(\zeta^\kappa - 1)}$. This means being able to send $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge #

We prove that the above protocol is zero-knowledge when $\mathsf{PolyCommit}_\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ that knows the trapdoor $\tau$, which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ choose arbitrary values for ${\mathsf{Poly}_\mathsf{Arr1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr2}(\tau)}$, and $\mathsf{Poly}_\mathsf{Arr3}(\tau)$, then computes $g^{\mathsf{Poly}_\mathsf{Arr1}(\tau)}$, $g^{\mathsf{Poly}_\mathsf{Arr2}(\tau)}$ , and $g^{\mathsf{Poly}_\mathsf{Arr3}(\tau)}$ to output as the commitments $K_\mathsf{Arr1}$, $ K_\mathsf{Arr2}$, and $ K_\mathsf{Arr3}$. $\mathcal{S}$ then generates the challenge evaluation point $\rho$ (by strong Fiat-Shamir) and computes $Q(\tau)$ using $\rho$ and the values they chose for ${\mathsf{Poly}_\mathsf{Arr1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr2}(\tau)}$, and $\mathsf{Poly}_\mathsf{Arr3}(\tau)$. $\mathcal{S}$ outputs the commitment $K_Q = g^{Q(\tau)}$.

Now, $\mathcal{S}$ generates the second random challenge point $\zeta$ (which we assume is not in $\mathcal{H}_\kappa$; if it is in $\mathcal{H}_\kappa$, $\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\mathcal{S}$ then create fake opening proofs for ${\mathsf{Poly}_\mathsf{Arr1}(\zeta)}$, ${\mathsf{Poly}_\mathsf{Arr2}(\zeta)}$, and $\mathsf{Poly}_\mathsf{Arr3}(\zeta)$, to arbitrary values. This is done using the knowledge of $\tau$, calculating the respective witness $q(\tau) = \frac{{f(\tau) - f(\zeta)}}{\tau - \zeta}$ for each of the polynomials.

Finally, $\mathcal{S}$ creates a fake opening proof for $Q(\zeta) = \frac{Y_\mathsf{Vanish1}}{(\zeta^\kappa - 1)}$. This is done using knowledge of $\tau$ to calculate an accepting witness $q(\tau)$, as above. This means that $Y_\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

  • For mult2, the proof is written with a simulator that doesn’t know the trapdoor; however, with small alterations the proof for mult2 should apply here and vice versa
\ No newline at end of file diff --git a/docs/gadgets/mult2/index.html b/docs/gadgets/mult2/index.html index 86cb890..12e2d78 100644 --- a/docs/gadgets/mult2/index.html +++ b/docs/gadgets/mult2/index.html @@ -1,18 +1,18 @@ Mult2 | Handbook - +
Mult2

Multiplication (Type 2) #

Recap of types #

TypeDescriptionRecapThis
mult1$\mathsf{Arr}_3=\mathsf{Arr}_1 \cdot \mathsf{Arr}_2$$\mathsf{Arr}_3$ is the element-wise multiplication of $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$.
mult2$\mathsf{Prod}_\mathsf{Arr}=\prod_{i = 0}^{n-1} \mathsf{Arr}[i]$$\mathsf{Prod}_\mathsf{Arr}$ is the disclosed product of all the elements in $\mathsf{Arr}$.
mult3$\prod_{i = 0}^{n-1} \mathsf{Arr}_1[i]=\prod_{i = 0}^{n-1} \mathsf{Arr}_2[i]$$\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ have the same undisclosed product.

Relation #

$ \mathcal{R}_{\mathtt{mult2}} := \left\{ \begin{array}{l} (K_\mathsf{Arr},\mathsf{Prod}_\mathsf{Arr}) \end{array} \middle | \begin{array}{l} \mathsf{Arr} = [a_0, a_1, a_2, \dots, a_{n-1}], \\ \mathsf{Prod}_\mathsf{Arr} = \prod_{i = 0}^{n-1} a_i, \\ \mathsf{Poly}_\mathsf{Arr}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr}), \\ K_\mathsf{Arr}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr}) \end{array} \right\} $

Intuition -#

The prover ($\mathcal{P}$) holds an array $\mathsf{Arr} = [a_0, a_1, a_2, \dots, a_{n-1}]$ of $n$ integers (from $\mathbb{Z}_q$) and a disclosed integer $\mathsf{Prod}_\mathsf{Arr}$. It will produce a succinct (independent of $n$) proof that $\mathsf{Prod}_\mathsf{Arr}$ is the product of all the elements in the array. The prover will encode the array into a polynomial $\mathsf{Poly}_\mathsf{Arr}$ (using evaluation points on the domain $\mathcal{H}_\kappa$) and commit to the polynomial $K_\mathsf{Arr}$. The verifier ($\mathcal{V}$) cannot check $\textsf{Arr}$ or $\mathsf{Poly}_\mathsf{Arr}$ directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\mathsf{Arr}$ and the asserted value $\mathsf{Prod_\mathsf{Arr}}$.

In order to prove $K_\mathsf{Arr}$ and $\mathsf{Prod}_\mathsf{Arr}$ are consistent, the prover will build a helper array $\mathsf{Acc}_\mathsf{Arr}$ called an accumulator (or accumulating array or incremental array). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\mathsf{Arr}$, the prover will also encode $\mathsf{Acc}$ as a polynomial and provide a commitment of it to the verifier. The idea is that the prover will prove a relation between $\mathsf{Arr}$ and $\mathsf{Acc}$; and a relation between $\mathsf{Acc}$ and $\mathsf{Prod_\mathsf{Arr}}$. Put together, it will imply the correct relation between $\mathsf{Arr}$ and $\mathsf{Prod_\mathsf{Arr}}$.

Consider a small numeric example in $\mathbb{Z}_{97}$ where $\mathsf{Arr}= [84,67,11,92,36,67]$ and $\mathsf{Prod}_\mathsf{Arr}=72$. The first idea is to get $\mathsf{Prod}_\mathsf{Arr}$ into an array. Say, we just append it: $\mathsf{Arr}''= [84,67,11,92,36,67,72] $. How does the prover show $\mathsf{Arr}''$ is correct? The last value of the array depends on every single element that precedes it, which will be a complex constraint to prove.

An alternative idea is to create a new array that starts the same as $\mathsf{Arr}$ and ends up at $\mathsf{Prod}_\mathsf{Arr}$ by folding in the integers from $\mathsf{Arr}$ one-by-one with multiplication. Then each value in the new array will depend on only two values, as below.

The first value in $\mathsf{Acc}$ will be a copy of the first value from $\mathsf{Arr}$:

  • $\mathsf{Arr}= [84,67,11,92,36,67]$

  • $\mathsf{Acc}= [84, \bot,\bot,\bot,\bot,\bot] $

The next value will be the multiplication (mod 97) of: 67 (the value at the same index in $\mathsf{Arr}$) and 84 (the previous value in $\mathsf{Acc}$):

  • $\mathsf{Arr}= [84,67,11,92,36,67]$

  • $ \mathsf{Acc} = [84, (67\cdot84),\bot,\bot,\bot,\bot] = [84, 2,\bot,\bot,\bot,\bot]$

The next value will be the multiplication of: 11 (the value at the same index in $\mathsf{Arr}$) and 2 (the previous value in $\mathsf{Acc}$):

  • $\mathsf{Arr}= [84,67,11,92,36,67]$
  • $ \mathsf{Acc} = [84, 2,(11\cdot2),\bot,\bot,\bot] = [84,2,22,\bot,\bot,\bot]$
  • $ \mathsf{Acc} = [84, 2,22,(92\cdot22),\bot,\bot] = [84,2,22,84,\bot,\bot]$
  • $ \mathsf{Acc} = [84, 2,22,84,(36\cdot84),\bot] = [84,2,22,84,17,\bot]$
  • $ \mathsf{Acc} = [84,2,22,84,17,(67\cdot17)] = [84, 2, 22, 84, 17, 72]$
  • $\mathsf{Prod}_\mathsf{Arr}=72$

Notice the last value in $\mathsf{Acc}$ is $\mathsf{Prod_\mathsf{Arr}}$. The prover wants to show three constraints:

  1. The first value in $\mathsf{Acc}$ matches the first value in $\mathsf{Arr}$,
  2. The rest of the values in $\mathsf{Acc}$ are of the form $\mathsf{Acc}[i]=\mathsf{Arr}[i]\cdot\mathsf{Acc}[i-1]$,
  3. The last value in $\mathsf{Acc}$ matches $\mathsf{Prod}_\mathsf{Arr}$.

If all three constraints are true, then $\mathsf{Prod}_\mathsf{Arr}$ is the product of the elements of $\mathsf{Arr}$.

Last, while it is not necessary to do, it is often convenient to hold the the value $\mathsf{Prod}_\mathsf{Arr}$ at the start of the array $\mathsf{Acc}$ instead of the end. For this reason, the mathematical explaination below will construct $\mathsf{Acc}$ “backwards” (or right-to-left) from the above example, where the last value of $\mathsf{Acc}$ matches the last value of $\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\mathsf{Acc}$ is $\mathsf{Prod}_\mathsf{Arr}$:

  • $\mathsf{Arr}= [84,67,11,92,36,67]$
  • $ \mathsf{Acc} = [\bot, \bot, \bot, \bot, \bot, 67]$
  • $ \mathsf{Acc} = [\bot, \bot, \bot, \bot, 84, 67]$
  • $\ldots$
  • $ \mathsf{Acc} = [72, 84, 36, 65, 84, 67]$
  • $\mathsf{Prod}_\mathsf{Arr}=72$

Protocol Details +#

The prover ($\mathcal{P}$) holds an array $\mathsf{Arr} = [a_0, a_1, a_2, \dots, a_{n-1}]$ of $n$ integers (from $\mathbb{Z}_q$) and a disclosed integer $\mathsf{Prod}_\mathsf{Arr}$. It will produce a succinct (independent of $n$) proof that $\mathsf{Prod}_\mathsf{Arr}$ is the product of all the elements in the array. The prover will encode the array into a polynomial $\mathsf{Poly}_\mathsf{Arr}$ (using evaluation points on the domain $\mathcal{H}_\kappa$) and commit to the polynomial $K_\mathsf{Arr}$. The verifier ($\mathcal{V}$) cannot check $\textsf{Arr}$ or $\mathsf{Poly}_\mathsf{Arr}$ directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\mathsf{Arr}$ and the asserted value $\mathsf{Prod_\mathsf{Arr}}$.

In order to prove $K_\mathsf{Arr}$ and $\mathsf{Prod}_\mathsf{Arr}$ are consistent, the prover will build a helper array $\mathsf{Acc}_\mathsf{Arr}$ called an accumulator (or accumulating array or incremental array). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\mathsf{Arr}$, the prover will also encode $\mathsf{Acc}$ as a polynomial and provide a commitment of it to the verifier. The idea is that the prover will prove a relation between $\mathsf{Arr}$ and $\mathsf{Acc}$; and a relation between $\mathsf{Acc}$ and $\mathsf{Prod_\mathsf{Arr}}$. Put together, it will imply the correct relation between $\mathsf{Arr}$ and $\mathsf{Prod_\mathsf{Arr}}$.

Consider a small numeric example in $\mathbb{Z}_{97}$ where $\mathsf{Arr}= [84,67,11,92,36,67]$ and $\mathsf{Prod}_\mathsf{Arr}=72$. The first idea is to get $\mathsf{Prod}_\mathsf{Arr}$ into an array. Say, we just append it: $\mathsf{Arr}''= [84,67,11,92,36,67,72] $. How does the prover show $\mathsf{Arr}''$ is correct? The last value of the array depends on every single element that precedes it, which will be a complex constraint to prove.

An alternative idea is to create a new array that starts the same as $\mathsf{Arr}$ and ends up at $\mathsf{Prod}_\mathsf{Arr}$ by folding in the integers from $\mathsf{Arr}$ one-by-one with multiplication. Then each value in the new array will depend on only two values, as below.

The first value in $\mathsf{Acc}$ will be a copy of the first value from $\mathsf{Arr}$:

  • $\mathsf{Arr}= [84,67,11,92,36,67]$

  • $\mathsf{Acc}= [84, \bot,\bot,\bot,\bot,\bot] $

The next value will be the multiplication (mod 97) of: 67 (the value at the same index in $\mathsf{Arr}$) and 84 (the previous value in $\mathsf{Acc}$):

  • $\mathsf{Arr}= [84,67,11,92,36,67]$

  • $ \mathsf{Acc} = [84, (67\cdot84),\bot,\bot,\bot,\bot] = [84, 2,\bot,\bot,\bot,\bot]$

The next value will be the multiplication of: 11 (the value at the same index in $\mathsf{Arr}$) and 2 (the previous value in $\mathsf{Acc}$):

  • $\mathsf{Arr}= [84,67,11,92,36,67]$
  • $ \mathsf{Acc} = [84, 2,(11\cdot2),\bot,\bot,\bot] = [84,2,22,\bot,\bot,\bot]$
  • $ \mathsf{Acc} = [84, 2,22,(92\cdot22),\bot,\bot] = [84,2,22,84,\bot,\bot]$
  • $ \mathsf{Acc} = [84, 2,22,84,(36\cdot84),\bot] = [84,2,22,84,17,\bot]$
  • $ \mathsf{Acc} = [84,2,22,84,17,(67\cdot17)] = [84, 2, 22, 84, 17, 72]$
  • $\mathsf{Prod}_\mathsf{Arr}=72$

Notice the last value in $\mathsf{Acc}$ is $\mathsf{Prod_\mathsf{Arr}}$. The prover wants to show three constraints:

  1. The first value in $\mathsf{Acc}$ matches the first value in $\mathsf{Arr}$,
  2. The rest of the values in $\mathsf{Acc}$ are of the form $\mathsf{Acc}[i]=\mathsf{Arr}[i]\cdot\mathsf{Acc}[i-1]$,
  3. The last value in $\mathsf{Acc}$ matches $\mathsf{Prod}_\mathsf{Arr}$.

If all three constraints are true, then $\mathsf{Prod}_\mathsf{Arr}$ is the product of the elements of $\mathsf{Arr}$.

Last, while it is not necessary to do, it is often convenient to hold the the value $\mathsf{Prod}_\mathsf{Arr}$ at the start of the array $\mathsf{Acc}$ instead of the end. For this reason, the mathematical explanation below will construct $\mathsf{Acc}$ “backwards” (or right-to-left) from the above example, where the last value of $\mathsf{Acc}$ matches the last value of $\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\mathsf{Acc}$ is $\mathsf{Prod}_\mathsf{Arr}$:

  • $\mathsf{Arr}= [84,67,11,92,36,67]$
  • $ \mathsf{Acc} = [\bot, \bot, \bot, \bot, \bot, 67]$
  • $ \mathsf{Acc} = [\bot, \bot, \bot, \bot, 84, 67]$
  • $\ldots$
  • $ \mathsf{Acc} = [72, 84, 36, 65, 84, 67]$
  • $\mathsf{Prod}_\mathsf{Arr}=72$

Protocol Details #

Array Level #

  • $\mathcal{P}$ holds an array $\mathsf{Arr} = [a_0, a_1, a_2, \dots, a_{n-1}]$ of $n$ integers ($a_i \in \mathbb{Z}_q$)
  • $\mathcal{P}$ computes array $\mathsf{Acc}$ as follows:
    • $\mathsf{Acc}[n-1]\leftarrow\mathsf{Arr}[n-1]$
    • $\mathsf{Acc}[i]\leftarrow\mathsf{Arr}[i]\cdot\mathsf{Acc}[i+1]$ for $i$ from $n-2$ to 0
  • $\mathcal{P}$ computes $\mathsf{Prod}_\mathsf{Arr}\leftarrow\mathsf{Acc}[0]$

Polynomial Level #

We assume arrays $\mathsf{Arr}$ and $\mathsf{Acc}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\mathcal{H}_\kappa$) are chosen as the multiplicative group of order $\kappa$ with generator $\omega\in\mathbb{G}_\kappa$ (see Background for more). In short, $\omega^0$ is the first element and $\omega^{\kappa-1}$ is the last element of $\mathcal{H}_\kappa$. If $\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product).

Recall the three constraints we want to prove (now adjusted to fit with an $\mathsf{Acc}$ that is constructed “backwards,” as noted above):

  1. The last value in $\mathsf{Acc}$ matches the last value in $\mathsf{Arr}$,
  2. The rest of the values in $\mathsf{Acc}$ are of the form $\mathsf{Acc}[i]=\mathsf{Arr}[i]\cdot\mathsf{Acc}[i-1]$,
  3. The first value in $\mathsf{Acc}$ matches $\mathsf{Prod}_\mathsf{Arr}$.

In polynomial form, the constraints are:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Poly}_\mathsf{Arr}(X)$,
  2. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Poly}_\mathsf{Arr}(X)\cdot\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X)$
  3. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Prod}_\mathsf{Arr}$

In constraint 2, $\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X)$ can also be conceptualized as rotate applied to $\mathsf{Poly}_\mathsf{Acc}(X)$ by one element (rightward in the array view). Also note that constraint 2 does not hold at $X=\omega^{\kappa-1}$ because this value is defined by constraint 1 (for the last value of $X$, the “next” value, $\omega X$, wraps back to the first element of the array which is a boundary condition).

We adjust each of these constraints to show an equality with 0:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X)=0$,
  2. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X)\cdot\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X)=0$
  3. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Prod}_\mathsf{Arr}=0$

Next we take care of the “for $X$” conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.

  1. $\mathsf{Poly}_\mathsf{Vanish1}(X)=(\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$,
  2. $\mathsf{Poly}_\mathsf{Vanish2}(X)=(\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X)\cdot\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X))\cdot(X-\omega^{\kappa-1})=0$
  3. $\mathsf{Poly}_\mathsf{Vanish3}(X)=(\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Prod}_\mathsf{Arr})\cdot\frac{(X^\kappa-1)}{(X-\omega^0)}=0$

These equations are true for every value of $X \in \mathcal{H}_\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\kappa - 1$, which is a minimal vanishing polynomial for $\mathcal{H}_\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\mathsf{Poly}_\mathsf{Vanish1}(X)$, $\mathsf{Poly}_\mathsf{Vanish2}(X)$, and $\mathsf{Poly}_\mathsf{Vanish3}(X)$ must be vanishing on $\mathcal{H}_\kappa$ too. Specifically, the prover computes,

  1. $Q_1(X) = \frac{\mathsf{Poly}_\mathsf{Vanish1}(X)}{X^\kappa - 1}$
  2. $Q_2(X) = \frac{\mathsf{Poly}_\mathsf{Vanish2}(X)}{X^\kappa - 1}$
  3. $Q_3(X) = \frac{\mathsf{Poly}_\mathsf{Vanish3}(X)}{X^\kappa - 1}$

We can replace polynomials $Q_1(X)$, $Q_2(X)$, and $Q_3(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\mathsf{Poly}_\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all three $\mathsf{Poly}_\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all three are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\rho$ selected after the commitments to the earlier polynomials are fixed.

$Q(X) = \frac{\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho + \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2}{X^\kappa - 1}$

By rearranging, we can get $\mathsf{Poly}_\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\mathcal{H}_\kappa$ and outside of it):

$\mathsf{Poly}_\mathsf{Zero}(X)=\mathsf{Poly}_\mathsf{Vanish1}(X) + \rho \mathsf{Poly}_\mathsf{Vanish2}(X) + \rho^2 \mathsf{Poly}_\mathsf{Vanish3}(X) - Q(X)\cdot (X^\kappa - 1)=0$

Ultimately the mult2 argument will satisfy the following constraints at the Commitment Level:

  1. Show $Q(X)$ exists (as a polynomial that evenly divides the divisor)
  2. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is correctly constructed from $\mathsf{Poly}_\mathsf{Acc}(X)$, $\mathsf{Poly}_\mathsf{Acc}(\omega X)$, $\mathsf{Poly}_\mathsf{Arr}(X)$, and $\mathsf{Prod}_\mathsf{Arr}$
  3. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is the zero polynomial

Commitment Level #

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr}(X))$
  • $K_\mathsf{Acc}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Acc}(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:

  • $\rho$
  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$
  • $\mathsf{Poly}_\mathsf{Arr}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr}(\zeta\omega)=\mathsf{KZG.Open}(K_\mathsf{Arr},\zeta\omega)$
  • $\mathsf{Poly}_\mathsf{Acc}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Acc},\zeta)$
  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish1}=(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}$
  • $Y_\mathsf{Vanish2}=(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)\cdot\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1})$
  • $Y_\mathsf{Vanish3}=(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Prod}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)}$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\rho$ and $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Implementations #

Security Proof #

Completeness -#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr}$ such that $\mathsf{Prod}_\mathsf{Arr}=\prod_{i = 0}^{n-1} \mathsf{Arr}[i] \space \forall i \in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)} \newline - \frac{\mathsf{Poly}_\mathsf{Vanish1}(\zeta) + \mathsf{Poly}_\mathsf{Vanish2}(\zeta) \rho + \mathsf{Poly}_\mathsf{Vanish3}(\zeta)\rho^2}{\zeta^\kappa - 1} \cdot(\zeta^\kappa - 1)$

$= (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)} \newline - ((\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) \newline + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)})$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly}_\mathsf{Vanish1}(\zeta) + \mathsf{Poly}_\mathsf{Vanish2}(\zeta) \rho + \mathsf{Poly}_\mathsf{Vanish3}(\zeta)\rho^2$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish_1}}(X), \mathsf{Poly_{Vanish_2}}(X)$ and $\mathsf{Poly_{Vanish_3}}(X),$ are all vanishing on $\mathcal{H_\kappa}$, i.e. if all three of the following conditions hold for all $X \in \mathcal{H}_\kappa$:

  1. $(\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$
  2. $ (\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X) \cdot \mathsf{Poly}_\mathsf{Acc}(\omega\cdot X))\cdot(X-\omega^{\kappa-1})=0$
  3. $ (\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Prod}_\mathsf{Arr})\cdot\frac{(X^\kappa-1)}{(X-\omega^0)}=0$

These conditions, in turn, hold if:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Poly}_\mathsf{Arr}(X)$
  2. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Poly}_\mathsf{Arr}(X) \cdot \mathsf{Poly}_\mathsf{Acc}(\omega\cdot X)$
  3. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Prod}_\mathsf{Arr}$

Where we get the “For $X$” due to zeroing parts of the polynomials (see zero1). Since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$, the above conditions are true if:

  1. The last value in $\mathsf{Acc}$ matches the last value in $\mathsf{Arr}$
  2. The rest of the values in $\mathsf{Acc}$ are of the form $\mathsf{Acc}[i]=\mathsf{Arr}[i] \cdot \mathsf{Acc}[i-1]$
  3. The first value in $\mathsf{Acc}$ matches $\mathsf{Prod}_\mathsf{Arr}$

Which are precisely the conditions the Intuitions sections explains will hold if the prover contructs their Accumulator by following the protocol and using $\mathsf{Arr}$ such that $\mathsf{Prod}_\mathsf{Arr}=\prod_{i = 0}^{n-1} \mathsf{Arr}[i] \space \forall i \in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.

Soundness -#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Acc}(X)$, $\mathsf{Poly}_\mathsf{Arr}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Acc}(X)$, $\mathsf{Poly}_\mathsf{Arr}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_\mathsf{Zero}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Prod}_\mathsf{Arr}\neq\prod_{i = 0}^{n-1} \mathsf{Arr}[i]$

Our proof is as follows:

For the second win condition to be fulfilled, one of the three constraints must be false. But then the $\mathsf{Poly}_\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcrip. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Acc}(X)$, and $\mathsf{Poly}_\mathsf{Arr}(X)$. Each commitment $\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Acc}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr}(\zeta)$, and $\mathsf{Poly}_\mathsf{Acc}(\zeta \cdot \omega)$ can only feasibliy be opened to one value each. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2Y_\mathsf{Vanish3}}{\zeta^\kappa - 1}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2Y_\mathsf{Vanish3}}{\zeta^\kappa - 1}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge +#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr}$ such that $\mathsf{Prod}_\mathsf{Arr}=\prod_{i = 0}^{n-1} \mathsf{Arr}[i] \space \forall i \in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)} \newline - \frac{\mathsf{Poly}_\mathsf{Vanish1}(\zeta) + \mathsf{Poly}_\mathsf{Vanish2}(\zeta) \rho + \mathsf{Poly}_\mathsf{Vanish3}(\zeta)\rho^2}{\zeta^\kappa - 1} \cdot(\zeta^\kappa - 1)$

$= (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)} \newline - ((\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}) + \rho(\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Poly}_\mathsf{Arr}(\zeta)+\mathsf{Poly}_\mathsf{Acc}(\omega\cdot \zeta))\cdot(\zeta-\omega^{\kappa-1}) \newline + \rho^2 (\mathsf{Poly}_\mathsf{Acc}(\zeta)-\mathsf{Sum}_\mathsf{Arr})\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)})$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly}_\mathsf{Vanish1}(\zeta) + \mathsf{Poly}_\mathsf{Vanish2}(\zeta) \rho + \mathsf{Poly}_\mathsf{Vanish3}(\zeta)\rho^2$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish_1}}(X), \mathsf{Poly_{Vanish_2}}(X)$ and $\mathsf{Poly_{Vanish_3}}(X),$ are all vanishing on $\mathcal{H_\kappa}$, i.e. if all three of the following conditions hold for all $X \in \mathcal{H}_\kappa$:

  1. $(\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$
  2. $ (\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Poly}_\mathsf{Arr}(X) \cdot \mathsf{Poly}_\mathsf{Acc}(\omega\cdot X))\cdot(X-\omega^{\kappa-1})=0$
  3. $ (\mathsf{Poly}_\mathsf{Acc}(X)-\mathsf{Prod}_\mathsf{Arr})\cdot\frac{(X^\kappa-1)}{(X-\omega^0)}=0$

These conditions, in turn, hold if:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Poly}_\mathsf{Arr}(X)$
  2. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Poly}_\mathsf{Arr}(X) \cdot \mathsf{Poly}_\mathsf{Acc}(\omega\cdot X)$
  3. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc}(X)=\mathsf{Prod}_\mathsf{Arr}$

Where we get the “For $X$” due to zeroing parts of the polynomials (see zero1). Since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$, the above conditions are true if:

  1. The last value in $\mathsf{Acc}$ matches the last value in $\mathsf{Arr}$
  2. The rest of the values in $\mathsf{Acc}$ are of the form $\mathsf{Acc}[i]=\mathsf{Arr}[i] \cdot \mathsf{Acc}[i-1]$
  3. The first value in $\mathsf{Acc}$ matches $\mathsf{Prod}_\mathsf{Arr}$

Which are precisely the conditions the Intuitions sections explains will hold if the prover constructs their Accumulator by following the protocol and using $\mathsf{Arr}$ such that $\mathsf{Prod}_\mathsf{Arr}=\prod_{i = 0}^{n-1} \mathsf{Arr}[i] \space \forall i \in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.

Soundness +#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Acc}(X)$, $\mathsf{Poly}_\mathsf{Arr}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Acc}(X)$, $\mathsf{Poly}_\mathsf{Arr}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_\mathsf{Zero}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Prod}_\mathsf{Arr}\neq\prod_{i = 0}^{n-1} \mathsf{Arr}[i]$

Our proof is as follows:

For the second win condition to be fulfilled, one of the three constraints must be false. But then the $\mathsf{Poly}_\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Acc}(X)$, and $\mathsf{Poly}_\mathsf{Arr}(X)$. Each commitment $\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Acc}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr}(\zeta)$, and $\mathsf{Poly}_\mathsf{Acc}(\zeta \cdot \omega)$ can only feasibly be opened to one value each. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2Y_\mathsf{Vanish3}}{\zeta^\kappa - 1}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2Y_\mathsf{Vanish3}}{\zeta^\kappa - 1}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge #

We prove that the above protocol is zero-knowledge when $\mathsf{PolyCommit}_\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ generates an array $\mathsf{Arr'}$ whose product is equal to the disclosed value $\mathsf{Prod}_\mathsf{Arr}$ (this array could just have $\mathsf{Prod}_\mathsf{Arr}$ in one entry, and $1$’s elsewhere), then follows the same steps a prover would to prove the product of this array. So, $\mathcal{S}$ computes the accumulator $\mathsf{Acc'}$ and interpolates the two arrays into their respective polynomials, $\mathsf{Poly}_\mathsf{Acc'}(X)$ and $\mathsf{Poly}_\mathsf{Arr'}(X)$. It computes $Q(X)'$ using $\mathsf{Poly}_\mathsf{Acc'}(X)$ and $\mathsf{Poly}_\mathsf{Arr'}(X)$ and the random challenge point $\rho'$ (by strong Fiat-Shamir). $\mathcal{S}$ commits to each of these three polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\zeta'$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\mathsf{Poly}_\mathsf{Acc}(\zeta'), \space \mathsf{Poly}_\mathsf{Arr}(\zeta'), \space Q(\zeta')$, and $\mathsf{Poly}_\mathsf{Acc}(\zeta' \cdot \omega)$, and writes these to the transcript as well. Since $\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution, since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

  • This proof could also be done by defining a simulator that knows the trapdoor $\tau$ and cant thus create a passing witness for any commitment. The proof for mult1 is done in this style, but with small alterations would work here as well (and vice versa for this style of proof working for mult1)
\ No newline at end of file diff --git a/docs/gadgets/mult3/index.html b/docs/gadgets/mult3/index.html index 41fdb9d..1cc8872 100644 --- a/docs/gadgets/mult3/index.html +++ b/docs/gadgets/mult3/index.html @@ -1,18 +1,18 @@ Mult3 | Handbook - +
Mult3

Multiplication (Type 3) #

Recap of types #

TypeDescriptionRecapThis
mult1$\mathsf{Arr}_3=\mathsf{Arr}_1 \cdot \mathsf{Arr}_2$$\mathsf{Arr}_3$ is the element-wise multiplication of $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$.
mult2$\mathsf{Prod}_\mathsf{Arr}=\prod_{i = 0}^{n-1} \mathsf{Arr}[i]$$\mathsf{Prod}_\mathsf{Arr}$ is the disclosed product of all the elements in $\mathsf{Arr}$.
mult3$\prod_{i = 0}^{n-1} \mathsf{Arr}_1[i]=\prod_{i = 0}^{n-1} \mathsf{Arr}_2[i]$$\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ have the same undisclosed product.

Relation #

$ \mathcal{R}_{\mathtt{mult3}} := \left\{ \begin{array}{l} (K_\mathsf{Arr_1},K_\mathsf{Arr2}) \end{array} \middle | \begin{array}{l} \mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \dots, a_{(1,n-1)}],\\ \mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \dots, a_{(2,n-1)}], \\ \mathsf{Poly}_\mathsf{Arr_1}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr_1}), \\ \mathsf{Poly}_\mathsf{Arr_2}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr_2}), \\ K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}),\\ K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}), \end{array} \right\} $

Intuition -#

The prover ($\mathcal{P}$) holds two arrays $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ of $n$ integers from $\mathbb{Z}_q$: $[a_0, a_1, a_2, \dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that they have the same undisclosed product. The prover will encode the two arrays into polynomials, $\mathsf{Poly}_\mathsf{Arr_1}$ and $\mathsf{Poly}_\mathsf{Arr_2}$ (using evaluation points on the domain $\mathcal{H}_\kappa$) and commit to them as $K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_2}$. The verifier ($\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_2}$.

In order to prove $K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_2}$ are consistent, the prover will build two helper arrays $\mathsf{Acc_1}$ and $\mathsf{Acc_2}$ called accumulators (or accumulating arrays or incremental arrays). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$, the prover will also encode $\mathsf{Acc_1}$ and $\mathsf{Acc_2}$ as a polynomials and provide a commitment to the verifier of each one. The idea is that the prover will prove a relation between each $\mathsf{Arr}$ and its $\mathsf{Acc}$; and a relation between $\mathsf{Acc_1}$ and $\mathsf{Acc_2}$. Put together, it will imply the correct relation between $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$.

We will illustrate a small numerical example in $\mathbb{Z}_{97}$ of constructing an accumulator $\mathsf{Acc}$ for the array $\mathsf{Arr}= [84,67,11,92,36,67]$. The idea is to create a new array, $\mathsf{Acc}$, that starts the same as $\mathsf{Arr}$ and ends with the product of all entries of $\mathsf{Arr}$, by folding in the integers from $\mathsf{Arr}$ one-by-one with multiplication. Then each value in the new array will depend on only two values, as below.

The first value in $\mathsf{Acc}$ will be a copy of the first value from $\mathsf{Arr}$:

  • $\mathsf{Arr}= [84,67,11,92,36,67]$

  • $\mathsf{Acc}= [84, \bot,\bot,\bot,\bot,\bot] $

The next value will be the multiplication (mod 97) of: 67 (the value at the same index in $\mathsf{Arr}$) and 84 (the previous value in $\mathsf{Acc}$):

  • $\mathsf{Arr}= [84,67,11,92,36,67]$

  • $ \mathsf{Acc} = [84, (67\cdot84),\bot,\bot,\bot,\bot] = [84, 2,\bot,\bot,\bot,\bot]$

The next value will be the multiplication of: 11 (the value at the same index in $\mathsf{Arr}$) and 2 (the previous value in $\mathsf{Acc}$):

  • $\mathsf{Arr}= [84,67,11,92,36,67]$
  • $ \mathsf{Acc} = [84, 2,(11\cdot2),\bot,\bot,\bot] = [84,2,22,\bot,\bot,\bot]$
  • $ \mathsf{Acc} = [84, 2,22,(92\cdot22),\bot,\bot] = [84,2,22,84,\bot,\bot]$
  • $ \mathsf{Acc} = [84, 2,22,84,(36\cdot84),\bot] = [84,2,22,84,17,\bot]$
  • $ \mathsf{Acc} = [84,2,22,84,17,(67\cdot17)] = [84, 2, 22, 84, 17, 72]$

Notice the last value in $\mathsf{Acc}$ is the product of all the entries in $\mathsf{Arr}$. The prover wants to show five constraints:

  1. The first value in $\mathsf{Acc_1}$ matches the first value in $\mathsf{Arr_1}$
  2. The first value in $\mathsf{Acc_2}$ matches the first value in $\mathsf{Arr_2}$
  3. The rest of the values in $\mathsf{Acc}_1$ are of the form $\mathsf{Acc_1}[i]=\mathsf{Arr_1}[i]\cdot\mathsf{Acc_1}[i-1]$
  4. The rest of the values in $\mathsf{Acc}_2$ are of the form $\mathsf{Acc_2}[i]=\mathsf{Arr_2}[i]\cdot\mathsf{Acc_2}[i-1]$
  5. The last value in $\mathsf{Acc_1}$ matches the last value in $\mathsf{Acc_2}$

If all five constraints are true, then entries of $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ have the same product.

Last, while it is not necessary to do, it is often convenient to hold the the value of the product at the start of the array $\mathsf{Acc}$ instead of the end. For this reason, the mathematical explaination below will construct $\mathsf{Acc}$ “backwards” (or right-to-left) from the above example, where the last value of $\mathsf{Acc}$ matches the last value of $\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\mathsf{Acc}$ is the product of all entries:

  • $\mathsf{Arr}= [84,67,11,92,36,67]$
  • $ \mathsf{Acc} = [\bot, \bot, \bot, \bot, \bot, 67]$
  • $ \mathsf{Acc} = [\bot, \bot, \bot, \bot, 84, 67]$
  • $\ldots$
  • $ \mathsf{Acc} = [72, 84, 36, 65, 84, 67]$
  • and the product of all entries in $\mathsf{Arr}$ is 72

Protocol Details +#

The prover ($\mathcal{P}$) holds two arrays $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ of $n$ integers from $\mathbb{Z}_q$: $[a_0, a_1, a_2, \dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that they have the same undisclosed product. The prover will encode the two arrays into polynomials, $\mathsf{Poly}_\mathsf{Arr_1}$ and $\mathsf{Poly}_\mathsf{Arr_2}$ (using evaluation points on the domain $\mathcal{H}_\kappa$) and commit to them as $K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_2}$. The verifier ($\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_2}$.

In order to prove $K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_2}$ are consistent, the prover will build two helper arrays $\mathsf{Acc_1}$ and $\mathsf{Acc_2}$ called accumulators (or accumulating arrays or incremental arrays). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$, the prover will also encode $\mathsf{Acc_1}$ and $\mathsf{Acc_2}$ as a polynomials and provide a commitment to the verifier of each one. The idea is that the prover will prove a relation between each $\mathsf{Arr}$ and its $\mathsf{Acc}$; and a relation between $\mathsf{Acc_1}$ and $\mathsf{Acc_2}$. Put together, it will imply the correct relation between $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$.

We will illustrate a small numerical example in $\mathbb{Z}_{97}$ of constructing an accumulator $\mathsf{Acc}$ for the array $\mathsf{Arr}= [84,67,11,92,36,67]$. The idea is to create a new array, $\mathsf{Acc}$, that starts the same as $\mathsf{Arr}$ and ends with the product of all entries of $\mathsf{Arr}$, by folding in the integers from $\mathsf{Arr}$ one-by-one with multiplication. Then each value in the new array will depend on only two values, as below.

The first value in $\mathsf{Acc}$ will be a copy of the first value from $\mathsf{Arr}$:

  • $\mathsf{Arr}= [84,67,11,92,36,67]$

  • $\mathsf{Acc}= [84, \bot,\bot,\bot,\bot,\bot] $

The next value will be the multiplication (mod 97) of: 67 (the value at the same index in $\mathsf{Arr}$) and 84 (the previous value in $\mathsf{Acc}$):

  • $\mathsf{Arr}= [84,67,11,92,36,67]$

  • $ \mathsf{Acc} = [84, (67\cdot84),\bot,\bot,\bot,\bot] = [84, 2,\bot,\bot,\bot,\bot]$

The next value will be the multiplication of: 11 (the value at the same index in $\mathsf{Arr}$) and 2 (the previous value in $\mathsf{Acc}$):

  • $\mathsf{Arr}= [84,67,11,92,36,67]$
  • $ \mathsf{Acc} = [84, 2,(11\cdot2),\bot,\bot,\bot] = [84,2,22,\bot,\bot,\bot]$
  • $ \mathsf{Acc} = [84, 2,22,(92\cdot22),\bot,\bot] = [84,2,22,84,\bot,\bot]$
  • $ \mathsf{Acc} = [84, 2,22,84,(36\cdot84),\bot] = [84,2,22,84,17,\bot]$
  • $ \mathsf{Acc} = [84,2,22,84,17,(67\cdot17)] = [84, 2, 22, 84, 17, 72]$

Notice the last value in $\mathsf{Acc}$ is the product of all the entries in $\mathsf{Arr}$. The prover wants to show five constraints:

  1. The first value in $\mathsf{Acc_1}$ matches the first value in $\mathsf{Arr_1}$
  2. The first value in $\mathsf{Acc_2}$ matches the first value in $\mathsf{Arr_2}$
  3. The rest of the values in $\mathsf{Acc}_1$ are of the form $\mathsf{Acc_1}[i]=\mathsf{Arr_1}[i]\cdot\mathsf{Acc_1}[i-1]$
  4. The rest of the values in $\mathsf{Acc}_2$ are of the form $\mathsf{Acc_2}[i]=\mathsf{Arr_2}[i]\cdot\mathsf{Acc_2}[i-1]$
  5. The last value in $\mathsf{Acc_1}$ matches the last value in $\mathsf{Acc_2}$

If all five constraints are true, then entries of $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ have the same product.

Last, while it is not necessary to do, it is often convenient to hold the the value of the product at the start of the array $\mathsf{Acc}$ instead of the end. For this reason, the mathematical explanation below will construct $\mathsf{Acc}$ “backwards” (or right-to-left) from the above example, where the last value of $\mathsf{Acc}$ matches the last value of $\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\mathsf{Acc}$ is the product of all entries:

  • $\mathsf{Arr}= [84,67,11,92,36,67]$
  • $ \mathsf{Acc} = [\bot, \bot, \bot, \bot, \bot, 67]$
  • $ \mathsf{Acc} = [\bot, \bot, \bot, \bot, 84, 67]$
  • $\ldots$
  • $ \mathsf{Acc} = [72, 84, 36, 65, 84, 67]$
  • and the product of all entries in $\mathsf{Arr}$ is 72

Protocol Details #

Array Level #

  • $\mathcal{P}$ holds an array $\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \in \mathbb{Z}_q$)
  • $\mathcal{P}$ holds an array $\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \in \mathbb{Z}_q$)
  • $\mathcal{P}$ computes array $\mathsf{Acc_j}$ as follows for $j \in [1,2]$:
    • $\mathsf{Acc_j}[n-1]\leftarrow\mathsf{Arr_j}[n-1]$
    • $\mathsf{Acc_j}[i]\leftarrow\mathsf{Arr_j}[i]\cdot\mathsf{Acc_j}[i+1]$ for $i$ from $n-2$ to 0

Polynomial Level #

We assume arrays $\mathsf{Arr_1}$, $\mathsf{Arr_2}$, $\mathsf{Acc_1}$, and $\mathsf{Acc_2}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\mathcal{H}_\kappa$) are chosen as the multiplicative group of order $\kappa$ with generator $\omega\in\mathbb{G}_\kappa$ (see Background for more). In short, $\omega^0$ is the first element and $\omega^{\kappa-1}$ is the last element of $\mathcal{H}_\kappa$. If $\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product).

Recall the five constraints we want to prove (now adjusted to fit with an $\mathsf{Acc}$ that is constructed “backwards,” as noted above):

  1. The last value in $\mathsf{Acc_1}$ matches the last value in $\mathsf{Arr_1}$
  2. The last value in $\mathsf{Acc_2}$ matches the last value in $\mathsf{Arr_2}$
  3. The rest of the values in $\mathsf{Acc}_1$ are of the form $\mathsf{Acc_1}[i]=\mathsf{Arr_1}[i]\cdot\mathsf{Acc_1}[i-1]$
  4. The rest of the values in $\mathsf{Acc}_2$ are of the form $\mathsf{Acc_2}[i]=\mathsf{Arr_2}[i]\cdot\mathsf{Acc_2}[i-1]$
  5. The first value in $\mathsf{Acc_1}$ matches the first value in $\mathsf{Acc_2}$

In polynomial form, the constraints are:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Arr_1}(X)$,
  2. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_2}(X)=\mathsf{Poly}_\mathsf{Arr_2}(X)$,
  3. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Arr_1}(X)\cdot\mathsf{Poly}_\mathsf{Acc_1}(\omega\cdot X)$
  4. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_2}(X)=\mathsf{Poly}_\mathsf{Arr_2}(X)\cdot\mathsf{Poly}_\mathsf{Acc_2}(\omega\cdot X)$
  5. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Acc_2}(X)$

In constraints 2 and 3, $\mathsf{Poly}_\mathsf{Acc}(\omega\cdot X)$ can also be conceptualized as rotate applied to $\mathsf{Poly}_\mathsf{Acc}(X)$ by one element (rightward in the array view). Also note thats constraint 2 and 3 do not hold at $X=\omega^{\kappa-1}$ because this value is defined by constraint 1 (for the last value of $X$, the “next” value, $\omega X$, wraps back to the first element of the array which is a boundary condition).

We adjust each of these constraints to show an equality with 0:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Arr_1}(X)=0$,
  2. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_2}(X)-\mathsf{Poly}_\mathsf{Arr_2}(X)=0$,
  3. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Arr_1}(X)\cdot\mathsf{Poly}_\mathsf{Acc_1}(\omega\cdot X)=0$
  4. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_2}(X)-\mathsf{Poly}_\mathsf{Arr_2}(X)\cdot\mathsf{Poly}_\mathsf{Acc_2}(\omega\cdot X)=0$
  5. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Acc_2}(X)=0$

Next we take care of the “for $X$” conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.

  1. $\mathsf{Poly}_\mathsf{Vanish1}(X)=(\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Arr_1}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$,
  2. $\mathsf{Poly}_\mathsf{Vanish2}(X)=(\mathsf{Poly}_\mathsf{Acc_2}(X)-\mathsf{Poly}_\mathsf{Arr_2}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$,
  3. $\mathsf{Poly}_\mathsf{Vanish3}(X)=(\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Arr_1}(X)\cdot\mathsf{Poly}_\mathsf{Acc_1}(\omega\cdot X))\cdot(X-\omega^{\kappa-1})=0$
  4. $\mathsf{Poly}_\mathsf{Vanish4}(X)=(\mathsf{Poly}_\mathsf{Acc_2}(X)-\mathsf{Poly}_\mathsf{Arr_2}(X)\cdot\mathsf{Poly}_\mathsf{Acc_2}(\omega\cdot X))\cdot(X-\omega^{\kappa-1})=0$
  5. $\mathsf{Poly}_\mathsf{Vanish5}(X)=(\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Acc_2}(X)\cdot\frac{(X^\kappa-1)}{(X-\omega^0)}=0$

These equations are true for every value of $X \in \mathcal{H}_\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\kappa - 1$, which is a minimal vanishing polynomial for $\mathcal{H}_\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\mathsf{Poly}_\mathsf{Vanish1}(X)$, $\mathsf{Poly}_\mathsf{Vanish2}(X)$, $\mathsf{Poly}_\mathsf{Vanish3}(X)$, $\mathsf{Poly}_\mathsf{Vanish4}(X)$, and $\mathsf{Poly}_\mathsf{Vanish5}(X)$ must be vanishing on $\mathcal{H}_\kappa$ too. Specifically, the prove computes,

  1. $Q_1(X) = \frac{\mathsf{Poly}_\mathsf{Vanish1}(X)}{X^\kappa - 1}$
  2. $Q_2(X) = \frac{\mathsf{Poly}_\mathsf{Vanish2}(X)}{X^\kappa - 1}$
  3. $Q_3(X) = \frac{\mathsf{Poly}_\mathsf{Vanish3}(X)}{X^\kappa - 1}$
  4. $Q_4(X) = \frac{\mathsf{Poly}_\mathsf{Vanish4}(X)}{X^\kappa - 1}$
  5. $Q_5(X) = \frac{\mathsf{Poly}_\mathsf{Vanish5}(X)}{X^\kappa - 1}$

We can replace polynomials $Q_1(X)$, $Q_2(X)$, $Q_3(X)$, $Q_4(X)$, and $Q_5(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\mathsf{Poly}_\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all five $\mathsf{Poly}_\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all five are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\rho$ selected after the commitments to the earlier polynomials are fixed.

$Q(X) = \frac{\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho + \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 + \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 + \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4}{X^\kappa - 1}$

By rearranging, we can get $\mathsf{Poly}_\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\mathcal{H}_\kappa$ and outside of it):

$\mathsf{Poly}_\mathsf{Zero}(X)=\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2} (X) \rho + \mathsf{Poly}_\mathsf{Vanish3}(X) \rho^2 + \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 + \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4 - Q(X)\cdot (X^\kappa - 1)=0$

Ultimately the mult3 argument will satisfy the following constraints at the Commitment Level:

  1. Show $Q(X)$ exists (as a polynomial that evenly divides the divisor)
  2. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is correctly constructed from $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_1}(\omega X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_2}(X)$, $\mathsf{Poly}_\mathsf{Acc_2}(\omega X)$, and $\mathsf{Poly}_\mathsf{Arr_2}(X)$
  3. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is the zero polynomial

Commitment Level #

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}(X))$
  • $K_\mathsf{Acc_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Acc_1}(X))$
  • $K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}(X))$
  • $K_\mathsf{Acc_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Acc_2}(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:

  • $\rho$
  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$
  • $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1},\zeta)$
  • $\mathsf{Poly}_\mathsf{Acc_1}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1},\zeta)$
  • $\mathsf{Poly}_\mathsf{Acc_1}(\zeta\omega)=\mathsf{KZG.Open}(K_\mathsf{Acc_1},\zeta\omega)$
  • $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2},\zeta)$
  • $\mathsf{Poly}_\mathsf{Acc_2}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2},\zeta)$
  • $\mathsf{Poly}_\mathsf{Acc_2}(\zeta\omega)=\mathsf{KZG.Open}(K_\mathsf{Acc_2},\zeta\omega)$
  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish1}= (\mathsf{Poly}_\mathsf{Acc_1}(\zeta)-\mathsf{Poly}_\mathsf{Arr_1}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}$
  • $Y_\mathsf{Vanish2}= (\mathsf{Poly}_\mathsf{Acc_2}(\zeta)-\mathsf{Poly}_\mathsf{Arr_2}(\zeta))\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^{\kappa-1})}$
  • $Y_\mathsf{Vanish3}=(\mathsf{Poly}_\mathsf{Acc_1}(\zeta)-\mathsf{Poly}_\mathsf{Arr_1}(\zeta)\cdot\mathsf{Poly}_\mathsf{Acc_1}(\omega\zeta))\cdot(\zeta-\omega^{\kappa-1})$
  • $Y_\mathsf{Vanish4}= (\mathsf{Poly}_\mathsf{Acc_2}(\zeta)-\mathsf{Poly}_\mathsf{Arr_2}(\zeta)\cdot\mathsf{Poly}_\mathsf{Acc_2}(\omega\zeta))\cdot(\zeta-\omega^{\kappa-1})$
  • $Y_\mathsf{Vanish5}= (\mathsf{Poly}_\mathsf{Acc_1}(\zeta)-\mathsf{Poly}_\mathsf{Acc_2}(\zeta)\cdot\frac{(\zeta^\kappa-1)}{(\zeta-\omega^0)}$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5}- Q(\zeta)\cdot (\zeta^\kappa - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\rho$ and $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Implementations #

Security Proof #

Completeness -#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ such that $\prod_{i = 0}^{n-1} \mathsf{Arr}_1[i]=\prod_{i = 0}^{n-1} \mathsf{Arr}_2[i] \space \forall i \in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$ = Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5}- Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5} - (\frac{\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho + \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 + \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 + \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4}{X^\kappa - 1})(\zeta^\kappa - 1)$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5} - {\mathsf{Poly}_\mathsf{Vanish1}(X) - \mathsf{Poly}_\mathsf{Vanish2}(X) \rho - \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 - \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 - \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4}$

$= 0$

Where the finally equality holds becaue $Y_{\mathsf{Vanish_j}}=\mathsf{Poly_{Vanish_j}}(\zeta)$.

Note also that the second equality relies on the fact that $\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho + \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 + \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 + \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish_1}}(X), \mathsf{Poly_{Vanish_2}}(X)$, $\mathsf{Poly_{Vanish_3}}(X),$ $\mathsf{Poly_{Vanish_4}}(X)$, and $\mathsf{Poly_{Vanish_5}}(X),$ are all vanishing on $\mathcal{H_\kappa}$, i.e. if all three of the following conditions hold for all $X \in \mathcal{H}_\kappa$:

  1. $ (\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Arr_1}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$
  2. $ (\mathsf{Poly}_\mathsf{Acc_2}(X)-\mathsf{Poly}_\mathsf{Arr_2}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$
  3. $(\mathsf{Poly}_\mathsf{Acc_1}(X)-(\mathsf{Poly}_\mathsf{Arr_1}(X) \cdot \mathsf{Poly}_\mathsf{Acc_1}(\omega\cdot X)))\cdot(X-\omega^{\kappa-1})=0$
  4. $ (\mathsf{Poly}_\mathsf{Acc_2}(X)-(\mathsf{Poly}_\mathsf{Arr_2}(X) \cdot \mathsf{Poly}_\mathsf{Acc_2}(\omega\cdot X)))\cdot(X-\omega^{\kappa-1})=0$
  5. $ (\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Acc_2}(X)\cdot\frac{(X^\kappa-1)}{(X-\omega^0)}=0$

These conditions, in turn, hold if:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Arr_1}(X)$
  2. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_2}(X)=\mathsf{Poly}_\mathsf{Arr_2}(X)$
  3. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Arr_1}(X) \cdot \mathsf{Poly}_\mathsf{Acc_1}(\omega\cdot X)$
  4. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_2}(X)=\mathsf{Poly}_\mathsf{Arr_2}(X) \cdot \mathsf{Poly}_\mathsf{Acc_2}(\omega\cdot X)$
  5. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Acc_2}(X)$

Where we get the “For $X$” due to zeroing parts of the polynomials (see zero1). Since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$, the above conditions are true if:

  1. The last value in $\mathsf{Acc_1}$ matches the last value in $\mathsf{Arr_1}$
  2. The last value in $\mathsf{Acc_2}$ matches the last value in $\mathsf{Arr_2}$
  3. The rest of the values in $\mathsf{Acc}_1$ are of the form $\mathsf{Acc_1}[i]=\mathsf{Arr_1}[i] \cdot \mathsf{Acc_1}[i-1]$
  4. The rest of the values in $\mathsf{Acc}_2$ are of the form $\mathsf{Acc_2}[i]=\mathsf{Arr_2}[i] \cdot \mathsf{Acc_2}[i-1]$
  5. The first value in $\mathsf{Acc_1}$ matches the first value in $\mathsf{Acc_2}$

Which are precisely the conditions the Intuitions sections explains will hold if the prover contructs their Accumulators by following the protocol and using $\mathsf{Arr}_1$ and $\mathsf{Arr_2}$ such that $\prod_{i = 0}^{n-1} \mathsf{Arr}_1[i] =\prod_{i = 0}^{n-1} \mathsf{Arr}_2[i] \space \forall i \in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.

Soundness -#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_{2}}(X)$, $\mathsf{Poly}_\mathsf{Arr_{2}}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_{2}}(X)$, $\mathsf{Poly}_\mathsf{Arr_{2}}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_\mathsf{Zero}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}A$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\prod_{i = 0}^{n-1} \mathsf{Arr_1}[i]\neq\prod_{i = 0}^{n-1} \mathsf{Arr_2}[i]$

Our proof is as follows:

For the second win condition to be fulfilled, one of the five constraints must be false. But then the $\mathsf{Poly}_\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, also writes commitments to $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_2}(X)$, and $\mathsf{Poly}_\mathsf{Arr_2}(X)$. Each commitment $\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_1}(\zeta\omega)$, $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_2}(\zeta)$, and $\mathsf{Poly}_\mathsf{Acc_2}(\zeta\omega)$ can each only feasibliy be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4Y_\mathsf{Vanish5}}{(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4Y_\mathsf{Vanish5}}{(\zeta^]kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge +#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ such that $\prod_{i = 0}^{n-1} \mathsf{Arr}_1[i]=\prod_{i = 0}^{n-1} \mathsf{Arr}_2[i] \space \forall i \in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$ = Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5}- Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5} - (\frac{\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho + \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 + \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 + \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4}{X^\kappa - 1})(\zeta^\kappa - 1)$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4 Y_\mathsf{Vanish5} - {\mathsf{Poly}_\mathsf{Vanish1}(X) - \mathsf{Poly}_\mathsf{Vanish2}(X) \rho - \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 - \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 - \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4}$

$= 0$

Where the finally equality holds because $Y_{\mathsf{Vanish_j}}=\mathsf{Poly_{Vanish_j}}(\zeta)$.

Note also that the second equality relies on the fact that $\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho + \mathsf{Poly}_\mathsf{Vanish3}(X)\rho^2 + \mathsf{Poly}_\mathsf{Vanish4}(X)\rho^3 + \mathsf{Poly}_\mathsf{Vanish5}(X)\rho^4$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish_1}}(X), \mathsf{Poly_{Vanish_2}}(X)$, $\mathsf{Poly_{Vanish_3}}(X),$ $\mathsf{Poly_{Vanish_4}}(X)$, and $\mathsf{Poly_{Vanish_5}}(X),$ are all vanishing on $\mathcal{H_\kappa}$, i.e. if all three of the following conditions hold for all $X \in \mathcal{H}_\kappa$:

  1. $ (\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Arr_1}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$
  2. $ (\mathsf{Poly}_\mathsf{Acc_2}(X)-\mathsf{Poly}_\mathsf{Arr_2}(X))\cdot\frac{(X^\kappa-1)}{(X-\omega^{\kappa-1})}=0$
  3. $(\mathsf{Poly}_\mathsf{Acc_1}(X)-(\mathsf{Poly}_\mathsf{Arr_1}(X) \cdot \mathsf{Poly}_\mathsf{Acc_1}(\omega\cdot X)))\cdot(X-\omega^{\kappa-1})=0$
  4. $ (\mathsf{Poly}_\mathsf{Acc_2}(X)-(\mathsf{Poly}_\mathsf{Arr_2}(X) \cdot \mathsf{Poly}_\mathsf{Acc_2}(\omega\cdot X)))\cdot(X-\omega^{\kappa-1})=0$
  5. $ (\mathsf{Poly}_\mathsf{Acc_1}(X)-\mathsf{Poly}_\mathsf{Acc_2}(X)\cdot\frac{(X^\kappa-1)}{(X-\omega^0)}=0$

These conditions, in turn, hold if:

  1. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Arr_1}(X)$
  2. For $X=w^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_2}(X)=\mathsf{Poly}_\mathsf{Arr_2}(X)$
  3. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Arr_1}(X) \cdot \mathsf{Poly}_\mathsf{Acc_1}(\omega\cdot X)$
  4. For all $X$ except $X=\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Acc_2}(X)=\mathsf{Poly}_\mathsf{Arr_2}(X) \cdot \mathsf{Poly}_\mathsf{Acc_2}(\omega\cdot X)$
  5. For $X=w^0$: $\mathsf{Poly}_\mathsf{Acc_1}(X)=\mathsf{Poly}_\mathsf{Acc_2}(X)$

Where we get the “For $X$” due to zeroing parts of the polynomials (see zero1). Since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$, the above conditions are true if:

  1. The last value in $\mathsf{Acc_1}$ matches the last value in $\mathsf{Arr_1}$
  2. The last value in $\mathsf{Acc_2}$ matches the last value in $\mathsf{Arr_2}$
  3. The rest of the values in $\mathsf{Acc}_1$ are of the form $\mathsf{Acc_1}[i]=\mathsf{Arr_1}[i] \cdot \mathsf{Acc_1}[i-1]$
  4. The rest of the values in $\mathsf{Acc}_2$ are of the form $\mathsf{Acc_2}[i]=\mathsf{Arr_2}[i] \cdot \mathsf{Acc_2}[i-1]$
  5. The first value in $\mathsf{Acc_1}$ matches the first value in $\mathsf{Acc_2}$

Which are precisely the conditions the Intuitions sections explains will hold if the prover constructs their Accumulators by following the protocol and using $\mathsf{Arr}_1$ and $\mathsf{Arr_2}$ such that $\prod_{i = 0}^{n-1} \mathsf{Arr}_1[i] =\prod_{i = 0}^{n-1} \mathsf{Arr}_2[i] \space \forall i \in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.

Soundness +#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_{2}}(X)$, $\mathsf{Poly}_\mathsf{Arr_{2}}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_{2}}(X)$, $\mathsf{Poly}_\mathsf{Arr_{2}}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_\mathsf{Zero}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}A$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\prod_{i = 0}^{n-1} \mathsf{Arr_1}[i]\neq\prod_{i = 0}^{n-1} \mathsf{Arr_2}[i]$

Our proof is as follows:

For the second win condition to be fulfilled, one of the five constraints must be false. But then the $\mathsf{Poly}_\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, also writes commitments to $\mathsf{Poly}_\mathsf{Acc_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Acc_2}(X)$, and $\mathsf{Poly}_\mathsf{Arr_2}(X)$. Each commitment $\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_1}(\zeta\omega)$, $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_2}(\zeta)$, and $\mathsf{Poly}_\mathsf{Acc_2}(\zeta\omega)$ can each only feasibly be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4Y_\mathsf{Vanish5}}{(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4Y_\mathsf{Vanish5}}{(\zeta^]kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge #

We prove that the above protocol is zero-knowledge when $\mathsf{PolyCommit}_\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ that knows the trapdoor $\tau$, which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ chooses arbitrary values for ${\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Acc_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$ and $\mathsf{Poly}_\mathsf{Acc_2}(\tau)$, then computes $g^{\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, $g^{\mathsf{Poly}_\mathsf{Acc_1}(\tau)}$, $g^{\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$, and $g^{\mathsf{Poly}_\mathsf{Acc_2}(\tau)}$ to write as the commitments $K_\mathsf{Arr_1}$, $ K_\mathsf{Acc_1}$, $K_\mathsf{Arr_2}$, and $ K_\mathsf{Acc_2}$. $\mathcal{S}$ then generates the challenge evaluation point $\rho$ (by strong Fiat-Shamir) and computes $Q(\tau)$ using $\rho$ and the values it chose for ${\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Acc_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$ and $\mathsf{Poly}_\mathsf{Acc_2}(\tau)$. $\mathcal{S}$ writes the commitment $K_Q = g^{Q(\tau)}$.

Now, $\mathcal{S}$ generates the second random challenge point $\zeta$ (which we assume is not in $\mathcal{H}_\kappa$; if it is in $\mathcal{H}_\kappa$, $\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\mathcal{S}$ then create fake opening proofs for $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_1}(\zeta\omega)$, $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)$, $\mathsf{Poly}_\mathsf{Acc_2}(\zeta)$, and $\mathsf{Poly}_\mathsf{Acc_2}(\zeta\omega)$, to arbitrary values. This is done using the knowledge of $\tau$, calculating the respective witness $q(\tau) = \frac{{f(\tau) - f(\zeta)}}{\tau - \zeta}$ for each of the polynomials.

Finally, $\mathcal{S}$ creates a fake opening proof for $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} + \rho^2 Y_\mathsf{Vanish3} + \rho^3 Y_\mathsf{Vanish4} + \rho^4Y_\mathsf{Vanish5}}{(\zeta^\kappa - 1)}$. This is done using knowledge of $\tau$ to calculate an accepting witness $q(\tau)$, as above. This means that $Y_\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

  • For mult2, the proof is written with a simulator that doesn’t know the trapdoor; however, with small alterations the proof for mult2 should apply here and vice versa
\ No newline at end of file diff --git a/docs/gadgets/range/index.html b/docs/gadgets/range/index.html index b9d0a69..fff5b6c 100644 --- a/docs/gadgets/range/index.html +++ b/docs/gadgets/range/index.html @@ -1,7 +1,7 @@ Range | Handbook - +
Range

Range diff --git a/docs/gadgets/rotate/index.html b/docs/gadgets/rotate/index.html index 463fe52..8705039 100644 --- a/docs/gadgets/rotate/index.html +++ b/docs/gadgets/rotate/index.html @@ -1,7 +1,7 @@ Rotate | Handbook - +
Rotate

Rotate @@ -10,9 +10,9 @@ #

Assume $\mathsf{Arr}$ is an array of data of size $n$. It is encoded as the y-coordinates into univariant polynomials where the x-coordinates (called the domain $\mathcal{H}_\kappa$) are chosen as the multiplicative group of order $\kappa$ with generator $\omega\in\mathbb{G}_\kappa$ (see Background for more). In short, $\omega^0$ is the first element and $\omega^{\kappa-1}$ is the last element of $\mathcal{H}_\kappa$. We call our polynomial $\mathsf{Poly}_\mathsf{Arr}(X)$. The goal is to construct an output polynomial $\mathsf{Poly_\mathsf{Arr'}}$ where all the elements in $\mathsf{Arr}$ have been rotated by $\alpha$ positions; i.e. $\mathsf{Arr'}[i] \leftarrow \mathsf{Arr}[i + \alpha]$. Here, the index is defined mod $n$.

Written in terms the polynomials, the goal is that $\mathsf{Poly_\mathsf{Arr'}}(\omega^i) = \mathsf{Poly_\mathsf{Arr}}(\omega^i\cdot\omega^\alpha)$ for all $i \in [0, n-1]$. To this end, we define $\mathsf{Poly_\mathsf{Arr}}(X) = \mathsf{Poly_\mathsf{Arr}}(X)\cdot\omega^\alpha$ and demonstrate below why this satisfies the requirements of the output polynomials.

Consider $\mathsf{Poly_\mathsf{Arr}}(X) = c_{n-1}X^{n-1} + \dots + c_2X^2 + c_1X + c_0$. Then:

$\mathsf{Poly_\mathsf{Arr'}}(X)$

$= \mathsf{Poly_Arr}(X) \cdot \omega^\alpha$

$= (c_{n-1}X^{n-1} + \dots + c_2X^2 + c_1X + c_0)(\omega^\alpha) $

$= c_{n-1}X^{n-1}\cdot\omega^\alpha + \dots + c_2X^2\cdot\omega^\alpha + c_1X\cdot\omega^\alpha + c_0\cdot\omega^\alpha$

$= \mathsf{Poly_\mathsf{Arr}}(X\cdot\omega^\alpha)$

In particular, $\mathsf{Poly_{Arr'}}(\omega^i) = \mathsf{Poly_\mathsf{Arr}}(\omega^i\cdot\omega^\alpha)$ for $i \in [0, n-1]$. We also note that $\omega^n = \omega^0$, since $\omega$ is of order $\kappa$. Thus the exponent of $\omega$ is defined mod $n$, like the indexing of $\mathsf{Arr}$. This means that $\omega^i\cdot\omega^\alpha$ wraps around to have the rotation defined as it should be for $i + \alpha \gt n-1$.

To prove the relation between $\mathsf{Arr}$ and $\mathsf{Arr'}$, the prover must commit to the two polynomials, $\mathsf{Poly_{Arr}}$ and $\mathsf{Poly_{Arr'}}$ as $K_{\mathsf{Arr}}$ and $K_\mathsf{Arr'}$. The verifier ($\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_2}$. The relation will be proven by showing $K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_2}$ and consistent; this mean verifying that $\mathsf{Arr'}[i] \leftarrow \mathsf{Arr}[i + \alpha]$.

Protocol Details #

Array Level #

* $\mathcal{P}$ holds an array $\mathsf{Arr_1} = [a_0, a_1, a_2, \dots, a_{n-1}]$ of $n$ integers ($a_{i} \in \mathbb{Z}_q$)

* $\mathcal{P}$ holds or computes $\mathsf{Arr}'$ such that:

* $\mathsf{Arr}'[i]= \mathsf{Arr}[i+\alpha]$ for $i \in [0, n-1]$

Polynomial Level -#

We assume that $\mathsf{Arr}$ and $\mathsf{Arr'}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\mathcal{H}_\kappa$) are chosen as the multiplicative group of order $\kappa$ with generator $\omega\in\mathbb{G}_\kappa$ (see Background for more). In short, $\omega^0$ is the first element and $\omega^{\kappa-1}$ is the last element of $\mathcal{H}_\kappa$. If $\kappa$ is larger than the length of the arrays, then $\mathsf{Arr}$ can be padded with any value (say, all 1s) as long as this is done before the rotation to create $\mathsf{Arr'}$ is computed.

Recall the constrant we want to prove:

  1. $\mathsf{Arr}'[i]= \mathsf{Arr}[i+\alpha]$ for $i \in [0, n-1]$

We write the constraint in polynomial form:

  1. For all $X$ from $\omega^0$ to $\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Arr'}(X) = \mathsf{Poly}_\mathsf{Arr}(X)\cdot\omega^\alpha$

We adjust the constraint to show an equality with 0 and label it:

  1. $\mathsf{Poly}_\mathsf{Vanish}(X)= \mathsf{Poly}_\mathsf{Arr'}(X) - \mathsf{Poly}_\mathsf{Arr}(X)\cdot\omega^\alpha = 0$

This equation is true for every value of $X \in \mathcal{H}_\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\kappa - 1$, which is a minimal vanishing polynomial for $\mathcal{H}_\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\mathsf{Poly}_\mathsf{Vanish}(X)$ must be vanishing on $\mathcal{H}_\kappa$ too. Specifically, the prover computes:

  1. $Q(X) = \frac{\mathsf{Poly}_\mathsf{Vanish}(X)}{X^\kappa - 1}$

By rearranging, we can get $\mathsf{Poly}_\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\mathcal{H}_\kappa$ and outside of it):

$\mathsf{Poly}_\mathsf{Zero}(X)=\mathsf{Poly}_\mathsf{Vanish}(X) - Q(X)\cdot (X^\kappa - 1)=0$

Ultimately the rotate argument will satisfy the following constraints at the Commitment Level:

  1. Show $Q(X)$ exists (as a polynomial that evenly divides the divisor)
  2. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is correctly constructed from $\mathsf{Poly}_\mathsf{Arr}(X)$ and $\mathsf{Poly}_\mathsf{Arr'}(X)$
  3. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is the zero polynomial

Commitment Level -#

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr}(X))$

  • $K_\mathsf{Arr'}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr'}(X))$

  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$

  • $\mathsf{Poly}_\mathsf{Arr}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr},\zeta)$

  • $$\mathsf{Poly}\mathsf{Arr’}(\zeta)=\mathsf{KZG.Open}(K\mathsf{Arr’},\zeta)$

  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish}= \mathsf{Poly}_\mathsf{Arr'}(\zeta) - \mathsf{Poly}_\mathsf{Arr}(\zeta)\cdot\omega^\alpha$

  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Security Proof +#

We assume that $\mathsf{Arr}$ and $\mathsf{Arr'}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\mathcal{H}_\kappa$) are chosen as the multiplicative group of order $\kappa$ with generator $\omega\in\mathbb{G}_\kappa$ (see Background for more). In short, $\omega^0$ is the first element and $\omega^{\kappa-1}$ is the last element of $\mathcal{H}_\kappa$. If $\kappa$ is larger than the length of the arrays, then $\mathsf{Arr}$ can be padded with any value (say, all 1s) as long as this is done before the rotation to create $\mathsf{Arr'}$ is computed.

Recall the constraint we want to prove:

  1. $\mathsf{Arr}'[i]= \mathsf{Arr}[i+\alpha]$ for $i \in [0, n-1]$

We write the constraint in polynomial form:

  1. For all $X$ from $\omega^0$ to $\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Arr'}(X) = \mathsf{Poly}_\mathsf{Arr}(X)\cdot\omega^\alpha$

We adjust the constraint to show an equality with 0 and label it:

  1. $\mathsf{Poly}_\mathsf{Vanish}(X)= \mathsf{Poly}_\mathsf{Arr'}(X) - \mathsf{Poly}_\mathsf{Arr}(X)\cdot\omega^\alpha = 0$

This equation is true for every value of $X \in \mathcal{H}_\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\kappa - 1$, which is a minimal vanishing polynomial for $\mathcal{H}_\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\mathsf{Poly}_\mathsf{Vanish}(X)$ must be vanishing on $\mathcal{H}_\kappa$ too. Specifically, the prover computes:

  1. $Q(X) = \frac{\mathsf{Poly}_\mathsf{Vanish}(X)}{X^\kappa - 1}$

By rearranging, we can get $\mathsf{Poly}_\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\mathcal{H}_\kappa$ and outside of it):

$\mathsf{Poly}_\mathsf{Zero}(X)=\mathsf{Poly}_\mathsf{Vanish}(X) - Q(X)\cdot (X^\kappa - 1)=0$

Ultimately the rotate argument will satisfy the following constraints at the Commitment Level:

  1. Show $Q(X)$ exists (as a polynomial that evenly divides the divisor)
  2. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is correctly constructed from $\mathsf{Poly}_\mathsf{Arr}(X)$ and $\mathsf{Poly}_\mathsf{Arr'}(X)$
  3. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is the zero polynomial

Commitment Level +#

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr}(X))$

  • $K_\mathsf{Arr'}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr'}(X))$

  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$

  • $\mathsf{Poly}_\mathsf{Arr}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr},\zeta)$

  • $\mathsf{Poly}_\mathsf{Arr'}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr'},\zeta)$

  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish}= \mathsf{Poly}_\mathsf{Arr'}(\zeta) - \mathsf{Poly}_\mathsf{Arr}(\zeta)\cdot\omega^\alpha$

  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Security Proof #

Completeness -#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr'}$ and $\mathsf{Arr}$ such that $\mathsf{Arr'}[i] = \mathsf{Arr}[i +\alpha] \space \forall i \in [0, n-1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$ = Y_\mathsf{Vanish} - Q(\zeta)(\zeta^\kappa - 1)$

$ = \mathsf{Poly_{Arr'}}(\zeta) - \mathsf{Poly_{Arr}}(\zeta)\cdot \omega^\alpha - Q(\zeta)(\zeta^\kappa - 1)$

$= \mathsf{Poly_{Arr'}}(\zeta) - \mathsf{Poly_{Arr}}(\zeta)\cdot \omega^\alpha - \frac{\mathsf{Poly_{Vanish}}(\zeta)}{\zeta^\kappa - 1}\cdot(\zeta^\kappa - 1)$

$= \mathsf{Poly_{Arr'}}(\zeta) - \mathsf{Poly_{Arr}}(\zeta)\cdot \omega^\alpha - \mathsf{Poly_{Arr'}}(\zeta) + \mathsf{Poly_{Arr}}(\zeta)\cdot \omega^\alpha$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish}}(X)$ is vanishing on $\mathcal{H_\kappa}$, i.e. if $\mathsf{Poly}_\mathsf{Arr'}(X) - \mathsf{Poly}_\mathsf{Arr}(X)\cdot\omega^\alpha = 0 \space \forall X \in \mathcal{H_\kappa}$. This is true if $\mathsf{Poly}_\mathsf{Arr'}(X) - \mathsf{Poly}_\mathsf{Arr}(X\cdot\omega^\alpha) = 0 \space \forall X \in \mathcal{H_\kappa}$, which is in turn true if $\mathsf{Arr'}[i] - \mathsf{Arr}[i + \alpha] = 0 \space \forall i \in [0, \kappa -1]$, since $\mathsf{Poly_Arr}(\omega^i)=\mathsf{Arr}[i] \space \forall i \in [0, \kappa -1]$. But $\mathsf{Arr'}[i] - \mathsf{Arr}[i + \alpha] = 0 \space \forall i \in [0, n-1]$ is precisely the relation between $\mathsf{Arr'}$ and $\mathsf{Arr}$ that we assumed held for our prover (if $\kappa \gt n$ then the arrays get padded such that this relation still holds), thus the $Y_\mathsf{Zero}(X)$ it creates by following the protocol is the zero polynomial, and its transcipt will be accepted.

Soundness -#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$, the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr}(X)$, $\mathsf{Poly}_\mathsf{Arr'}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr}(X)$, $\mathsf{Poly}_\mathsf{Arr'}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Arr'}[i] \neq \mathsf{Arr}[i + \alpha]$ for some $i \in [0, n-1]$

Our proof is as follows:

For the second win condition to be fulfilled, there must be some $i \in [0, n-1]$ such that $\mathsf{Arr'}[i] \neq \mathsf{Arr}[i + \alpha]$. But then $\mathsf{Poly}_\mathsf{Vanish}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Arr}(X)$ and $\mathsf{Poly}_\mathsf{Arr'}(X)$. All commitments $\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr}(\zeta)$ and $\mathsf{Poly}_\mathsf{Arr'}(\zeta)$ can each only feasibliy be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish}} {(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge +#

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr'}$ and $\mathsf{Arr}$ such that $\mathsf{Arr'}[i] = \mathsf{Arr}[i +\alpha] \space \forall i \in [0, n-1]$ can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$ = Y_\mathsf{Vanish} - Q(\zeta)(\zeta^\kappa - 1)$

$ = \mathsf{Poly_{Arr'}}(\zeta) - \mathsf{Poly_{Arr}}(\zeta)\cdot \omega^\alpha - Q(\zeta)(\zeta^\kappa - 1)$

$= \mathsf{Poly_{Arr'}}(\zeta) - \mathsf{Poly_{Arr}}(\zeta)\cdot \omega^\alpha - \frac{\mathsf{Poly_{Vanish}}(\zeta)}{\zeta^\kappa - 1}\cdot(\zeta^\kappa - 1)$

$= \mathsf{Poly_{Arr'}}(\zeta) - \mathsf{Poly_{Arr}}(\zeta)\cdot \omega^\alpha - \mathsf{Poly_{Arr'}}(\zeta) + \mathsf{Poly_{Arr}}(\zeta)\cdot \omega^\alpha$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\kappa - 1$. This is true if $\mathsf{Poly_{Vanish}}(X)$ is vanishing on $\mathcal{H_\kappa}$, i.e. if $\mathsf{Poly}_\mathsf{Arr'}(X) - \mathsf{Poly}_\mathsf{Arr}(X)\cdot\omega^\alpha = 0 \space \forall X \in \mathcal{H_\kappa}$. This is true if $\mathsf{Poly}_\mathsf{Arr'}(X) - \mathsf{Poly}_\mathsf{Arr}(X\cdot\omega^\alpha) = 0 \space \forall X \in \mathcal{H_\kappa}$, which is in turn true if $\mathsf{Arr'}[i] - \mathsf{Arr}[i + \alpha] = 0 \space \forall i \in [0, \kappa -1]$, since $\mathsf{Poly_Arr}(\omega^i)=\mathsf{Arr}[i] \space \forall i \in [0, \kappa -1]$. But $\mathsf{Arr'}[i] - \mathsf{Arr}[i + \alpha] = 0 \space \forall i \in [0, n-1]$ is precisely the relation between $\mathsf{Arr'}$ and $\mathsf{Arr}$ that we assumed held for our prover (if $\kappa \gt n$ then the arrays get padded such that this relation still holds), thus the $Y_\mathsf{Zero}(X)$ it creates by following the protocol is the zero polynomial, and its transcript will be accepted.

Soundness +#

We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$, the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr}(X)$, $\mathsf{Poly}_\mathsf{Arr'}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr}(X)$, $\mathsf{Poly}_\mathsf{Arr'}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Arr'}[i] \neq \mathsf{Arr}[i + \alpha]$ for some $i \in [0, n-1]$

Our proof is as follows:

For the second win condition to be fulfilled, there must be some $i \in [0, n-1]$ such that $\mathsf{Arr'}[i] \neq \mathsf{Arr}[i + \alpha]$. But then $\mathsf{Poly}_\mathsf{Vanish}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Arr}(X)$ and $\mathsf{Poly}_\mathsf{Arr'}(X)$. All commitments $\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr}(\zeta)$ and $\mathsf{Poly}_\mathsf{Arr'}(\zeta)$ can each only feasibly be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish}} {(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge #

We prove that the above protocol is zero-knowledge when $\mathsf{PolyCommit}_\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ that knows the trapdoor $\tau$, which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ chooses arbitrary values for ${\mathsf{Poly}_\mathsf{Arr}(\tau)}$ and ${\mathsf{Poly}_\mathsf{Arr'}(\tau)}$, then computes $g^{\mathsf{Poly}_\mathsf{Arr}(\tau)}$ and $g^{\mathsf{Poly}_\mathsf{Arr'}(\tau)}$ to write as the commitments $ K_\mathsf{Arr}$ and $K_\mathsf{Arr'}$. $\mathcal{S}$ computes $Q(\tau)$ using the values it chose for ${\mathsf{Poly}_\mathsf{Arr}(\tau)}$ and ${\mathsf{Poly}_\mathsf{Arr'}(\tau)}$. $\mathcal{S}$ writes the commitment $K_Q = g^{Q(\tau)}$.

Now, $\mathcal{S}$ generates the random challenge point $\zeta$ (which we assume is not in $\mathcal{H}_\kappa$; if it is in $\mathcal{H}_\kappa$, $\mathcal{S}$ simply restarts and runs from the beginning). This is by strong Fiat-Shamir. $\mathcal{S}$ then create fake opening proofs for ${\mathsf{Poly}_\mathsf{Arr}(\zeta)}$ and ${\mathsf{Poly}_\mathsf{Arr'}(\zeta)}$, to arbitrary values. This is done using the knowledge of $\tau$, calculating the respective witness $q(\tau) = \frac{{f(\tau) - f(\zeta)}}{\tau - \zeta}$ for each of the polynomials.

Finally, $\mathcal{S}$ creates a fake opening proof for $Q(\zeta) = \frac{Y_\mathsf{Vanish}}{(\zeta^\kappa - 1)}$. This is done using knowledge of $\tau$ to calculate an accepting witness $q(\tau)$, as above. This means that $Y_\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

\ No newline at end of file diff --git a/docs/gadgets/shuffle1/index.html b/docs/gadgets/shuffle1/index.html index f068406..f90d0b5 100644 --- a/docs/gadgets/shuffle1/index.html +++ b/docs/gadgets/shuffle1/index.html @@ -1,18 +1,18 @@ Shuffle1 | Handbook - +
Shuffle1

Shuffle (Type 1) #

Recap of types #

TypeDescriptionRecapThis
shuffle1$\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1)$Array $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ for some undisclosed permutation $\pi$.
shuffle2$\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1 ,\pi)$Array $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ under a disclosed permutation $\pi$.

Relation #

$ \mathcal{R}_{\mathtt{shuffle1}} := \left\{ \begin{array}{l} (K_\mathsf{Arr_1},K_\mathsf{Arr2}) \end{array} \middle | \begin{array}{l} \mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \dots, a_{(1,n-1)}],\\ \mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \dots, a_{(2,n-1)}], \\ \mathsf{Poly}_\mathsf{Arr_1}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr_1}), \\ \mathsf{Poly}_\mathsf{Arr_2}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr_2}), \\ K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}),\\ K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}), \end{array} \right\} $

Intuition -#

The prover ($\mathcal{P}$) holds 2 arrays, $\mathsf{Arr_1 }$ and $\mathsf{Arr_2}$, of $n$ integers from $\mathbb{Z}_q$: $[a_0, a_1, a_2, \dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ for some undisclosed permutation $\pi$. The prover will encode the two arrays into polynomials, $\mathsf{Poly}_\mathsf{Arr_1}$ and $\mathsf{Poly}_\mathsf{Arr_2}$ (using evaluation points on the domain $\mathcal{H}_\kappa$) and commit to them as $K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_2}$. The verifier ($\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_2}$.

One idea to check that $\mathsf{Arr_2}$ is a permutation of $\mathsf{Arr_1}$ might be to perform a product check on the two arrays. If the permutation relation holds, then the products will be equal; however, many arrays can have their entries multiply to the same number, without necessarily containing the same elements.

Instead, the prover constructs two new arrays, $\mathsf{Arr_1}'$ and $\mathsf{Arr_2}'$, where $\mathsf{Arr_j}'$ contains the points $ \{r - \mathsf{Arr_j}[i] \}_{i \in [0, n-1]}$ for $r$ a random field element. Then, a product check is run on these two arrays. One way to understand why this works is to think of it as creating two auxilary polynomials, ${\mathsf{Poly}}_\mathsf{Arr_1'}$ and ${\mathsf{Poly}}_\mathsf{Arr_2'}$, where $\mathsf{Poly}_\mathsf{Arr_j'}(X) = \prod^{n-1}_{i = 1}(X - \mathsf{Arr_j}[i])$. If ${\mathsf{Poly}}_\mathsf{Arr_1'}$ = $\mathsf{Poly}_\mathsf{Arr_2'}$, then they have the same factorization. This means that $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ must contain the same elements (in possibly different orders); in other words, $\mathsf{Arr}_2$ is a permutation of $\mathsf{Arr}_1$. To check this equality, a random challenge point $r$ is generated and the products are checked at that point. If they are equal at that point then (with overwhelming probabiltiy) the polynomials are equal.

In addition to demontrasting the equality of the product of $\mathsf{Arr_1}'$ and $\mathsf{Arr_2}'$, it must also be shown that these two arrays are defined correctly in terms of the original arrays. In other words, it must be shown that $\mathsf{Arr_j}'[i]= r - \mathsf{Arr_j}[i]$ for $i \in [0, n-1]$. Once this, in addition to the product check, has been done, we have shown that $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ for some undisclosed permutation $\pi$.

Protocol Details +#

The prover ($\mathcal{P}$) holds 2 arrays, $\mathsf{Arr_1 }$ and $\mathsf{Arr_2}$, of $n$ integers from $\mathbb{Z}_q$: $[a_0, a_1, a_2, \dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ for some undisclosed permutation $\pi$. The prover will encode the two arrays into polynomials, $\mathsf{Poly}_\mathsf{Arr_1}$ and $\mathsf{Poly}_\mathsf{Arr_2}$ (using evaluation points on the domain $\mathcal{H}_\kappa$) and commit to them as $K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_2}$. The verifier ($\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_2}$.

One idea to check that $\mathsf{Arr_2}$ is a permutation of $\mathsf{Arr_1}$ might be to perform a product check on the two arrays. If the permutation relation holds, then the products will be equal; however, many arrays can have their entries multiply to the same number, without necessarily containing the same elements.

Instead, the prover constructs two new arrays, $\mathsf{Arr_1}'$ and $\mathsf{Arr_2}'$, where $\mathsf{Arr_j}'$ contains the points $ \{r - \mathsf{Arr_j}[i] \}_{i \in [0, n-1]}$ for $r$ a random field element. Then, a product check is run on these two arrays. One way to understand why this works is to think of it as creating two auxiliary polynomials, ${\mathsf{Poly}}_\mathsf{Arr_1'}$ and ${\mathsf{Poly}}_\mathsf{Arr_2'}$, where $\mathsf{Poly}_\mathsf{Arr_j'}(X) = \prod^{n-1}_{i = 1}(X - \mathsf{Arr_j}[i])$. If ${\mathsf{Poly}}_\mathsf{Arr_1'}$ = $\mathsf{Poly}_\mathsf{Arr_2'}$, then they have the same factorization. This means that $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ must contain the same elements (in possibly different orders); in other words, $\mathsf{Arr}_2$ is a permutation of $\mathsf{Arr}_1$. To check this equality, a random challenge point $r$ is generated and the products are checked at that point. If they are equal at that point then (with overwhelming probability) the polynomials are equal.

In addition to demonstrating the equality of the product of $\mathsf{Arr_1}'$ and $\mathsf{Arr_2}'$, it must also be shown that these two arrays are defined correctly in terms of the original arrays. In other words, it must be shown that $\mathsf{Arr_j}'[i]= r - \mathsf{Arr_j}[i]$ for $i \in [0, n-1]$. Once this, in addition to the product check, has been done, we have shown that $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ for some undisclosed permutation $\pi$.

Protocol Details #

Array Level #

  • $\mathcal{P}$ holds an array $\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \in \mathbb{Z}_q$)
  • $\mathcal{P}$ holds an array $\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \in \mathbb{Z}_q$)
  • $\mathcal{P}$ generates the random challenge $r$ and computes $\mathsf{Arr_j}'$ as follows for $j \in [1,2]$:
    • $\mathsf{Arr_j}'[i]= r - \mathsf{Arr_j}[i]$

Polynomial Level #

We assume that $\mathsf{Arr_1}$, $\mathsf{Arr_2}$, $\mathsf{Arr_1'}$, and $\mathsf{Arr_2'}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\mathcal{H}_\kappa$) are chosen as the multiplicative group of order $\kappa$ with generator $\omega\in\mathbb{G}_\kappa$ (see Background for more). In short, $\omega^0$ is the first element and $\omega^{\kappa-1}$ is the last element of $\mathcal{H}_\kappa$. If $\kappa$ is larger than the length of the arrays, the arrays can be padded with elements all of value 1 (or any other value, as long as it is the same for both arrays).

Recall the two steps we want to prove:

  1. $\prod^{n-1}_{i=0}\{r - \mathsf{Arr_1[i]}\} = \prod^{n-1}_{i=0}\{r - \mathsf{Arr_2[i]}\}$
  2. $\mathsf{Arr_j}'[i]= r - \mathsf{Arr_j}[i]$ for $j \in [1,2]$, $0 \leq 1 \leq n-1$

The first step is done as a mult3 product check, and we write the second step as two constraints in polynomial form. From this point on we focus on the polynomial details of the second step.

  1. For all $X$ from $\omega^0$ to $\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Arr_1'}(X) = (r - \mathsf{Poly}_\mathsf{Arr_1}(X))$
  2. For all $X$ from $\omega^0$ to $\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Arr_2'}(X) = (r - \mathsf{Poly}_\mathsf{Arr_2}(X))$

We adjust each of these constraints to show an equality with 0 and label them:

  1. $\mathsf{Poly}_\mathsf{Vanish1}(X)= \mathsf{Poly}_\mathsf{Arr_1'}(X) - (r - \mathsf{Poly}_\mathsf{Arr_1}(X)) = 0$
  2. $\mathsf{Poly}_\mathsf{Vanish2}(X)= \mathsf{Poly}_\mathsf{Arr_2'}(X) - (r - \mathsf{Poly}_\mathsf{Arr_2}(X)) = 0$

This equation is true for every value of $X \in \mathcal{H}_\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\kappa - 1$, which is a minimal vanishing polynomial for $\mathcal{H}_\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\mathsf{Poly}_\mathsf{Vanish}(X)$ must be vanishing on $\mathcal{H}_\kappa$ too. Specifically, the prover computes:

  1. $Q_1(X) = \frac{\mathsf{Poly}_\mathsf{Vanish1}(X)}{X^\kappa - 1}$
  2. $Q_2(X) = \frac{\mathsf{Poly}_\mathsf{Vanish2}(X)}{X^\kappa - 1}$

We can replace polynomials $Q_1(X)$ and $Q_2(X)$ with a single polynomial $Q(X)$. We can do this because both constraints have the same format: $\mathsf{Poly}_\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with both $\mathsf{Poly}_\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if both are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\rho$ selected after the commitments to the earlier polynomials are fixed.

$Q(X) = \frac{\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho}{X^\kappa - 1}$

By rearranging, we can get $\mathsf{Poly}_\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\mathcal{H}_\kappa$ and outside of it):

$\mathsf{Poly}_\mathsf{Zero}(X)=\mathsf{Poly}_\mathsf{Vanish1}(X) + \rho \mathsf{Poly}_\mathsf{Vanish2}(X) - Q(X)\cdot (X^\kappa - 1)=0$

Ultimately the shuffle1 argument will satisfy the following constraints at the Commitment Level:

  1. Show $Q(X)$ exists (as a polynomial that evenly divides the divisor)
  2. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is correctly constructed from $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, and $\mathsf{Poly}_\mathsf{Arr_2'}(X)$
  3. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is the zero polynomial

In addition, it will show that $\prod^{n-1}_{i=0}(r - \mathsf{Arr_1}[i]) = \prod^{n-1}_{i=0}(r - \mathsf{Arr_2}[i])$ using a mult3 product check.

Commitment Level -#

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will create a transcript for the product check, as decribed in mult3. Below, we give details specific to the second step, showing that $\mathsf{Arr_j}'[i]= r - \mathsf{Arr_j}[i]$ for $j \in [1,2]$, $0 \leq 1 \leq n-1$.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}(X))$
  • $K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call this point $r$. It will use this point to define the sets $ \{r - \mathsf{Poly}_\mathsf{Arr_j}(a) \}_{a \in \mathcal{H}_\kappa}$ and run the product check. It will write the product check into the transcript. However, here we focus only on what is relevant to the second step, the point $r$ and the following polynomials, which it also writes to the transcript:

  • $r$
  • $K_\mathsf{Arr_1'}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1'}(X))$
  • $K_\mathsf{Arr_2'}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2'}(X))$​

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:

  • $\rho$
  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$
  • $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_1'}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1'},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_2'}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2'},\zeta)$
  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish1}= \mathsf{Poly}_\mathsf{Arr_1'}(\zeta) - (r - \mathsf{Poly}_\mathsf{Arr_1}(\zeta))$
  • $Y_\mathsf{Vanish2}= \mathsf{Poly}_\mathsf{Arr_2'}(\zeta) - (r - \mathsf{Poly}_\mathsf{Arr_2}(\zeta))$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Implementations +#

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will create a transcript for the product check, as described in mult3. Below, we give details specific to the second step, showing that $\mathsf{Arr_j}'[i]= r - \mathsf{Arr_j}[i]$ for $j \in [1,2]$, $0 \leq 1 \leq n-1$.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}(X))$
  • $K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call this point $r$. It will use this point to define the sets $ \{r - \mathsf{Poly}_\mathsf{Arr_j}(a) \}_{a \in \mathcal{H}_\kappa}$ and run the product check. It will write the product check into the transcript. However, here we focus only on what is relevant to the second step, the point $r$ and the following polynomials, which it also writes to the transcript:

  • $r$
  • $K_\mathsf{Arr_1'}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1'}(X))$
  • $K_\mathsf{Arr_2'}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2'}(X))$​

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:

  • $\rho$
  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$
  • $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_1'}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1'},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_2'}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2'},\zeta)$
  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish1}= \mathsf{Poly}_\mathsf{Arr_1'}(\zeta) - (r - \mathsf{Poly}_\mathsf{Arr_1}(\zeta))$
  • $Y_\mathsf{Vanish2}= \mathsf{Poly}_\mathsf{Arr_2'}(\zeta) - (r - \mathsf{Poly}_\mathsf{Arr_2}(\zeta))$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Implementations #

Security Proof #

Completeness #

We assume completeness of the product check (it is proven in mult3) and conduct a proof of completeness for the rest of the protocol.

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ such that $\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1)$, can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= [\mathsf{Poly}_\mathsf{Arr_1'}(\zeta) - (r - \mathsf{Poly}_\mathsf{Arr_1}(\zeta))] + \rho [\mathsf{Poly}_\mathsf{Arr_2'}(\zeta) - (r - \mathsf{Poly}_\mathsf{Arr_2}(\zeta))] - Q(\zeta) \cdot (\zeta^\kappa - 1)$

$= [\mathsf{Poly}_\mathsf{Arr_1'}(\zeta) - (r - \mathsf{Poly}_\mathsf{Arr_1}(\zeta))] + \rho [\mathsf{Poly}_\mathsf{Arr_2'}(\zeta) - (r - \mathsf{Poly}_\mathsf{Arr_2}(\zeta))] - \frac{\mathsf{Poly}_\mathsf{Vanish1}(\zeta) + \rho \mathsf{Poly}_\mathsf{Vanish2}(\zeta)}{X^\kappa - 1} \cdot (\zeta^\kappa - 1)$

$= [\mathsf{Poly}_\mathsf{Arr_1'}(\zeta) - (r - \mathsf{Poly}_\mathsf{Arr_1}(\zeta))] + \rho [\mathsf{Poly}_\mathsf{Arr_2'}(\zeta) - (r - \mathsf{Poly}_\mathsf{Arr_2}(\zeta))] - [\mathsf{Poly}_\mathsf{Arr_1'}(\zeta) - (r - \mathsf{Poly}_\mathsf{Arr_1}(\zeta)) + \rho[\mathsf{Poly}_\mathsf{Arr_2'}(\zeta) - (r - \mathsf{Poly}_\mathsf{Arr_2}(\zeta))]]$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly}_\mathsf{Vanish1}(X) + \rho \mathsf{Poly}_\mathsf{Vanish2}(X)$ is divisible by $X^\kappa -1$. This is true if $\mathsf{Poly_{Vanish1}}(\zeta)$ and $\mathsf{Poly_{Vanish2}}(\zeta)$ are vanishing on $\mathcal{H}_\kappa$, i.e. if $\mathsf{Poly}_\mathsf{Arr_1'}(X) - (r - \mathsf{Poly}_\mathsf{Arr_1}(X)) = 0$ and $\mathsf{Poly}_\mathsf{Arr_2'}(X) - (r - \mathsf{Poly}_\mathsf{Arr_2}(X)) = 0$, $X \in \mathcal{H}_\kappa$. This is true if $\mathsf{Arr}_1'[i] - (r - \mathsf{Arr}_1[i]) = 0$ and $\mathsf{Arr}_2'[i] - (r - \mathsf{Arr}_1[i]) = 0$, $\forall 0 \leq i\leq \kappa$, since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$ and $\mathsf{Poly_j}'(\omega^i) = \mathsf{Arr_j}'[i] \space \forall i \in [0, \kappa - 1]$. But this is precisely how the honest prover defines $\mathsf{Arr}_1'$ and $\mathsf{Arr}_2'$, so the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and the transcript will be accepted.

Soundness -#

We prove knowledge soundness in the Algebraic Group Model (AGM). We assume soundness of the product check (it is proven in mult3) and conduct a proof of soundness for the rest of the protocol. To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$, the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, $\mathsf{Poly}_\mathsf{Arr_2'}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, $\mathsf{Poly}_\mathsf{Arr_2'}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Arr}_2 \neq \mathsf{Permute}(\mathsf{Arr}_1)$

Our proof is as follows:

For the second win condition to be fulfilled, there must be some $a \in \mathsf{Arr_2}, a \notin \mathsf{Arr_1}$, or vice versa. Since $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ have different entries, $\prod^{n-1}_{i = 1}(X - \mathsf{Arr_1}[i])$ and $\prod^{n-1}_{i = 1}(X - \mathsf{Arr_2}[i])$ have different factorizations and are thus different polynomials. By the Schwartz-Zippel lemma, there is negligible probability that they are equal at $r$ (thus the product check will fail). Any strategy to increase this probability to greater than negligible means $\mathcal{A}$ must pass in $\mathsf{Arr_j'}$ such that $\mathsf{Arr_j'}[i] \neq r - \mathsf{Arr_j}[i]$ for some index $i$ and $j \in [1, 2]$. But then $\mathsf{Poly}_\mathsf{Vanishj}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, and $\mathsf{Poly}_\mathsf{Arr_2'}(X)$. All commitments $\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr_1'}(\zeta)$, and $\mathsf{Poly}_\mathsf{Arr_2'}(\zeta)$ can each only feasibliy be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2}}{(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge +#

We prove knowledge soundness in the Algebraic Group Model (AGM). We assume soundness of the product check (it is proven in mult3) and conduct a proof of soundness for the rest of the protocol. To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$, the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, $\mathsf{Poly}_\mathsf{Arr_2'}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, $\mathsf{Poly}_\mathsf{Arr_2'}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Arr}_2 \neq \mathsf{Permute}(\mathsf{Arr}_1)$

Our proof is as follows:

For the second win condition to be fulfilled, there must be some $a \in \mathsf{Arr_2}, a \notin \mathsf{Arr_1}$, or vice versa. Since $\mathsf{Arr_1}$ and $\mathsf{Arr_2}$ have different entries, $\prod^{n-1}_{i = 1}(X - \mathsf{Arr_1}[i])$ and $\prod^{n-1}_{i = 1}(X - \mathsf{Arr_2}[i])$ have different factorizations and are thus different polynomials. By the Schwartz-Zippel lemma, there is negligible probability that they are equal at $r$ (thus the product check will fail). Any strategy to increase this probability to greater than negligible means $\mathcal{A}$ must pass in $\mathsf{Arr_j'}$ such that $\mathsf{Arr_j'}[i] \neq r - \mathsf{Arr_j}[i]$ for some index $i$ and $j \in [1, 2]$. But then $\mathsf{Poly}_\mathsf{Vanish_j}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, and $\mathsf{Poly}_\mathsf{Arr_2'}(X)$. All commitments $\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr_1'}(\zeta)$, and $\mathsf{Poly}_\mathsf{Arr_2'}(\zeta)$ can each only feasibly be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2}}{(\zeta^\kappa - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2}}{(\zeta^\kappa - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge #

We prove that the above protocol is zero-knowledge when $\mathsf{PolyCommit}_\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We assume the product check is zero-knowledge (it is proven in mult3), and conduct a proof for the rest of the protocol. We do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ that knows the trapdoor $\tau$, which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ chooses arbitrary values for ${\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$ and ${\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$, then computes $g^{\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$ and $g^{\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$ to write as the commitments $ K_\mathsf{Arr_1}$ and $K_\mathsf{Arr_1}$. $\mathcal{S}$ then generates the random challenge $r$ (by strong Fiat-Shamir). It chooses arbitrary values for ${\mathsf{Poly}_\mathsf{Arr_1'}(\tau)}$ and ${\mathsf{Poly}_\mathsf{Arr_2'}(\tau)}$, then computes $g^{\mathsf{Poly}_\mathsf{Arr_1'}(\tau)}$ and $g^{\mathsf{Poly}_\mathsf{Arr_2'}(\tau)}$ to write as the commitments $ K_\mathsf{Arr_1'}$ and $K_\mathsf{Arr_1'}$. It creates a view of the product check as described in the zero-knowledge proof for mult3.

$\mathcal{S}$ generates the challenge evaluation point $\rho$ (by strong Fiat-Shamir) and computes $Q(\tau)$ using $\rho$ and the values it chose for ${\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr_1'}(\tau)}$, and ${\mathsf{Poly}_\mathsf{Arr_2'}(\tau)}$. $\mathcal{S}$ outputs the commitment $K_Q = g^{Q(\tau)}$.

Now, $\mathcal{S}$ generates the random challenge point $\zeta$ (which we assume is not in $\mathcal{H}_\kappa$; if it is in $\mathcal{H}_\kappa$, $\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\mathcal{S}$ then create fake opening proofs for ${\mathsf{Poly}_\mathsf{Arr_1}(\zeta)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\zeta)}$, ${\mathsf{Poly}_\mathsf{Arr_1'}(\zeta)}$, and ${\mathsf{Poly}_\mathsf{Arr_2'}(\zeta)}$, to arbitrary values. This is done using the knowledge of $\tau$, calculating the respective witness $q(\tau) = \frac{{f(\tau) - f(\zeta)}}{\tau - \zeta}$ for each of the polynomials.

Finally, $\mathcal{S}$ creates a fake opening proof for $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2}}{(\zeta^\kappa - 1)}$. This is done using knowledge of $\tau$ to calculate an accepting witness $q(\tau)$, as above. This means that $Y_\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

\ No newline at end of file diff --git a/docs/gadgets/shuffle2/index.html b/docs/gadgets/shuffle2/index.html index 087060f..2debb45 100644 --- a/docs/gadgets/shuffle2/index.html +++ b/docs/gadgets/shuffle2/index.html @@ -1,18 +1,18 @@ Shuffle2 | Handbook - +
Shuffle2

Shuffle (Type 2) #

Recap of types #

TypeDescriptionRecapThis
shuffle1$\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1)$Array $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ for some undisclosed permutation $\pi$.
shuffle2$\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1 ,\pi)$Array $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ under a disclosed permutation $\pi$.

Relation #

$\mathcal{R}_{\mathtt{shuffle2}} := \left\{ \begin{array}{l} (K_\mathsf{Arr_1},K_\mathsf{Arr2}, K_\pi) \end{array} \middle | \begin{array}{l} \mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \dots, a_{(1,n-1)}],\\ \mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \dots, a_{(2,n-1)}], \\ \mathsf{Arr_\pi} = [\pi(\omega^0), \pi(\omega^1), \pi(\omega^2), \dots, \pi(\omega^{n-1})], \\ \mathsf{Poly}_\mathsf{Arr_1}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr_1}), \\ \mathsf{Poly}_\mathsf{Arr_2}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr_2}), \\ \mathsf{Poly_\pi} = \mathsf{FFT.Interp}(\omega, \mathsf{Arr_\pi}), \\ K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}),\\ K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}),\\K_\pi = \mathsf{KZG.Commit(Poly_{\pi})} \end{array} \right\}$

Intuition -#

The prover ($\mathcal{P}$) holds 2 arrays, $\mathsf{Arr_1 }$ and $\mathsf{Arr_2}$, of $n$ integers from $\mathbb{Z}_q$: $[a_0, a_1, a_2, \dots, a_{n-1}]$. It also holds an array $\mathsf{Arr_\pi}$, which represents the disclosed permutation $\pi$. It will produce a succinct (independent of $n$) proof that $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ under the disclosed permutation $\pi$. The prover will encode the three arrays into polynomials, $\mathsf{Poly}_\mathsf{Arr_1}$, $\mathsf{Poly}_\mathsf{Arr_2}$, and $\mathsf{Poly_\pi}$ (using evaluation points on the domain $\mathcal{H}_\kappa$) and commit to them as $K_\mathsf{Arr_1}$, $K_\mathsf{Arr_2}$, and $K_\pi$. The verifier ($\mathcal{V}$) cannot check any array directly ($\mathsf{Arr_1 }$ and $\mathsf{Arr_2}$ may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\mathsf{Arr_1}$, $K_\mathsf{Arr_2}$ and $K_\pi$.

The idea behind this check is that if $(\mathsf{Arr_\pi}[i], \mathsf{Arr_2}[i]) = (i, \mathsf{Arr_1}[i])$ for all $0 \leq i \leq n-1$, then $\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1 ,\pi)$. To gain some intuition on why this is true, pair up tuples from the left and right hand sides of the equation by matching the first entries. Then, if each pair is equal, it means that $\mathsf{Arr_2}[i] = \mathsf{Arr_1}[\mathsf{Arr_\pi}[i]]$ for $0 \leq i \leq n-1$. In other words, $\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1 ,\pi)$.

To check that $(\mathsf{Arr_\pi}[i], \mathsf{Arr_2}[i]) = (i, \mathsf{Arr_1}[i])$ for all $0 \leq j \leq n-1$, we use a similar trick to shuffle1. The prover constructs two arrays: $\mathsf{Arr_1'} = \{ r - s\cdot i - \mathsf{Arr_1}[i]\}_{i \in [0, n-1]}$ and $\mathsf{Arr_2'} = \{ r - s\cdot\mathsf{Arr_\pi}[i] - \mathsf{Arr_2}[i]\}_{i \in [0, n-1]}$ for random field elements $r, s$. Then, a product check is conducted on the two arrays. One way to understand why this works is to think of it as creating two auxilary polynomials, ${\mathsf{Poly}}_\mathsf{Arr_1'}$ and ${\mathsf{Poly}}_\mathsf{Arr_2'}$. Here, $\mathsf{Poly}_\mathsf{Arr_1'}(X) = \prod^{n-1}_{i = 1}(X - Y\cdot i - \mathsf{Arr_1}[i])$ and $\mathsf{Poly}_\mathsf{Arr_2'}(X) = \prod^{n-1}_{i = 1}(X - Y\cdot \mathsf{Arr_\pi}[i] - \mathsf{Arr_2}[i])$. If ${\mathsf{Poly}}_\mathsf{Arr_1'}$ = $\mathsf{Poly}_\mathsf{Arr_2'}$, then they have the same factorization. This means that $\mathsf{Arr}_1'$ and $\mathsf{Arr}_2'$ must contain the same elements (in possibly different orders). By the same intuition of matching first entries as above (in this case, we are pairing up factors where $i$ in $\mathsf{Poly}_\mathsf{Arr_1'}(X)$ equals $\mathsf{Arr_\pi}[i]$ in $\mathsf{Poly}_\mathsf{Arr_2'}(X)$) this shows that $\mathsf{Arr}_2$ is a permutation of $\mathsf{Arr}_1$ under $\pi$. To check the equality of the two auxilary polynomials, random challenge values $r$ and $s$ are generated and the products are checked at that point. If they are equal at that point then (with overwhelming probabiltiy) the polynomials are equal.

In addition to demontrasting the equality of the product of $\mathsf{Arr_1}'$ and $\mathsf{Arr_2}'$, it must also be shown that these two arrays are defined correctly in terms of the original arrays. In other words, it must be shown that $\mathsf{Arr_1}'[i]= (i, \mathsf{Arr_1}[i])$ and $\mathsf{Arr_2}'[i]= (\mathsf{Arr_\pi}[i], \mathsf{Arr_2}[i])$. Once this, in addition to the product check, has been done, it has been shown that $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ under the disclosed permutation $\pi$.

Protocol Details +#

The prover ($\mathcal{P}$) holds 2 arrays, $\mathsf{Arr_1 }$ and $\mathsf{Arr_2}$, of $n$ integers from $\mathbb{Z}_q$: $[a_0, a_1, a_2, \dots, a_{n-1}]$. It also holds an array $\mathsf{Arr_\pi}$, which represents the disclosed permutation $\pi$. It will produce a succinct (independent of $n$) proof that $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ under the disclosed permutation $\pi$. The prover will encode the three arrays into polynomials, $\mathsf{Poly}_\mathsf{Arr_1}$, $\mathsf{Poly}_\mathsf{Arr_2}$, and $\mathsf{Poly_\pi}$ (using evaluation points on the domain $\mathcal{H}_\kappa$) and commit to them as $K_\mathsf{Arr_1}$, $K_\mathsf{Arr_2}$, and $K_\pi$. The verifier ($\mathcal{V}$) cannot check any array directly ($\mathsf{Arr_1 }$ and $\mathsf{Arr_2}$ may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\mathsf{Arr_1}$, $K_\mathsf{Arr_2}$ and $K_\pi$.

The idea behind this check is that if $(\mathsf{Arr_\pi}[i], \mathsf{Arr_2}[i]) = (i, \mathsf{Arr_1}[i])$ for all $0 \leq i \leq n-1$, then $\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1 ,\pi)$. To gain some intuition on why this is true, pair up tuples from the left and right hand sides of the equation by matching the first entries. Then, if each pair is equal, it means that $\mathsf{Arr_2}[i] = \mathsf{Arr_1}[\mathsf{Arr_\pi}[i]]$ for $0 \leq i \leq n-1$. In other words, $\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1 ,\pi)$.

To check that $(\mathsf{Arr_\pi}[i], \mathsf{Arr_2}[i]) = (i, \mathsf{Arr_1}[i])$ for all $0 \leq j \leq n-1$, we use a similar trick to shuffle1. The prover constructs two arrays: $\mathsf{Arr_1'} = \{ r - s\cdot i - \mathsf{Arr_1}[i]\}_{i \in [0, n-1]}$ and $\mathsf{Arr_2'} = \{ r - s\cdot\mathsf{Arr_\pi}[i] - \mathsf{Arr_2}[i]\}_{i \in [0, n-1]}$ for random field elements $r, s$. Then, a product check is conducted on the two arrays. One way to understand why this works is to think of it as creating two auxiliary polynomials, ${\mathsf{Poly}}_\mathsf{Arr_1'}$ and ${\mathsf{Poly}}_\mathsf{Arr_2'}$. Here, $\mathsf{Poly}_\mathsf{Arr_1'}(X) = \prod^{n-1}_{i = 1}(X - Y\cdot i - \mathsf{Arr_1}[i])$ and $\mathsf{Poly}_\mathsf{Arr_2'}(X) = \prod^{n-1}_{i = 1}(X - Y\cdot \mathsf{Arr_\pi}[i] - \mathsf{Arr_2}[i])$. If ${\mathsf{Poly}}_\mathsf{Arr_1'}$ = $\mathsf{Poly}_\mathsf{Arr_2'}$, then they have the same factorization. This means that $\mathsf{Arr}_1'$ and $\mathsf{Arr}_2'$ must contain the same elements (in possibly different orders). By the same intuition of matching first entries as above (in this case, we are pairing up factors where $i$ in $\mathsf{Poly}_\mathsf{Arr_1'}(X)$ equals $\mathsf{Arr_\pi}[i]$ in $\mathsf{Poly}_\mathsf{Arr_2'}(X)$) this shows that $\mathsf{Arr}_2$ is a permutation of $\mathsf{Arr}_1$ under $\pi$. To check the equality of the two auxiliary polynomials, random challenge values $r$ and $s$ are generated and the products are checked at that point. If they are equal at that point then (with overwhelming probability) the polynomials are equal.

In addition to demonstrating the equality of the product of $\mathsf{Arr_1}'$ and $\mathsf{Arr_2}'$, it must also be shown that these two arrays are defined correctly in terms of the original arrays. In other words, it must be shown that $\mathsf{Arr_1}'[i]= (i, \mathsf{Arr_1}[i])$ and $\mathsf{Arr_2}'[i]= (\mathsf{Arr_\pi}[i], \mathsf{Arr_2}[i])$. Once this, in addition to the product check, has been done, it has been shown that $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ under the disclosed permutation $\pi$.

Protocol Details #

Array Level #

  • $\mathcal{P}$ holds an array $\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \in \mathbb{Z}_q$)
  • $\mathcal{P}$ holds an array $\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \in \mathbb{Z}_q$​)
  • $\mathcal{P}$ holds an array $\mathsf{Arr_\pi} = [\pi(\omega^0), \pi(\omega^1), \pi(\omega^2), \dots, \pi(\omega^{n-1})]$ of $n$ integers ($a_{(2,i)} \in \mathbb{Z}_q$)
  • $\mathcal{P}$ generates the random challenge $r, s$ and computes $\mathsf{Arr_1}'$ as follows:
    • $\mathsf{Arr_1}'[i]= r - s\cdot i - \mathsf{Arr_1}[i]$
  • $\mathcal{P}$ computes $\mathsf{Arr_2}'$ as follows:
    • $\mathsf{Arr_2}'[i]= r - s\cdot \mathsf{Arr_\pi}[i] - \mathsf{Arr_2}[i]$

Polynomial Level #

We assume that $\mathsf{Arr_1}$, $\mathsf{Arr_2}$, $\mathsf{Arr_\pi}[i]$, $\mathsf{Arr_1'}$, and $\mathsf{Arr_2'}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\mathcal{H}_\kappa$) are chosen as the multiplicative group of order $\kappa$ with generator $\omega\in\mathbb{G}_\kappa$ (see Background for more). In short, $\omega^0$ is the first element and $\omega^{\kappa-1}$ is the last element of $\mathcal{H}_\kappa$. If $\kappa$ is larger than the length of the arrays, the arrays can be padded with elements all of value 1 (or any other value, as long as it is the same for both arrays).

Recall the two components we want to prove. First, the product check:

$\prod^{n-1}_{i = 1}(r - s\cdot i - \mathsf{Arr_1}[i]) = \prod^{n-1}_{i = 1}(r - s\cdot \mathsf{Arr_\pi}[i] - \mathsf{Arr_2}[i])$

As well as the two constraints:

  1. $\mathsf{Arr_1}'[i]= r - s\cdot i - \mathsf{Arr_1}[i]$
  2. $\mathsf{Arr_2}'[i]= r - s\cdot \mathsf{Arr_\pi}[i] - \mathsf{Arr_2}[i]$

The first component is done as a mult3 product check, and we write the second component in polynomial form. From this point on we focus on the polynomial details of the second component.

  1. For all $X$ from $\omega^0$ to $\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Arr_1'}(X) = r - s\cdot X - \mathsf{Poly}_\mathsf{Arr_1}(X)$
  2. For all $X$ from $\omega^0$ to $\omega^{\kappa-1}$: $\mathsf{Poly}_\mathsf{Arr_2'}(X) = r - s\cdot \mathsf{Poly_\pi}(X) - \mathsf{Poly}_\mathsf{Arr_2}(X)$

We adjust each of these constraints to show an equality with 0 and label them:

  1. $\mathsf{Poly}_\mathsf{Vanish1}(X)= \mathsf{Poly}_\mathsf{Arr_1'}(X) - (r - s\cdot X - \mathsf{Poly}_\mathsf{Arr_1}(X)) = 0$
  2. $\mathsf{Poly}_\mathsf{Vanish2}(X)= \mathsf{Poly}_\mathsf{Arr_2'}(X) - (r - s\cdot \mathsf{Poly_\pi}(X) - \mathsf{Poly}_\mathsf{Arr_2}(X)) = 0$

This equation is true for every value of $X \in \mathcal{H}_\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\kappa - 1$, which is a minimal vanishing polynomial for $\mathcal{H}_\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\mathsf{Poly}_\mathsf{Vanish}(X)$ must be vanishing on $\mathcal{H}_\kappa$ too. Specifically, the prover computes:

  1. $Q_1(X) = \frac{\mathsf{Poly}_\mathsf{Vanish1}(X)}{X^\kappa - 1}$
  2. $Q_2(X) = \frac{\mathsf{Poly}_\mathsf{Vanish2}(X)}{X^\kappa - 1}$

We can replace polynomials $Q_1(X)$ and $Q_2(X)$ with a single polynomial $Q(X)$. We can do this because both constraints have the same format: $\mathsf{Poly}_\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with both $\mathsf{Poly}_\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if both are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\rho$ selected after the commitments to the earlier polynomials are fixed.

$Q(X) = \frac{\mathsf{Poly}_\mathsf{Vanish1}(X) + \mathsf{Poly}_\mathsf{Vanish2}(X) \rho}{X^n - 1}$

By rearranging, we can get $\mathsf{Poly}_\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\mathcal{H}_\kappa$ and outside of it):

$\mathsf{Poly}_\mathsf{Zero}(X)=\mathsf{Poly}_\mathsf{Vanish1}(X) + \rho \mathsf{Poly}_\mathsf{Vanish2}(X) - Q(X)\cdot (X^n - 1)=0$

Ultimately the shuffle1 argument will satisfy the following constraints at the Commitment Level:

  1. Show $Q(X)$ exists (as a polynomial that evenly divides the divisor)
  2. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is correctly constructed from $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly_\pi(X)}$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, $\mathsf{Poly}_\mathsf{Arr_2'}(X)$
  3. Show $\mathsf{Poly}_\mathsf{Zero}(X)$ is the zero polynomial

In addition, it will show that $\prod^{n-1}_{i = 1}(X - Y\cdot i - \mathsf{Arr_1}[i]) = \prod^{n-1}_{i = 1}(X - Y\cdot \mathsf{Arr_\pi}[i] - \mathsf{Arr_2}[i])$ using a mult3 product check.

Commitment Level -#

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will create a transcript for the product check, as decribed in mult3. Below, we give details specific to the second component, verifing the two constraints.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}(X))$
  • $K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}(X))$​
  • $K_\pi = \mathsf{KZG.Commit(Poly_\pi}(X))$

The prover will generate two random challenge evaluation points (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call these points $r$ and $s$. It will use these points to define the arrays $\mathsf{Arr_1'} = \{ r - s\cdot i - \mathsf{Arr_1}[i]\}_{i \in [0, n-1]}$ and $\mathsf{Arr_2'} = \{ r - s\cdot\mathsf{Arr_\pi}[i] - \mathsf{Arr_2}[i]\}_{i \in [0, n-1]}$ and run the product check. It will write the product check into the transcript. However, here we focus only on what is relevant to the second component, the points $r$ and $s$ and the following polynomials, which are also written to the transcript:

  • $r$
  • $K_\mathsf{Arr_1'}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1'}(X))$
  • $K_\mathsf{Arr_2'}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2'}(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:

  • $\rho$
  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$
  • $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2},\zeta)$​
  • $\mathsf{Poly_\pi}(\zeta) = \mathsf{KZG.Open}(K_\pi, \zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_1'}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1'},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_2'}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2'},\zeta)$
  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish1}= \mathsf{Poly}_\mathsf{Arr_1'}(\zeta) - (r - s\cdot \zeta - \mathsf{Poly}_\mathsf{Arr_1}(\zeta))$
  • $Y_\mathsf{Vanish2}= \mathsf{Poly}_\mathsf{Arr_2'}(\zeta) - (r - s\cdot \mathsf{Poly_\pi}(\zeta) - \mathsf{Poly}_\mathsf{Arr_2}(\zeta))$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} - Q(\zeta)\cdot (\zeta^n - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Implementations +#

The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.

The prover will create a transcript for the product check, as described in mult3. Below, we give details specific to the second component, verifying the two constraints.

The prover will write the following commitments to the transcript:

  • $K_\mathsf{Arr_1}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1}(X))$
  • $K_\mathsf{Arr_2}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2}(X))$​
  • $K_\pi = \mathsf{KZG.Commit(Poly_\pi}(X))$

The prover will generate two random challenge evaluation points (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call these points $r$ and $s$. It will use these points to define the arrays $\mathsf{Arr_1'} = \{ r - s\cdot i - \mathsf{Arr_1}[i]\}_{i \in [0, n-1]}$ and $\mathsf{Arr_2'} = \{ r - s\cdot\mathsf{Arr_\pi}[i] - \mathsf{Arr_2}[i]\}_{i \in [0, n-1]}$ and run the product check. It will write the product check into the transcript. However, here we focus only on what is relevant to the second component, the points $r$ and $s$ and the following polynomials, which are also written to the transcript:

  • $r$
  • $K_\mathsf{Arr_1'}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_1'}(X))$
  • $K_\mathsf{Arr_2'}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr_2'}(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\mathcal{H}_\kappa$. Call this point $\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:

  • $\rho$
  • $K_Q=\mathsf{KZG.Commit}(Q(X))$

The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\mathcal{H}_\kappa$. Call this point $\zeta$. The prover will write the point and opening proofs to the transcript:

  • $\zeta$
  • $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2},\zeta)$​
  • $\mathsf{Poly_\pi}(\zeta) = \mathsf{KZG.Open}(K_\pi, \zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_1'}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_1'},\zeta)$
  • $\mathsf{Poly}_\mathsf{Arr_2'}(\zeta)=\mathsf{KZG.Open}(K_\mathsf{Arr_2'},\zeta)$
  • $Q(\zeta)=\mathsf{KZG.Open}(K_Q,\zeta)$

To check the proof, the verifier uses the transcript to construct the value $Y_\mathsf{Zero}$ as follows:

  • $Y_\mathsf{Vanish1}= \mathsf{Poly}_\mathsf{Arr_1'}(\zeta) - (r - s\cdot \zeta - \mathsf{Poly}_\mathsf{Arr_1}(\zeta))$
  • $Y_\mathsf{Vanish2}= \mathsf{Poly}_\mathsf{Arr_2'}(\zeta) - (r - s\cdot \mathsf{Poly_\pi}(\zeta) - \mathsf{Poly}_\mathsf{Arr_2}(\zeta))$
  • $Y_\mathsf{Zero}=Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} - Q(\zeta)\cdot (\zeta^n - 1)$

Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\zeta$) :

  • $Y_\mathsf{Zero}\overset{?}{=}0$

Implementations #

Security Proof #

Completeness #

We assume completeness of the product check (it is proven in mult3) and conduct a proof of completeness for the rest of the protocol.

If $Y_\mathsf{Zero}$ is zero, then $\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ such that $\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1)$, can follow the steps outlined in the above protocol and the resulting $Y_\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\mathsf{Zero}$

$= Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2} - Q(\zeta)\cdot (\zeta^\kappa - 1)$

$= [\mathsf{Poly}_\mathsf{Arr_1'}(\zeta) - (r - s \cdot \zeta - \mathsf{Poly}_\mathsf{Arr_1}(\zeta))] + \rho [\mathsf{Poly}_\mathsf{Arr_2'}(\zeta) - (r - s\cdot\mathsf{Poly_{\pi}(\zeta)} - \mathsf{Poly}_\mathsf{Arr_2}(\zeta))] - Q(\zeta) \cdot (\zeta^\kappa - 1)$

$= [\mathsf{Poly}_\mathsf{Arr_1'}(\zeta) - (r - s\cdot\zeta - \mathsf{Poly}_\mathsf{Arr_1}(\zeta))] + \rho [\mathsf{Poly}_\mathsf{Arr_2'}(\zeta) - (r - s\cdot \mathsf{Poly_\pi}(\zeta) - \mathsf{Poly}_\mathsf{Arr_2}(\zeta))] - \frac{\mathsf{Poly}_\mathsf{Vanish1}(\zeta) + \rho \mathsf{Poly}_\mathsf{Vanish2}(\zeta)}{X^\kappa - 1} \cdot (\zeta^\kappa - 1)$

$= [\mathsf{Poly}_\mathsf{Arr_1'}(\zeta) - (r - s\cdot\zeta - \mathsf{Poly}_\mathsf{Arr_1}(\zeta))] + \rho [\mathsf{Poly}_\mathsf{Arr_2'}(\zeta) - (r - s\cdot \mathsf{Poly_\pi}(\zeta) - \mathsf{Poly}_\mathsf{Arr_2}(\zeta))] \newline - [\mathsf{Poly}_\mathsf{Arr_1'}(\zeta) - (r - s\cdot\zeta - \mathsf{Poly}_\mathsf{Arr_1}(\zeta)) + \rho[\mathsf{Poly}_\mathsf{Arr_2'}(\zeta) - (r - s\cdot\mathsf{Poly_\pi}(\zeta) - \mathsf{Poly}_\mathsf{Arr_2}(\zeta))]]$

$= 0$

Where the third equality relies on the fact that $\mathsf{Poly}_\mathsf{Vanish1}(X) + \rho \mathsf{Poly}_\mathsf{Vanish2}(X)$ is divisible by $X^\kappa -1$. This is true if $\mathsf{Poly_{Vanish1}}(\zeta)$ and $\mathsf{Poly_{Vanish2}}(\zeta)$ are vanishing on $\mathcal{H}_\kappa$, i.e. if $\mathsf{Poly}_\mathsf{Arr_1'}(X) - (r - s\cdot\zeta - \mathsf{Poly}_\mathsf{Arr_1}(X)) = 0$ and $\mathsf{Poly}_\mathsf{Arr_2'}(X) - (r - s\cdot \mathsf{Poly_\pi}(\zeta) - \mathsf{Poly}_\mathsf{Arr_2}(X)) = 0$, $X \in \mathcal{H}_\kappa$. This is true if $\mathsf{Arr}_1'[i] - (r - s\cdot i - \mathsf{Arr}_1[i]) = 0$ and $\mathsf{Arr}_2'[i] - (r - s \cdot \mathsf{Arr}_\pi(i) - \mathsf{Arr}_1[i]) = 0$, $\forall 0 \leq i\leq \kappa$, since $\mathsf{Poly_j}(\omega^i) = \mathsf{Arr_j}[i] \space \forall i \in [0, \kappa - 1]$, $\mathsf{Poly_j}'(\omega^i) = \mathsf{Arr_j}'[i] \space \forall i \in [0, \kappa - 1]$, and since $\mathsf{Poly_\pi}(\omega^i) = \mathsf{Arr_\pi}[i] \space \forall i \in [0, \kappa - 1]$ . But this is precisely how the honest prover defines $\mathsf{Arr}_1'$ and $\mathsf{Arr}_2'$, so the $Y_\mathsf{Zero}$ it creates by following the protocol is zero, and the transcript will be accepted.

Soundness -#

We prove knowledge soundness in the Algebraic Group Model (AGM). We assume soundness of the product check (it is proven in mult3) and conduct a proof of soundness for the rest of the protocol. To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly_\pi}$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, $\mathsf{Poly}_\mathsf{Arr_2'}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly_\pi}$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, $\mathsf{Poly}_\mathsf{Arr_2'}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Arr}_2 \neq \mathsf{Permute}(\mathsf{Arr}_1 ,\pi)$

Our proof is as follows:

For the second win condition to be fulfilled, it must be that $(\mathsf{Arr_\pi}[i], \mathsf{Arr_2}[i]) \neq (i, \mathsf{Arr_1}[i])$ for some $i \in [0, n-1]$. But then, $\mathsf{Arr_1'}$ and $\mathsf{Arr_2'}$ contain differing element. This means that $\mathsf{Poly}_\mathsf{Arr_1'}(X) = \prod^{n-1}_{i = 1}(X - Y\cdot i - \mathsf{Arr_1}[i])$ and $\mathsf{Poly}_\mathsf{Arr_2'}(X) = \prod^{n-1}_{i = 1}(X - Y\cdot \mathsf{Arr_\pi}[i] - \mathsf{Arr_2}[i])$ and different polynomials, and thus by the Schwartz-Zippel lemma, there is negligible probability that they are equal at $X=r$ and $Y=2$ for the random challenge $r, s$ (thus the product check will fail). Any strategy to increase this probability to greater than negligible means $\mathcal{A}$ must pass in $\mathsf{Arr_j'}$ for $j = 1$ or $j = 2$ that is not defined according to the its corresponding constraint. But then $\mathsf{Poly}_\mathsf{Vanishj}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly_\pi}$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, and $\mathsf{Poly}_\mathsf{Arr_2'}(X)$. All commitments $\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)$, $\mathsf{Poly_\pi(\zeta)}$, $\mathsf{Poly}_\mathsf{Arr_1'}(\zeta)$, and $\mathsf{Poly}_\mathsf{Arr_2'}(\zeta)$ can only feasibliy be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2}}{(\zeta^n - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2}}{(\zeta^n - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge -#

We prove that the above protocol is zero-knowledge when $\mathsf{PolyCommit}_\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We assume the product check is zero-knowledge (it is proven in mult3), and conduct a proof for the rest of the protocol. We do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ that knows the trapdoor $\tau$, which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ chooses arbitrary values for ${\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$, and $\mathsf{Poly_\pi}(\tau)$, then computes $g^{\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, $g^{\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$, $g^{\mathsf{Poly_\pi}(\tau)}$ to write as the commitments $ K_\mathsf{Arr_1}$, $K_\mathsf{Arr_1}$, $K_\pi$. $\mathcal{S}$ then generates $r$ and $s$ as values for the ranom challenge (by strong Fiat-Shamir). It then chooses arbitrary values for ${\mathsf{Poly}_\mathsf{Arr_1'}(\tau)}$ and ${\mathsf{Poly}_\mathsf{Arr_2'}(\tau)}$, computes $g^{\mathsf{Poly}_\mathsf{Arr_1'}(\tau)}$ and $g^{\mathsf{Poly}_\mathsf{Arr_2'}(\tau)}$ to write as the commitments $ K_\mathsf{Arr_1'}$ and $K_\mathsf{Arr_1'}$. It creates a view of the product check as described in the zero-knowledge proof for mult3.

$\mathcal{S}$ generates the challenge evaluation point $\rho$ (by strong Fiat-Shamir) and computes $Q(\tau)$ using $\rho$ and the values it chose for ${\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$, $\mathsf{Poly_\pi}(\tau)$, ${\mathsf{Poly}_\mathsf{Arr_1'}(\tau)}$, and ${\mathsf{Poly}_\mathsf{Arr_2'}(\tau)}$. $\mathcal{S}$ outputs the commitment $K_Q = g^{Q(\tau)}$.

Now, $\mathcal{S}$ generates the second random challenge, $\zeta$ (which we assume is not in $\mathcal{H}_\kappa$; if it is in $\mathcal{H}_\kappa$, $\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\mathcal{S}$ then create fake opening proofs for ${\mathsf{Poly}_\mathsf{Arr_1}(\zeta)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\zeta)}$, $\mathsf{Poly_\pi}(\zeta)$, ${\mathsf{Poly}_\mathsf{Arr_1'}(\zeta)}$, and ${\mathsf{Poly}_\mathsf{Arr_2'}(\zeta)}$, to arbitrary values. This is done using the knowledge of $\tau$, calculating the respective witness $q(\tau) = \frac{{f(\tau) - f(\zeta)}}{\tau - \zeta}$ for each of the polynomials.

Finally, $\mathcal{S}$ creates a fake opening proof for $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2}}{(\zeta^n - 1)}$. This is done using knowledge of $\tau$ to calculate an accepting witness $q(\tau)$, as above. This means that $Y_\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

\ No newline at end of file +#

We prove knowledge soundness in the Algebraic Group Model (AGM). We assume soundness of the product check (it is proven in mult3) and conduct a proof of soundness for the rest of the protocol. To do so, we must prove that there exists an efficient extractor $\mathcal{E}$ such that for any algebraic adversary $\mathcal{A}$ the probability of $\mathcal{A}$ winning the following game is $\mathsf{negl}(\lambda)$.

  1. Given $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$ $\mathcal{A}$ outputs commitments to $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly_\pi}$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, $\mathsf{Poly}_\mathsf{Arr_2'}(X)$, $Q(X)$

  2. $\mathcal{E}$, given access to $\mathcal{A}$’s outputs from the previous step, outputs $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly_\pi}$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, $\mathsf{Poly}_\mathsf{Arr_2'}(X)$, $Q(X)$

  3. $\mathcal{A}$ plays the part of the prover in showing that $Y_{\mathsf{Zero}}$ is zero at a random challenge $\zeta$

  4. $\mathcal{A}$ wins if:

    i) $\mathcal{V}$ accepts at the end of the protocol

    ii) $\mathsf{Arr}_2 \neq \mathsf{Permute}(\mathsf{Arr}_1 ,\pi)$

Our proof is as follows:

For the second win condition to be fulfilled, it must be that $(\mathsf{Arr_\pi}[i], \mathsf{Arr_2}[i]) \neq (i, \mathsf{Arr_1}[i])$ for some $i \in [0, n-1]$. But then, $\mathsf{Arr_1'}$ and $\mathsf{Arr_2'}$ contain differing element. This means that $\mathsf{Poly}_\mathsf{Arr_1'}(X) = \prod^{n-1}_{i = 1}(X - Y\cdot i - \mathsf{Arr_1}[i])$ and $\mathsf{Poly}_\mathsf{Arr_2'}(X) = \prod^{n-1}_{i = 1}(X - Y\cdot \mathsf{Arr_\pi}[i] - \mathsf{Arr_2}[i])$ and different polynomials, and thus by the Schwartz-Zippel lemma, there is negligible probability that they are equal at $X=r$ and $Y=2$ for the random challenge $r, s$ (thus the product check will fail). Any strategy to increase this probability to greater than negligible means $\mathcal{A}$ must pass in $\mathsf{Arr_j'}$ for $j = 1$ or $j = 2$ that is not defined according to the its corresponding constraint. But then $\mathsf{Poly}_\mathsf{Vanish_j}(X)$ is not vanishing on $\mathcal{H}_\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\tau)}$ without solving the t-SDH. Thus, $\mathcal{A}$ chooses an arbitrary value for $Q(\tau)$ and writes $K_Q = g^{Q(\tau)}$ to the transcript. Before this, it also writes commitments to $\mathsf{Poly}_\mathsf{Arr_1}(X)$, $\mathsf{Poly}_\mathsf{Arr_2}(X)$, $\mathsf{Poly_\pi}$, $\mathsf{Poly}_\mathsf{Arr_1'}(X)$, and $\mathsf{Poly}_\mathsf{Arr_2'}(X)$. All commitments $\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\tau, g^{\tau^2}, \dots,g^{\tau^{n-1}}]$. $\mathcal{E}$ is given these coefficients (since $\mathcal{A}$ is an algebraic adversary) so $\mathcal{E}$ can output the original polynomials.

$\mathcal{A}$ then obtains the random challenge $\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\mathsf{Poly}_\mathsf{Arr_1}(\zeta)$, $\mathsf{Poly}_\mathsf{Arr_2}(\zeta)$, $\mathsf{Poly_\pi(\zeta)}$, $\mathsf{Poly}_\mathsf{Arr_1'}(\zeta)$, and $\mathsf{Poly}_\mathsf{Arr_2'}(\zeta)$ can only feasibly be opened to one value. For $\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\zeta)$ opens to $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2}}{(\zeta^n - 1)}$. This means being able to produce $g^{q(\tau)}$ where $q(\tau) = \frac{Q(\tau) - Q(\zeta)}{\tau - \zeta}$ and $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2}}{(\zeta^n - 1)}$. Since $Q(\tau)$ and $Q(\zeta)$ are known, this implies knowing $g^{\frac{1}{\tau - \zeta}}$. Thus $\mathcal{A}$ would have found $\langle\zeta,g^{\frac{1}{\tau - \zeta}}\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\mathcal{A}$’s probability of success is negligible.

Zero-Knowledge +#

We prove that the above protocol is zero-knowledge when $\mathsf{PolyCommit}_\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We assume the product check is zero-knowledge (it is proven in mult3), and conduct a proof for the rest of the protocol. We do so by constructing a probabilistic polynomial time simulator $\mathcal{S}$ that knows the trapdoor $\tau$, which, for every (possibly malicious) verifier $\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.

The simulator $\mathcal{S}$ chooses arbitrary values for ${\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$, and $\mathsf{Poly_\pi}(\tau)$, then computes $g^{\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, $g^{\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$, $g^{\mathsf{Poly_\pi}(\tau)}$ to write as the commitments $ K_\mathsf{Arr_1}$, $K_\mathsf{Arr_1}$, $K_\pi$. $\mathcal{S}$ then generates $r$ and $s$ as values for the random challenge (by strong Fiat-Shamir). It then chooses arbitrary values for ${\mathsf{Poly}_\mathsf{Arr_1'}(\tau)}$ and ${\mathsf{Poly}_\mathsf{Arr_2'}(\tau)}$, computes $g^{\mathsf{Poly}_\mathsf{Arr_1'}(\tau)}$ and $g^{\mathsf{Poly}_\mathsf{Arr_2'}(\tau)}$ to write as the commitments $ K_\mathsf{Arr_1'}$ and $K_\mathsf{Arr_1'}$. It creates a view of the product check as described in the zero-knowledge proof for mult3.

$\mathcal{S}$ generates the challenge evaluation point $\rho$ (by strong Fiat-Shamir) and computes $Q(\tau)$ using $\rho$ and the values it chose for ${\mathsf{Poly}_\mathsf{Arr_1}(\tau)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\tau)}$, $\mathsf{Poly_\pi}(\tau)$, ${\mathsf{Poly}_\mathsf{Arr_1'}(\tau)}$, and ${\mathsf{Poly}_\mathsf{Arr_2'}(\tau)}$. $\mathcal{S}$ outputs the commitment $K_Q = g^{Q(\tau)}$.

Now, $\mathcal{S}$ generates the second random challenge, $\zeta$ (which we assume is not in $\mathcal{H}_\kappa$; if it is in $\mathcal{H}_\kappa$, $\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\mathcal{S}$ then create fake opening proofs for ${\mathsf{Poly}_\mathsf{Arr_1}(\zeta)}$, ${\mathsf{Poly}_\mathsf{Arr_2}(\zeta)}$, $\mathsf{Poly_\pi}(\zeta)$, ${\mathsf{Poly}_\mathsf{Arr_1'}(\zeta)}$, and ${\mathsf{Poly}_\mathsf{Arr_2'}(\zeta)}$, to arbitrary values. This is done using the knowledge of $\tau$, calculating the respective witness $q(\tau) = \frac{{f(\tau) - f(\zeta)}}{\tau - \zeta}$ for each of the polynomials.

Finally, $\mathcal{S}$ creates a fake opening proof for $Q(\zeta) = \frac{Y_\mathsf{Vanish1} + \rho Y_\mathsf{Vanish2}}{(\zeta^n - 1)}$. This is done using knowledge of $\tau$ to calculate an accepting witness $q(\tau)$, as above. This means that $Y_\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\mathsf{PolyCommit}_\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\hat{\phi}(x)}$.

\ No newline at end of file diff --git a/docs/gadgets/zero1/index.html b/docs/gadgets/zero1/index.html index 14a9460..34b2f4c 100644 --- a/docs/gadgets/zero1/index.html +++ b/docs/gadgets/zero1/index.html @@ -1,5 +1,5 @@ Zero1 | Handbook - +
Zero1

Zero (Type 1) diff --git a/docs/gadgets/zero2/index.html b/docs/gadgets/zero2/index.html index d40e11f..78ff6f2 100644 --- a/docs/gadgets/zero2/index.html +++ b/docs/gadgets/zero2/index.html @@ -1,5 +1,5 @@ Zero2 | Handbook - +
Zero2

Zero (Type 2) diff --git a/docs/index.html b/docs/index.html index a49c0fb..079713f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,5 +1,5 @@ Docs | Handbook - +
Docs
\ No newline at end of file diff --git a/en.search-data.min.095fef5514cefcc621486d2d6eb615cc3f20ff8f3d6f8d5568a0c4e9a152148e.json b/en.search-data.min.095fef5514cefcc621486d2d6eb615cc3f20ff8f3d6f8d5568a0c4e9a152148e.json new file mode 100644 index 0000000..80c720e --- /dev/null +++ b/en.search-data.min.095fef5514cefcc621486d2d6eb615cc3f20ff8f3d6f8d5568a0c4e9a152148e.json @@ -0,0 +1 @@ +[{"id":0,"href":"/docs/background/","title":"Background","section":"Docs","content":"Select a background topic from the menu.\n"},{"id":1,"href":"/docs/gadgets/","title":"Gadgets","section":"Docs","content":"Select a gadget from the menu.\n"},{"id":2,"href":"/docs/gadgets/add1/","title":"Add1","section":"Gadgets","content":" Addition (Type 1) # Recap of types # Type Description Recap This add1 $\\mathsf{Arr}_3=\\mathsf{Arr}_1 + \\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the element-wise addition of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. ✅ add2 $\\mathsf{Sum}_\\mathsf{Arr}=\\sum_{i = 0}^{n-1} \\mathsf{Arr}[i]$ $\\mathsf{Sum}_\\mathsf{Arr}$ is the disclosed sum of all the elements in $\\mathsf{Arr}$. add3 $\\sum_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\sum_{i = 0}^{n-1} \\mathsf{Arr}_2[i]$ $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ have the same undisclosed sum. Relation # $ \\mathcal{R}_{\\mathtt{add1}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr_2},K_\\mathsf{Arr_3}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i], 0\\leq i \\leq n, \\\\ \\mathsf{Poly}_\\mathsf{Arr_j}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_j}), 1\\leq j \\leq 3, \\\\ K_\\mathsf{Arr_j}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_j}), 1\\leq j \\leq 3, \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds two arrays $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that $\\mathsf{Arr_3}$ is the element-wise sum of all the elements in the array: $\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i]$. The prover will encode the three arrays into three polynomials: $\\mathsf{Poly}_\\mathsf{Arr_1}$, $\\mathsf{Poly}_\\mathsf{Arr_2}$, and $\\mathsf{Poly}_\\mathsf{Arr_3}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$). It will commit to each polynomial: $K_\\mathsf{Arr_1}$,$K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$. The verifier ($\\mathcal{V}$) cannot check any of the $\\mathsf{Arr_i}$ or $\\mathsf{Poly}_\\mathsf{Arr_i}$ values directly (they may contain secret information, and even if they do not, they are too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$,$K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$.\nIn order to prove $K_\\mathsf{Arr_1}$,$K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$ are consistent, the prover can use one of two methods.\nThe most straight-forward method is to use the additive homomorphic property of the KZG polynomial commitment scheme which states that for equal-sized polynomials on the same domain:\n$K_\\mathsf{Arr_1}\\otimes K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}\\oplus \\mathsf{Poly}_\\mathsf{Arr_2})$ Here $\\otimes$ is multiplication in the KZG group (e.g., $\\mathbb{G}_1$ in BLS12-381) while $\\oplus$ is addition in $\\mathbb{Z}_q$ of each evaluation point in $ \\mathsf{Poly}_\\mathsf{Arr_1}$ with each evaluation point in $\\mathsf{Poly}_\\mathsf{Arr_2}$. If the prover ($\\mathcal{P}$) can set $K_\\mathsf{Arr_3}\\leftarrow K_\\mathsf{Arr_1}\\otimes K_\\mathsf{Arr_2}$, then the verifier can check $K_\\mathsf{Arr_3}\\stackrel{?}{=}K_\\mathsf{Arr_1}\\otimes K_\\mathsf{Arr_2}$.\nHowever a second method is needed in other cases. Note that there are many different polynomials that interpolate $\\mathsf{Arr_3}$ on the domain $\\mathcal{H}_\\kappa$ (but are different elsewhere in the polynomial outside of $\\mathcal{H}_\\kappa)$. Each of these polynomials will have a unique commitment value. So it is possible that $K_\\mathsf{Arr_3}\\neq K_\\mathsf{Arr_1}\\otimes K_\\mathsf{Arr_2}$, and yet $\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i]$ for all $i$. This arises when $\\mathsf{Poly}_\\mathsf{Arr_3}$ comes from a different part of the protocol than $\\mathsf{Poly}_\\mathsf{Arr_1}$ and $\\mathsf{Poly}_\\mathsf{Arr_2}$.\nThe second method is more general so it can be used in place of the first method (but is more expensive), as well as covering all cases where $\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i]$. The idea is to show $\\mathsf{Arr_3}[i]-\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i]=0$ for each evaluation point in the domain $\\mathcal{H}_\\kappa$. Showing a polynomial is zero on the domain (a \u0026ldquo;vanishing polynomial\u0026rdquo;) is a common sub-protocol used by many gadgets.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ computes or holds an array $\\mathsf{Arr_3} = [a_{(3,0)}, a_{(3,1)}, a_{(3,2)}, \\dots, a_{(3,n-1)}]$ of $n$ integers ($a_{(3,i)} \\in \\mathbb{Z}_q$) such that: $\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i]$ for $i$ from 0 to $n-1$ Polynomial Level # We assume the three arrays $\\mathsf{Arr_1}$, $\\mathsf{Arr_2}$, and $\\mathsf{Arr_3}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 0 (which will not change the sum).\nRecall the constraint we want to prove:\n$\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i]$ for $i$ from 0 to $n-1$ In polynomial form, the constraint is:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_3}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Arr_2}(X)$ We adjust the constraints to show an equality with 0 and label it:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Vanish}(X)= \\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Arr_2}(X) - \\mathsf{Poly}_\\mathsf{Arr_3}(X)=0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(X)}{X^\\kappa - 1}$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$ Ultimately the add1 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_3}(X)$. Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) are too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$\n$K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$\n$K_\\mathsf{Arr_3}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_3}(X))$\n$K_Q=\\mathsf{KZG.Commit}(Q(X))$\nThe prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$\n$\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$\n$\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$\n$\\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_3},\\zeta)$\n$Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$\nTo check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish}=\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)+\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta)$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Rust Mathematica (Toy Example) Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr_1}, \\mathsf{Arr_2}$ and $\\mathsf{Arr_3}$ such that $\\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i] - \\mathsf{Arr_3}[i] = 0 \\space \\forall i \\in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$ = Y_\\mathsf{Vanish} - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$ = \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta) - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta) - \\frac{\\mathsf{Poly_{Vanish}}(\\zeta)}{\\zeta^\\kappa - 1}\\cdot(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)+\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta))$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish}}(X)$ is vanishing on $\\mathcal{H_\\kappa}$, i.e. if $\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Arr_2}(X) - \\mathsf{Poly}_\\mathsf{Arr_3}(X) =0 \\space \\forall X \\in \\mathcal{H}_\\kappa$. This is true if if $\\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i] - \\mathsf{Arr_3}[i] = 0 \\space \\forall i \\in [0, \\kappa - 1]$, since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$. But $\\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i] - \\mathsf{Arr_3}[i] = 0 \\space \\forall i \\in [0, \\kappa - 1]$ is precisely the relation tnat we assumed held for our prover (if $\\kappa \\gt n$ then the arrays get padded such that this relation still holds), thus the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr3}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr3}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{\\mathcal{V}}$ accepts at the end of the protocol\nii) $\\mathsf{Arr}_3\\neq \\mathsf{Arr}_1 + \\mathsf{Arr}_2$\nOur proof is as follows:\nFor the second win condition to be fulfilled, the constraint must not hold for at least one index of the arrays. But then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calculate the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Arr1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr2}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr3}(X)$. Each commitment $\\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr2}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\zeta)$ can only feasibly be opened to one value each. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr2}(\\tau)}$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\tau)$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Arr2}(\\tau)}$, and $g^{\\mathsf{Poly}_\\mathsf{Arr3}(\\tau)}$ to write as the commitments $K_\\mathsf{Arr1}$, $ K_\\mathsf{Arr2}$, and $ K_\\mathsf{Arr3}$. $\\mathcal{S}$ then generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr2}(\\tau)}$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\tau)$. $\\mathcal{S}$ writes the commitment $K_Q = g^{Q(\\tau)}$ to the transcript.\nNow, $\\mathcal{S}$ generates the second random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Arr2}(\\zeta)}$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\zeta)$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generated from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nFor add2, the proof is written with a simulator that doesn\u0026rsquo;t know the trapdoor; however, with small alterations the proof for add2 should apply here and vice versa "},{"id":3,"href":"/docs/gadgets/add2/","title":"Add2","section":"Gadgets","content":" Addition (Type 2) # Recap of types # Type Description Recap This add1 $\\mathsf{Arr}_3=\\mathsf{Arr}_1 + \\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the element-wise addition of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. add2 $\\mathsf{Sum}_\\mathsf{Arr}=\\sum_{i = 0}^{n-1} \\mathsf{Arr}[i]$ $\\mathsf{Sum}_\\mathsf{Arr}$ is the disclosed sum of all the elements in $\\mathsf{Arr}$. ✅ add3 $\\sum_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\sum_{i = 0}^{n-1} \\mathsf{Arr}_2[i]$ $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ have the same undisclosed sum. Relation # $ \\mathcal{R}_{\\mathtt{add2}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr},\\mathsf{Sum}_\\mathsf{Arr}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}], \\\\ \\mathsf{Sum}_\\mathsf{Arr} = \\sum_{i = 0}^{n-1} a_i, \\\\ \\mathsf{Poly}_\\mathsf{Arr}(X)=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X)) \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds an array $\\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers (from $\\mathbb{Z}_q$) and a disclosed integer $\\mathsf{Sum}_\\mathsf{Arr}$. It will produce a succinct (independent of $n$) proof that $\\mathsf{Sum}_\\mathsf{Arr}$ is the sum of all the elements in the array. The prover will encode the array into a polynomial $\\mathsf{Poly}_\\mathsf{Arr}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to the polynomial $K_\\mathsf{Arr}$. The verifier ($\\mathcal{V}$) cannot check $\\textsf{Arr}$ or $\\mathsf{Poly}_\\mathsf{Arr}$ directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr}$ and the asserted value $\\mathsf{Sum_\\mathsf{Arr}}$.\nIn order to prove $K_\\mathsf{Arr}$ and $\\mathsf{Sum}_\\mathsf{Arr}$ are consistent, the prover will build a helper array $\\mathsf{Acc}_\\mathsf{Arr}$ called an accumulator (or accumulating array or incremental array). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\\mathsf{Arr}$, the prover will also encode $\\mathsf{Acc}$ as a polynomial and provide a commitment of it to the verifier. The idea is that the prover will prove a relation between $\\mathsf{Arr}$ and $\\mathsf{Acc}$; and a relation between $\\mathsf{Acc}$ and $\\mathsf{Sum_\\mathsf{Arr}}$. Put together, it will imply the correct relation between $\\mathsf{Arr}$ and $\\mathsf{Sum_\\mathsf{Arr}}$.\nConsider a small numeric example in $\\mathbb{Z}_{97}$ where $\\mathsf{Arr}= [84,67,11,92,36,67]$ and $\\mathsf{Sum}_\\mathsf{Arr}=66$. The first idea is to get $\\mathsf{Sum}_\\mathsf{Arr}$ into an array. Say, we just append it: $\\mathsf{Arr}''= [84,67,11,92,36,67,66] $. How does the prover show $\\mathsf{Arr}''$ is correct? The last value of the array depends on every single element that precedes it, which will be a complex constraint to prove.\nAn alternative idea is to create a new array that starts the same as $\\mathsf{Arr}$ and ends up at $\\mathsf{Sum}_\\mathsf{Arr}$ by folding in the integers from $\\mathsf{Arr}$ one-by-one with addition. Then each value in the new array will depend on only two values, as below.\nThe first value in $\\mathsf{Acc}$ will be a copy of the first value from $\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$\\mathsf{Acc}= [84, \\bot,\\bot,\\bot,\\bot,\\bot] $\nThe next value will be the addition (mod 97) of: 67 (the value at the same index in $\\mathsf{Arr}$) and 84 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$ \\mathsf{Acc} = [84, (67+84),\\bot,\\bot,\\bot,\\bot] = [84, 54,\\bot,\\bot,\\bot,\\bot]$\nThe next value will be the addition of: 11 (the value at the same index in $\\mathsf{Arr}$) and 54 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [84, 54,(11+54),\\bot,\\bot,\\bot] = [84,54,65,\\bot,\\bot,\\bot]$ $ \\mathsf{Acc} = [84, 54, 65,(92+65),\\bot,\\bot] = [84,54,65, 60,\\bot,\\bot]$ $ \\mathsf{Acc} = [84,54,65, 60,(36 + 60),\\bot] = [84,54,65, 60, 96,\\bot]$ $ \\mathsf{Acc} = [84,54,65, 60, 96, (67+96)] = [84,54,65, 60, 96, 66]$ $\\mathsf{Sum}_\\mathsf{Arr}=66$ Notice the last value in $\\mathsf{Acc}$ is $\\mathsf{Sum_\\mathsf{Arr}}$. The prover wants to show three constraints:\nThe first value in $\\mathsf{Acc}$ matches the first value in $\\mathsf{Arr}$, The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i]+\\mathsf{Acc}[i-1]$, The last value in $\\mathsf{Acc}$ matches $\\mathsf{Sum}_\\mathsf{Arr}$. If all three constraints are true, then $\\mathsf{Sum}_\\mathsf{Arr}$ is the sum of the elements of $\\mathsf{Arr}$.\nLast, while it is not necessary to do, it is often convenient to hold the the value $\\mathsf{Sum}_\\mathsf{Arr}$ at the start of the array $\\mathsf{Acc}$ instead of the end. For this reason, the mathematical explanation below will construct $\\mathsf{Acc}$ \u0026ldquo;backwards\u0026rdquo; (or right-to-left) from the above example, where the last value of $\\mathsf{Acc}$ matches the last value of $\\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\\mathsf{Acc}$ is $\\mathsf{Sum}_\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, \\bot, 67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, 6, 67]$ $\\ldots$ $ \\mathsf{Acc} = [66, 79, 12, 1, 6, 67]$ $\\mathsf{Sum}_\\mathsf{Arr}=66$ Protocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers ($a_i \\in \\mathbb{Z}_q$) $\\mathcal{P}$ computes array $\\mathsf{Acc}$ as follows: $\\mathsf{Acc}[n-1]\\leftarrow\\mathsf{Arr}[n-1]$ $\\mathsf{Acc}[i]\\leftarrow\\mathsf{Arr}[i]+\\mathsf{Acc}[i+1]$ for $i$ from $n-2$ to 0 $\\mathcal{P}$ computes $\\mathsf{Sum}_\\mathsf{Arr}\\leftarrow\\mathsf{Acc}[0]$ Polynomial Level # We assume arrays $\\mathsf{Arr}$ and $\\mathsf{Acc}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 0 (which will not change the sum).\nRecall the three constraints we want to prove (now adjusted to fit with an $\\mathsf{Acc}$ that is constructed \u0026ldquo;backwards,\u0026rdquo; as noted above):\nThe last value in $\\mathsf{Acc}$ matches the last value in $\\mathsf{Arr}$, The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i]+\\mathsf{Acc}[i-1]$, The first value in $\\mathsf{Acc}$ matches $\\mathsf{Sum}_\\mathsf{Arr}$. In polynomial form, the constraints are:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Sum}_\\mathsf{Arr}$ In constraint 2, $\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ can also be conceptualized as rotate applied to $\\mathsf{Poly}_\\mathsf{Acc}(X)$ by one element (rightward in the array view). Also note that constraint 2 does not hold at $X=\\omega^{\\kappa-1}$ because this value is defined by constraint 1 (for the last value of $X$, the \u0026ldquo;next\u0026rdquo; value, $\\omega X$, wraps back to the first element of the array which is a boundary condition).\nWe adjust each of these constraints to show an equality with 0:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)=0$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)=0$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Sum}_\\mathsf{Arr}=0$ Next we take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X))\\cdot(X-\\omega^{\\kappa-1})=0$ $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These equations are true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$, and $\\mathsf{Poly}_\\mathsf{Vanish3}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prove computes,\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ $Q_3(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$, $Q_2(X)$, and $Q_3(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all three $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all three are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2}{X^\\kappa - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(X) + \\rho^2 \\mathsf{Poly}_\\mathsf{Vanish3}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the add2 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Acc}(X)$, $\\mathsf{Poly}_\\mathsf{Acc}(\\omega X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, and $\\mathsf{Sum}_\\mathsf{Arr}$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X))$ $K_\\mathsf{Acc}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Acc}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Acc},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}=(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish2}=(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Vanish3}=(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)}$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Rust Mathematica (Toy Example) Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}$ such that $\\mathsf{Sum}_\\mathsf{Arr}=\\sum_{i = 0}^{n-1} \\mathsf{Arr}[i] \\space \\forall i \\in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)} \\newline - \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(\\zeta)\\rho^2}{\\zeta^\\kappa - 1} \\cdot(\\zeta^\\kappa - 1)$\n$= (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)} \\newline - ((\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) \\newline + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)})$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(\\zeta)\\rho^2$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish_1}}(X), \\mathsf{Poly_{Vanish_2}}(X)$ and $\\mathsf{Poly_{Vanish_3}}(X),$ are all vanishing on $\\mathcal{H_\\kappa}$, i.e. if all three of the following conditions hold for all $X \\in \\mathcal{H}_\\kappa$:\n$(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$ $ (\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X))\\cdot(X-\\omega^{\\kappa-1})=0$ $ (\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These conditions, in turn, hold if:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Sum}_\\mathsf{Arr}$ Where we get the \u0026ldquo;For $X$\u0026rdquo; due to zeroing parts of the polynomials (see zero1). Since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$, the above conditions are true if:\nThe last value in $\\mathsf{Acc}$ matches the last value in $\\mathsf{Arr}$ The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i]+\\mathsf{Acc}[i-1]$ The first value in $\\mathsf{Acc}$ matches $\\mathsf{Sum}_\\mathsf{Arr}$ Which are precisely the conditions the Intuitions sections explains will hold if the prover contructs their Accumulator by following the protocol and using $\\mathsf{Arr}$ such that $\\mathsf{Sum}_\\mathsf{Arr}=\\sum_{i = 0}^{n-1} \\mathsf{Arr}[i] \\space \\forall i \\in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Acc}(X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Acc}(X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Sum}_\\mathsf{Arr}\\neq\\sum_{i = 0}^{n-1} \\mathsf{Arr}[i]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, one of the three constraints must be false. But then the $\\mathsf{Poly}_\\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Acc}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr}(X)$. Each commitment $\\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta \\cdot \\omega)$ can only feasibly be opened to one value each. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2Y_\\mathsf{Vanish3}}{\\zeta^\\kappa - 1}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2Y_\\mathsf{Vanish3}}{\\zeta^\\kappa - 1}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $A$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ generates an array $\\mathsf{Arr'}$ whose product is equal to the disclosed value $\\mathsf{Sum}_\\mathsf{Arr}$ (this array could just have $\\mathsf{Prod}_\\mathsf{Sum}$ in one entry, and $0$\u0026rsquo;s elsewhere), then follows the same steps a prover would to prove the sum of this array. So, $\\mathcal{S}$ computes the accumulator $\\mathsf{Acc'}$ and interpolates the two arrays into their respective polynomials, $\\mathsf{Poly}_\\mathsf{Acc'}(X)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(X)$. It computes $Q(X)'$ using $\\mathsf{Poly}_\\mathsf{Acc'}(X)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(X)$ and the random challenge point $\\rho'$ (by strong Fiat-Shamir). $\\mathcal{S}$ commits to each of these three polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta'$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_\\mathsf{Acc'}(\\zeta'), \\space \\mathsf{Poly}_\\mathsf{Arr'}(\\zeta'), \\space Q(\\zeta')'$, and $\\mathsf{Poly}_\\mathsf{Acc'}(\\zeta' \\cdot \\omega)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nThis proof could also be done by defining a simulator that knows the trapdoor $\\tau$ and can thus create a passing witness for any commitment. The proof for add1 is done in this style, but with small alterations would work here as well (and vice versa with this style of proof working for add1) "},{"id":4,"href":"/docs/gadgets/add3/","title":"Add3","section":"Gadgets","content":" Addition (Type 3) # Recap of types # Type Description Recap This add1 $\\mathsf{Arr}_3=\\mathsf{Arr}_1 + \\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the element-wise addition of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. add2 $\\mathsf{Sum}_\\mathsf{Arr}=\\sum_{i = 0}^{n-1} \\mathsf{Arr}[i]$ $\\mathsf{Sum}_\\mathsf{Arr}$ is the disclosed sum of all the elements in $\\mathsf{Arr}$. add3 $\\sum_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\sum_{i = 0}^{n-1} \\mathsf{Arr}_2[i]$ $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ have the same undisclosed sum. ✅ Relation # $ \\mathcal{R}_{\\mathtt{add3}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr2}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}],\\\\ \\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}], \\\\ \\mathsf{Poly}_\\mathsf{Arr_1}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_1}), \\\\ \\mathsf{Poly}_\\mathsf{Arr_2}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_2}), \\\\ K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}),\\\\ K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}), \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds two arrays $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that they have the same undisclosed sum. The prover will encode the two arrays into polynomials, $\\mathsf{Poly}_\\mathsf{Arr_1}$ and $\\mathsf{Poly}_\\mathsf{Arr_2}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to them as $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$. The verifier ($\\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$.\nIn order to prove $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$ are consistent, the prover will build two helper arrays $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$ called accumulators (or accumulating arrays or incremental arrays). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$, the prover will also encode $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$ as a polynomials and provide a commitment to the verifier of each one. The idea is that the prover will prove a relation between each $\\mathsf{Arr}$ and its $\\mathsf{Acc}$; and a relation between $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$. Put together, it will imply the correct relation between $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$.\nWe will illustrate a small numerical example in $\\mathbb{Z}_{97}$ of constructing an accumulator $\\mathsf{Acc}$ for the array $\\mathsf{Arr}= [84,67,11,92,36,67]$. The idea is to create a new array, $\\mathsf{Acc}$, that starts the same as $\\mathsf{Arr}$ and ends with the sum of all entries of $\\mathsf{Arr}$, by folding in the integers from $\\mathsf{Arr}$ one-by-one with multiplication. Then each value in the new array will depend on only two values, as below.\nThe first value in $\\mathsf{Acc}$ will be a copy of the first value from $\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$\\mathsf{Acc}= [84, \\bot,\\bot,\\bot,\\bot,\\bot] $\nThe next value will be the addition (mod 97) of: 67 (the value at the same index in $\\mathsf{Arr}$) and 84 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$ \\mathsf{Acc} = [84, (67+84),\\bot,\\bot,\\bot,\\bot] = [84, 54,\\bot,\\bot,\\bot,\\bot]$\nThe next value will be the addition of: 11 (the value at the same index in $\\mathsf{Arr}$) and 54 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [84, 54,(11+54),\\bot,\\bot,\\bot] = [84,54,65,\\bot,\\bot,\\bot]$ $ \\mathsf{Acc} = [84, 54, 65,(92+65),\\bot,\\bot] = [84,54,65, 60,\\bot,\\bot]$ $ \\mathsf{Acc} = [84,54,65, 60,(36 + 60),\\bot] = [84,54,65, 60, 96,\\bot]$ $ \\mathsf{Acc} = [84,54,65, 60, 96, (67+96)] = [84,54,65, 60, 96, 66]$ $\\mathsf{Sum}_\\mathsf{Arr}=66$ Notice the last value in $\\mathsf{Acc}$ is $\\mathsf{Sum_\\mathsf{Arr}}$. The prover wants to show three constraints:\nThe first value in $\\mathsf{Acc}$ matches the first value in $\\mathsf{Arr}$, The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i]+\\mathsf{Acc}[i-1]$, The last value in $\\mathsf{Acc}$ matches $\\mathsf{Sum}_\\mathsf{Arr}$. If all three constraints are true, then $\\mathsf{Sum}_\\mathsf{Arr}$ is the sum of the elements of $\\mathsf{Arr}$.\nLast, while it is not necessary to do, it is often convenient to hold the the value $\\mathsf{Sum}_\\mathsf{Arr}$ at the start of the array $\\mathsf{Acc}$ instead of the end. For this reason, the mathematical explaination below will construct $\\mathsf{Acc}$ \u0026ldquo;backwards\u0026rdquo; (or right-to-left) from the above example, where the last value of $\\mathsf{Acc}$ matches the last value of $\\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\\mathsf{Acc}$ is $\\mathsf{Sum}_\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, \\bot, 67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, 6, 67]$ $\\ldots$ $ \\mathsf{Acc} = [66, 79, 12, 1, 6, 67]$ and the sum of all entries in $\\mathsf{Acc}$ is 66 Protocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ computes array $\\mathsf{Acc_j}$ as follows for $j \\in [1,2]$: $\\mathsf{Acc_j}[n-1]\\leftarrow\\mathsf{Arr_j}[n-1]$ $\\mathsf{Acc_j}[i]\\leftarrow\\mathsf{Arr_j}[i]+\\mathsf{Acc_j}[i+1]$ for $i$ from $n-2$ to 0 Polynomial Level # We assume arrays $\\mathsf{Arr_1}$, $\\mathsf{Arr_2}$, $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 0 (which will not change the sum).\nRecall the five constraints we want to prove (now adjusted to fit with an $\\mathsf{Acc}$ that is constructed \u0026ldquo;backwards,\u0026rdquo; as noted above):\nThe last value in $\\mathsf{Acc_1}$ matches the last value in $\\mathsf{Arr_1}$ The last value in $\\mathsf{Acc_2}$ matches the last value in $\\mathsf{Arr_2}$ The rest of the values in $\\mathsf{Acc}_1$ are of the form $\\mathsf{Acc_1}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Acc_1}[i-1]$ The rest of the values in $\\mathsf{Acc}_2$ are of the form $\\mathsf{Acc_2}[i]=\\mathsf{Arr_2}[i]+\\mathsf{Acc_2}[i-1]$ The first value in $\\mathsf{Acc_1}$ matches the first value in $\\mathsf{Acc_2}$ In polynomial form, the constraints are:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, For $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)+\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Acc_2}(X)$ In constraints 2 and 3, $\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ can also be conceptualized as rotate applied to $\\mathsf{Poly}_\\mathsf{Acc}(X)$ by one element (rightward in the array view). Also note that constraints 2 and 3 do not hold at $X=\\omega^{\\kappa-1}$ because this value is defined by constraint 1 (for the last value of $X$, the \u0026ldquo;next\u0026rdquo; value, $\\omega X$, wraps back to the first element of the array which is a boundary condition).\nWe adjust each of these constraints to show an equality with 0:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X)=0$, For $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X)=0$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)=0$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X)+\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)=0$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Acc_2}(X)=0$ Next we take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=(\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$, $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-(\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)))\\cdot(X-\\omega^{\\kappa-1})=0$ $\\mathsf{Poly}_\\mathsf{Vanish4}(X)=(\\mathsf{Poly}_\\mathsf{Acc_2}(X)-(\\mathsf{Poly}_\\mathsf{Arr_2}(X)+\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)))\\cdot(X-\\omega^{\\kappa-1})=0$ $\\mathsf{Poly}_\\mathsf{Vanish5}(X)=(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Acc_2}(X)\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These equations are true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish3}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish4}(X)$, and $\\mathsf{Poly}_\\mathsf{Vanish5}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prove computes,\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ $Q_3(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^\\kappa - 1}$ $Q_4(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish4}(X)}{X^\\kappa - 1}$ $Q_5(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish5}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$, $Q_2(X)$, $Q_3(X)$, $Q_4(X)$, and $Q_5(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all five $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all five are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4}{X^\\kappa - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2} (X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X) \\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4 - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the add3 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$ $K_\\mathsf{Acc_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Acc_1}(X))$ $K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$ $K_\\mathsf{Acc_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Acc_2}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Acc_1},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Acc_2},\\zeta\\omega)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}= (\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish2}= (\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish3}=(\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)-(\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot \\zeta)))\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Vanish4}= (\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)-(\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot \\zeta)))\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Vanish5}= (\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)-\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)}$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5}- Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ such that $\\sum_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\sum_{i = 0}^{n-1} \\mathsf{Arr}_2[i] \\space \\forall i \\in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$ = Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5}- Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5} - (\\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4}{X^\\kappa - 1})(\\zeta^\\kappa - 1)$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5} - {\\mathsf{Poly}_\\mathsf{Vanish1}(X) - \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho - \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 - \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 - \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4}$\n$= 0$\nWhere the finally equality holds because $Y_{\\mathsf{Vanish_j}}=\\mathsf{Poly_{Vanish_j}}(\\zeta)$.\nNote also that the second equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish_1}}(X), \\mathsf{Poly_{Vanish_2}}(X)$, $\\mathsf{Poly_{Vanish_3}}(X),$ $\\mathsf{Poly_{Vanish_4}}(X)$, and $\\mathsf{Poly_{Vanish_5}}(X),$ are all vanishing on $\\mathcal{H_\\kappa}$, i.e. if all three of the following conditions hold for all $X \\in \\mathcal{H}_\\kappa$:\n$ (\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$ $ (\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$ $(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-(\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)))\\cdot(X-\\omega^{\\kappa-1})=0$ $ (\\mathsf{Poly}_\\mathsf{Acc_2}(X)-(\\mathsf{Poly}_\\mathsf{Arr_2}(X)+\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)))\\cdot(X-\\omega^{\\kappa-1})=0$ $ (\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Acc_2}(X)\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These conditions, in turn, hold if:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)$ For $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)+\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Acc_2}(X)$ Where we get the \u0026ldquo;For $X$\u0026rdquo; due to zeroing parts of the polynomials (see zero1). Since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$, the above conditions are true if:\nThe last value in $\\mathsf{Acc_1}$ matches the last value in $\\mathsf{Arr_1}$ The last value in $\\mathsf{Acc_2}$ matches the last value in $\\mathsf{Arr_2}$ The rest of the values in $\\mathsf{Acc}_1$ are of the form $\\mathsf{Acc_1}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Acc_1}[i-1]$ The rest of the values in $\\mathsf{Acc}_2$ are of the form $\\mathsf{Acc_2}[i]=\\mathsf{Arr_2}[i]+\\mathsf{Acc_2}[i-1]$ The first value in $\\mathsf{Acc_1}$ matches the first value in $\\mathsf{Acc_2}$ Which are precisely the conditions the Intuitions sections explains will hold if the prover constructs their Accumulators by following the protocol and using $\\mathsf{Arr}_1$ and $\\mathsf{Arr_2}$ such that $\\sum_{i = 0}^{n-1} \\mathsf{Arr}_1[i] =\\sum_{i = 0}^{n-1} \\mathsf{Arr}_2[i] \\space \\forall i \\in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_{2}}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_{2}}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_{2}}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_{2}}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\sum_{i = 0}^{n-1} \\mathsf{Arr_1}[i]\\neq\\sum_{i = 0}^{n-1} \\mathsf{Arr_2}[i]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, one of the five constraints must be false. But then the $\\mathsf{Poly}_\\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$. Each commitment $\\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta \\cdot \\omega)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta \\cdot \\omega)$ can each only feasibly be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4Y_\\mathsf{Vanish5}}{(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4Y_\\mathsf{Vanish5}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Acc_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$ and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\tau)$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Acc_1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, and $g^{\\mathsf{Poly}_\\mathsf{Acc_2}(\\tau)}$ to write as the commitments $K_\\mathsf{Arr_1}$, $ K_\\mathsf{Acc_1}$, $K_\\mathsf{Arr_2}$, and $ K_\\mathsf{Acc_2}$. $\\mathcal{S}$ then generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Acc_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$ and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\tau)$. $\\mathcal{S}$ writes the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the second random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta \\cdot \\omega)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)}$, and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta\\cdot\\omega)$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4Y_\\mathsf{Vanish5}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nFor mult2, the proof is written with a simulator that doesn\u0026rsquo;t know the trapdoor; however, with small alterations the proof for mult2 should apply here and vice versa "},{"id":5,"href":"/docs/gadgets/circuit/","title":"Circuit","section":"Gadgets","content":" Circuit # Recap of types # Type Description Recap This circuit $z=\\mathsf{Circ}(x,y)$ $z$ is the output of disclosed arithmetic circuit $\\mathsf{Circ}$ with disclosed (and/or undisclosed) inputs $x$ and $y$. ✅ Relation # $\\mathcal{R}_{\\mathtt{circ}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{T},K_\\mathsf{In}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{In}=[i_0,i_1,i_2,i_3], \\\\ \\mathsf{T}=[t_0,t_1,t_2,t_3], \\\\ \\mathsf{T}[3]\\in\\{0,1\\}, \\\\ \\mathsf{T}[3]\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{T}[0]+\\mathsf{In}[1]\\cdot\\mathsf{T}[1])+(1-\\mathsf{T}[3])\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{In}[1]\\cdot\\mathsf{T}[2])+\\mathsf{In}[2]=\\mathsf{In}[3], \\\\ \\mathsf{Poly}_\\mathsf{T}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{T}), \\\\ \\mathsf{Poly}_\\mathsf{In}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{In}), \\\\ K_\\mathsf{T}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T}), \\\\ K_\\mathsf{In}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{In}) \\\\ \\end{array} \\right\\}$\nIntuition # The prover ($\\mathcal{P}$) and the verifier ($\\mathcal{V}$) are both given a circuit $\\mathsf{T}$, where $\\mathsf{T}[0]$ and $\\mathsf{T}[1]$ are the coefficients of the two inputs respectively, $\\mathsf{T}[2]$ is the coefficient of the product of the two inputs, and $\\mathsf{T}[3]$ is the selector of the gate ($\\mathsf{T}[3]$ is one for addition gate and zero for multiplication gate). The prover wants to prove he knows an input vector $\\mathsf{In}$ satisfying $\\mathsf{T}$. Specifically, we define $\\mathsf{In}[0]$ and $\\mathsf{In}[1]$ are the inputs of the circuit, $\\mathsf{In}[2]$ is a constant, and $\\mathsf{In}[3]$ is the output. Thus, the prover will produce a succinct proof that $\\mathsf{In}$ satisfies the following condition: the equation $\\mathsf{T}[3]\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{T}[0]+\\mathsf{In}[1]\\cdot\\mathsf{T}[1])+(1-\\mathsf{T}[3])\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{In}[1]\\cdot\\mathsf{T}[2])+\\mathsf{In}[2]=\\mathsf{In}[3]$ holds.\nThis means that if $\\mathsf{T}[3] = 0$, this is the circuit which must be satisfied:\nflowchart LR in0[\"In[0]\"] \u0026 in1[\"In[1]\"] --\u003e id1((x)) t2[\"T[2]\"] \u0026 id1 --\u003e id2((x)) in2[\"In[2]\"] \u0026 id2 --\u003e id3((+)) id3 --\u003e in3[\"In[3]\"] And if $\\mathsf{T}[3] = 1$, this is the circuit which must be satisfied:\nflowchart LR in0[\"In[0]\"] \u0026 t0[\"T[0]\"] --\u003e id1((x)) in1[\"In[1]\"] \u0026 t1[\"T[1]\"] --\u003e id2((x)) id1 \u0026 id2 --\u003e id3((+)) in2[\"In[2]\"] \u0026 id3 --\u003e id4((+)) id4 --\u003e in3[\"In[3]\"] Consider, as an example, the circuit $5x+6y$. Thus, $\\mathsf{T}=[5,6,0,1]$. Since $\\mathsf{T}$ is publicly known to both parties, $\\mathsf{Poly}_\\mathsf{T}$ is also known and the prover does not need to prove the correctness of $\\mathsf{T}$. Now the prover claims $\\mathsf{In}=[6,5,0,60]$ satisfies the circuit. Indeed, $5\\cdot 6+ 6\\cdot 5 + 0 = 60$. Instead of sending each element of $\\mathsf{In}$ one by one to show this, the prover interpolates a polynomial $\\mathsf{Poly}_\\mathsf{In}$ from $\\mathsf{In}$ and computes a vanishing polynomial with $\\mathsf{Poly}_\\mathsf{T}$ and $\\mathsf{Poly}_\\mathsf{In}$. If the prover can prove the polynomial is vanishing, the verifier will be convinced that the prover knows a valid $\\mathsf{In}$.\nProtocol Details # Array Level # $\\mathsf{P}$ and $\\mathsf{V}$ hold the array of the circuit $\\mathsf{T}=[t_0,t_1,t_2,t_3]$ $\\mathsf{P}$ holds an input array $\\mathsf{In}=[i_0,i_1,i_2,i_3]$ $\\mathsf{T}$ and $\\mathsf{In}$ satisfy the following conditions $\\mathsf{T}[3]\\in\\{0,1\\}$ $\\mathsf{T}[3]\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{T}[0]+\\mathsf{In}[1]\\cdot\\mathsf{T}[1])+(1-\\mathsf{T}[3])\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{In}[1]\\cdot\\mathsf{T}[2])+\\mathsf{In}[2]=\\mathsf{In}[3]$ Polynomial Level # We assume arrays $\\mathsf{T}$ and $\\mathsf{In}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product). In this case, $\\kappa$ is $4$.\nRecall the constraint we want to prove:\n$\\mathsf{T}[3]\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{T}[0]+\\mathsf{In}[1]\\cdot\\mathsf{T}[1])+(1-\\mathsf{T}[3])\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{In}[1]\\cdot\\mathsf{T}[2])+\\mathsf{In}[2]=\\mathsf{In}[3]$ In polynomial form, the constraint is:\nFor $X=\\omega^0$: $\\displaylines{\\mathsf{Poly}_\\mathsf{T}(X\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(X)\\cdot\\mathsf{Poly}_\\mathsf{T}(X)+\\mathsf{Poly}_\\mathsf{In}(X\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega))\\\\+(1-\\mathsf{Poly}_\\mathsf{T}(X\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(X)\\cdot\\mathsf{Poly}_\\mathsf{In}(X\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega^2))+\\mathsf{Poly}_\\mathsf{In}(X\\omega^2)=\\mathsf{Poly}_\\mathsf{In}(X\\omega^3)}$ We take care of the \u0026ldquo;for $X$\u0026rdquo; condition by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\displaylines{\\mathsf{Poly}_\\mathsf{Vanish}(X)=[\\mathsf{Poly}_\\mathsf{T}(X\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(X)\\cdot\\mathsf{Poly}_\\mathsf{T}(X)+\\mathsf{Poly}_\\mathsf{In}(X\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega))\\\\+(1-\\mathsf{Poly}_\\mathsf{T}(X\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(X)\\cdot\\mathsf{Poly}_\\mathsf{In}(X\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega^2))+\\\\\\mathsf{Poly}_\\mathsf{In}(X\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(X\\omega^3)]\\cdot\\frac{X^\\kappa-1}{X-\\omega^0}}$ The equation is vanishing for every value of $X\\in\\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\\kappa-1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$$ Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(X)}{X^\\kappa-1} $$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish}(X)-Q(X)\\cdot(X^{\\kappa}-1)=0$\nUltimately the range gadget will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{T}(X)$ and $\\mathsf{Poly}_\\mathsf{In}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the vector $\\mathsf{In}$ or the polynomial $\\mathsf{Poly}_\\mathsf{In}$. It is undisclosed because it either (i) contains private data or (ii) is too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{T}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T}(X))$ $K_\\mathsf{In}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{In}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta)$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta\\omega^2)$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta\\omega^3)$ $\\mathsf{Poly}_\\mathsf{In}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{In},\\zeta)$ $\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{In},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)=\\mathsf{KZG.Open}(K_\\mathsf{In},\\zeta\\omega^2)$ $\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)=\\mathsf{KZG.Open}(K_\\mathsf{In},\\zeta\\omega^3)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$$ \\displaylines{Y_\\mathsf{Vanish}=[\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega))\\\\+(1-\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2))+\\\\\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^0}} $$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{In}$ that satisfies the circuit $\\mathsf{T}$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= \\mathsf{Poly}_\\mathsf{Vanish}(\\zeta)-Q(\\zeta)\\cdot(\\zeta^{\\kappa}-1)$\n$= [\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega))+(1-\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2))+\\\\\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^0} -Q(\\zeta)\\cdot(\\zeta^\\kappa-1)$\n$= [\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega))+(1-\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2))+\\\\\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^0} - \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(\\zeta)}{\\zeta^\\kappa-1} \\cdot(\\zeta^\\kappa-1)$\n$= [\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega))+(1-\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2))+\\\\\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^0} \\newline - [[\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega))+(1-\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2))+\\\\\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^0} \\cdot(\\zeta^\\kappa-1)]$\n$=0$\nWhere the third equality relies on the fact that $\\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\\kappa -1$. This is true if $\\mathsf{Poly_{Vanish}}(\\zeta)$ is vanishing on $\\mathcal{H}_\\kappa$, i.e. if:\n$\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega))+(1-\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2))\\\\+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^0} = 0$\nWhich hold if, for $X=\\omega^0$:\n$ \\mathsf{Poly}_\\mathsf{T}(X\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(X)\\cdot\\mathsf{Poly}_\\mathsf{T}(X)+\\mathsf{Poly}_\\mathsf{In}(X\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega))+(1-\\mathsf{Poly}_\\mathsf{T}(X\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(X)\\cdot\\mathsf{Poly}_\\mathsf{In}(X\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega^2))\\\\+\\mathsf{Poly}_\\mathsf{In}(X\\omega^2)=\\mathsf{Poly}_\\mathsf{In}(X\\omega^3)$\nWhere we get the \u0026ldquo;for $X = \\omega^0$\u0026rdquo; due to zeroing parts of the polynomials (see zero1). Since $\\mathsf{Poly_T}(\\omega^i) = \\mathsf{T}[i]$ and $\\mathsf{Poly_{In}}(\\omega^i) = \\mathsf{In}[i]$, $\\forall i \\in [0, \\kappa - 1]$, the above conditions are true if:\n$\\mathsf{T}[3]\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{T}[0]+\\mathsf{In}[1]\\cdot\\mathsf{T}[1])+(1-\\mathsf{T}[3])\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{In}[1]\\cdot\\mathsf{T}[2])+\\mathsf{In}[2]=\\mathsf{In}[3]$\nBut this means precisely that $\\mathsf{In}$ satisfies the circuit $\\mathsf{T}$, which was the condition we assumed about the prover. Thus, the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g,g^\\tau,g^{\\tau^2},\\dots,g^{\\tau^{n-1}}]$, $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{In}(X)$ and $Q$ $\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{In}(X)$ and $Q$ $\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$ $\\mathcal{A}$ wins if $\\mathcal{V}$ accepts at the end of the protocol the values in $\\mathsf{In}$ do not satisfy the circuit The proof is trivial: to make $\\mathsf{Poly}_\\mathsf{Vanish}$ exist, the values in $\\mathsf{In}$ have to satisfy the circuit. By the Schwartz-Zippel lemma, the soundness error is $\\kappa/|\\mathbb{F}|$, which is negligible since $\\kappa=4$ and $\\mathbb{F}$ is enormous for any widely used elliptic curve.\nZero-Knowledge # To prove the above protocol is zero-knowledge, we do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ randomly generates $a$ and $b$ as the inputs of the circuit, and runs the circuit to compute the output $c$. Then $\\mathcal{S}$ follows the same steps a prover would prove the lookup argument. $\\mathcal{S}$ interpolates $\\mathsf{Poly}_\\mathsf{In^*}$ from $\\mathsf{In^*}$. It computes $Q^*(X)$ and finally outputs the commitments to each of these polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta^*$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_\\mathsf{T^*}$ and $\\mathsf{Poly}_\\mathsf{In^*}$ at $\\zeta^*,\\zeta^*\\omega,\\zeta^*\\omega^2,\\zeta^*\\omega^3$ respectively, and $Q^*(\\zeta^*)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":6,"href":"/docs/gadgets/concat/","title":"Concat","section":"Gadgets","content":" Concatenation # Recap of types # Type Description Recap This concat $\\mathsf{Arr}_3=\\mathsf{Arr}_1\\cup\\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the concatenation of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ ✅ Relation # $$ \\mathcal{R}_{\\mathtt{mult1}} := \\left\\{ \\begin{array}{l} (K_{\\mathsf{Arr}_1},K_{\\mathsf{Arr}_2},K_{\\mathsf{Arr}_3}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr}_3=\\mathsf{Arr}_1\\cup\\mathsf{Arr}_2, \\\\ \\mathsf{Arr}_3[i]=\\mathsf{Arr}_1[i],i\\in[0,n_1), \\\\ \\mathsf{Arr}_3[i+n_1]=\\mathsf{Arr}_2[i],i\\in[0,n_2), \\\\ \\mathsf{Poly}_\\mathsf{Arr_j}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_j}), 1\\leq j \\leq 3, \\\\ K_\\mathsf{Arr_j}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_j}), 1\\leq j \\leq 3, \\end{array} \\right\\} $$ Intuition # The prover ($\\mathcal{P}$) holds three arrays $\\mathsf{Arr}_1$, $\\mathsf{Arr}_2$ and $\\mathsf{Arr_3}$. He wants to convince the verifier ($\\mathcal{V}$) $\\mathsf{Arr}_3$ is the concatenation of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. Specifically, assume there are $n_1$, $n_2$, and $n_3$ elements in $\\mathsf{Arr}_1$, $\\mathsf{Arr}_2$, and $\\mathsf{Arr}_3$ respectively, then the prover will prove: (i) $\\mathsf{Arr}_3[i]=\\mathsf{Arr}_1[i],i\\in[0,n_1)$ (ii) $\\mathsf{Arr}_3[i+n_1]=\\mathsf{Arr}_2[i],i\\in[0,n_2)$. It is intuitive to think about using the grand product check in the Plookup. However, the product check of Plookup holds if and only if (i) $\\mathsf{Arr}_1$ is the subset of $\\mathsf{Arr}_2$ (ii) $\\mathsf{Arr}_3$ is the union set of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ (iii) $\\mathsf{Arr}_3$ is sorted by $\\mathsf{Arr}$. Thus, we cannot use the product check directly, but we can leverage the same fact in the product check of Plookup: the product of $\\mathsf{Arr}_3$ equals the product of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ if and only if $\\mathsf{Arr}_3$ is the union set of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ (permutation check). Additionally, we need to prove the concatenation relationship rather than the permutation. To solve this problem, we can break $\\mathsf{Arr}_3$ to two sub arrays $\\mathsf{Arr}_{3_l}$ and $\\mathsf{Arr}_{3_h}$ as we do in Plookup, and prove the product of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ equals the product of $\\mathsf{Arr}_{3_l}$ and $\\mathsf{Arr}_{3_h}$.\nThe other approach is fill $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ with zero to $n_1+n_2$, and construct a new vector $\\mathsf{Arr}_2^\\prime$ by rotating right $\\mathsf{Arr}_2$ by $n_1$, so that $\\mathsf{Arr}_3$ is the sum of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2^\\prime$. Instead of performing the product check in the previous approach, the prover proves three things: (i) $\\mathsf{Arr}_2^\\prime$ is rotated from $\\mathsf{Arr}_2$ (ii) $\\mathsf{Arr}_3=\\mathsf{Arr}_1+\\mathsf{Arr}_2^\\prime$ (iii) $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ are correctly fill with zero. Since we already discussed how product check in the plookup works, we will focus on the second solution in this post.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr}_1=[a_{(1,0)},a_{(1,1),\\dots,a_{(1,n_1-1)}}]$ of $n_1$ integers and fills it with zero to $n_1+n_2$ such that $\\mathsf{Arr}_1[i]=a_{(1,i)},i\\in[0,n_1)$ $\\mathsf{Arr}_1[i]=0,i\\in[n_1,n_1+n_2)$ $\\mathcal{P}$ holds an array $\\mathsf{Arr}_2=[a_{(2,0)},a_{(2,1),\\dots,a_{(2,n_1-1)}}]$ of $n_2$ integers and fills it with zero to $n_1+n_2$ such that $\\mathsf{Arr}_2[i]=a_{(2,i)},i\\in[0,n_2)$ $\\mathsf{Arr}_2[i]=0,i\\in[n_2,n_1+n_2)$ $\\mathcal{P}$ holds an array $\\mathsf{Arr}_3$ of $n_1+n_2$ integers $\\mathcal{P}$ computes or holds an arrays $\\mathsf{Arr}_2^\\prime$ of $n_1+n_2$ integers such that $\\mathsf{Arr}_2^\\prime[i+n_1]=\\mathsf{Arr}_2[i],i\\in[0,n_1+n_2)$ $\\mathsf{Arr}_1$, $\\mathsf{Arr}_2^\\prime$, and $\\mathsf{Arr}_3$ satisfy: $\\mathsf{Arr}_3[i]=\\mathsf{Arr}_1[i]+\\mathsf{Arr}_2^\\prime[i],i\\in[0,n_1+n_2)$ Polynomial Level # We assume arrays $\\mathsf{Arr}_1$, $\\mathsf{Arr}_2$, and $\\mathsf{Arr}_3$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product).\nRecall the constraints we want to prove:\n$\\mathsf{Arr}_3[i]=\\mathsf{Arr}_1[i]+\\mathsf{Arr}_2^\\prime[i],i\\in[0,n_1+n_2)$ $\\mathsf{Arr}_2^\\prime[i+n_1]=\\mathsf{Arr}_2[i],i\\in[n_1,n_1+n_2)$ $\\mathsf{Arr}_1[i]=0,i\\in[n_1,n_1+n_2)$ $\\mathsf{Arr}_2[i]=0,i\\in[n_2,n_1+n_2)$ In polynomial form, the constraints are:\n$\\mathsf{Poly}_{\\mathsf{Arr}_3}(X)=\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)+\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X)$ $\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)=\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X\\omega^{n_1})$ For $X\\in[n_1,n_1+n_2)$, $\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)=0$ For $X\\in[n_2,n_1+n_2)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)=0$ Next we take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=\\mathsf{Poly}_{\\mathsf{Arr}_3}(X)-\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)-\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X)$ $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)-\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X\\omega^{n_1})$ $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)\\cdot\\frac{X^\\kappa-1}{\\prod_{i=n_1}^{n_1+n_2-1}(X-\\omega^i)}$ $\\mathsf{Poly}_\\mathsf{Vanish4}(X)=\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)\\cdot\\frac{X^\\kappa-1}{\\prod_{i=n_2}^{n_1+n_2-1}(X-\\omega^i)}$ The four equations are vanishing for every value of $X\\in\\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa-1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$ and $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q_1(X)=\\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa-1}$ $Q_2(X)=\\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa-1}$ $Q_3(X)=\\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^\\kappa-1}$ $Q_4(X)=\\frac{\\mathsf{Poly}_\\mathsf{Vanish4}(X)}{X^\\kappa-1}$ We can replace polynomials $Q_1(X)$, $Q_2(X)$, $Q_3(X)$, and $Q_4(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all two $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all three are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$$ Q(X)=\\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)+\\rho^2\\cdot\\mathsf{Poly}_\\mathsf{Vanish3}(X)+\\rho^3\\cdot\\mathsf{Poly}_\\mathsf{Vanish4}(X)}{X^\\kappa-1} $$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$$ \\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)+\\rho^2\\cdot\\mathsf{Poly}_\\mathsf{Vanish3}(X)+\\rho^3\\cdot\\mathsf{Poly}_\\mathsf{Vanish4}(X)-Q(X)\\cdot(X^{\\kappa-1}-1)=0 $$ Ultimately the range gadget will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)$, and $\\mathsf{Poly}_{\\mathsf{Arr}_3}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) are too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_{\\mathsf{Arr}_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_{\\mathsf{Arr}_1}(X))$ $K_{\\mathsf{Arr}_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_{\\mathsf{Arr}_2}(X))$ $K_{\\mathsf{Arr}_3}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_{\\mathsf{Arr}_3}(X))$ $K_{\\mathsf{Arr}_2^\\prime}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_{\\mathsf{Arr}_1}(\\zeta)=\\mathsf{KZG.Open}(K_{\\mathsf{Arr}_1},\\zeta)$ $\\mathsf{Poly}_{\\mathsf{Arr}_2}(\\zeta)=\\mathsf{KZG.Open}(K_{\\mathsf{Arr}_2},\\zeta)$ $\\mathsf{Poly}_{\\mathsf{Arr}_3}(\\zeta)=\\mathsf{KZG.Open}(K_{\\mathsf{Arr}_3},\\zeta)$ $\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(\\zeta\\omega^{n_1})=\\mathsf{KZG.Open}(K_{\\mathsf{Arr}_2^\\prime},\\zeta\\omega^{n_1})$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}=\\mathsf{Poly}_{\\mathsf{Arr}_3}(\\zeta)-\\mathsf{Poly}_{\\mathsf{Arr}_1}(\\zeta)-\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(\\zeta)$ $Y_\\mathsf{Vanish2}=\\mathsf{Poly}_{\\mathsf{Arr}_2}(\\zeta)-\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(\\zeta\\omega^{n_1})$ $Y_\\mathsf{Vanish3}=\\mathsf{Poly}_{\\mathsf{Arr}_1}(\\zeta)\\cdot\\frac{\\zeta^\\kappa-1}{\\prod_{i=n_1}^{n_1+n_2-1}(\\zeta-\\omega^i)}$ $Y_\\mathsf{Vanish4}=\\mathsf{Poly}_{\\mathsf{Arr}_2}(\\zeta)\\cdot\\frac{\\zeta^\\kappa-1}{\\prod_{i=n_2}^{n_1+n_2-1}(\\zeta-\\omega^i)}$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1}+\\rho\\cdot{Y_\\mathsf{Vanish2}}+\\rho^2\\cdot{Y_\\mathsf{Vanish3}}+\\rho^3\\cdot{Y_\\mathsf{Vanish4}}-Q(\\zeta)\\cdot(\\zeta^n-1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Security Proof # Completeness # Any honest prover can do the computations explained above and create an accepting proof.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g,g^\\tau,g^{\\tau^2},\\dots,g^{\\tau^{n-1}}]$, $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_3}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X)$, and $Q$ $\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_3}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X)$, and $Q$ $\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$ $\\mathcal{A}$ wins if $\\mathcal{V}$ accepts at the end of the protocol $\\mathsf{Arr}_3$ is not the concatenation of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ Our proof is as follows:\nWhen $\\mathsf{Arr}_3$ is not the concatenation of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$, there are three cases: some elements in $\\mathsf{Arr}_1$ do not appear in $\\mathsf{Arr}_3$, or some elements in $\\mathsf{Arr}_2$ do not appear in $\\mathsf{Arr}_3$, or both of the previous situations. Since $\\mathcal{A}$ has to win the KS game in the first and the second cases if $\\mathcal{A}$ wants to win the game in the last case, it suffices to check any one of the first two situations. Now assume there are some elements in $\\mathsf{Arr}_1$ do not exist in $\\mathsf{Arr}_3$. Because the first $n_1$ elements in $\\mathsf{Arr}_2^\\prime$ are zero, we know that the equation $\\mathsf{Arr}_3[i]=\\mathsf{Arr}_1[i]+\\mathsf{Arr}_2^\\prime[i]$ does not hold for some $i\\in[0,n_1)$. Thus, for $\\mathsf{Poly}_\\mathsf{Vanish1}$, $Q_1$ does not exist (it is a rational function, not a polynomial), which means the probability that $Y_\\mathsf{Zero}$ is a zero polynomial is negligible.\nZero-Knowledge # To prove the above protocol is zero-knowledge, we do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ randomly generates $\\mathsf{Arr}_1^*$ and $\\mathsf{Arr}_2^*$ and computes $\\mathsf{Arr}_3^*$, then follows the same steps a prover would prove the concatenation. $\\mathcal{S}$ computes $\\mathsf{Arr}_2^{\\prime*}$ and interpolates $\\mathsf{Poly}_{\\mathsf{Arr}_1^*}$, $\\mathsf{Poly}_{\\mathsf{Arr}_2^*}$, $\\mathsf{Poly}_{\\mathsf{Arr}_3^*}$, and $\\mathsf{Poly}_{\\mathsf{Arr}_2^{\\prime*}}$. It computes $Q^*(X)$ and finally outputs the commitments to each of these polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta^*$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_{\\mathsf{Arr}_1^*}(\\zeta^*)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2^*}(\\zeta^*)$, $\\mathsf{Poly}_{\\mathsf{Arr}_3^*}(\\zeta^*)$, and $\\mathsf{Poly}_{\\mathsf{Arr}_2^{\\prime*}}(\\zeta^*\\omega^{n_1})$, and $Q^*(\\zeta^*)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":7,"href":"/docs/gadgets/encode/","title":"Encode","section":"Gadgets","content":" Encode # Relation # $ \\mathcal{R}_{\\mathtt{mult3}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr2}, \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}],\\\\ \\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}], \\\\ \\mathsf{Poly}_\\mathsf{Arr_1}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_1}), \\\\ \\mathsf{Poly}_\\mathsf{Arr_2}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_2}), \\\\ K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}),\\\\ K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}), \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds two arrays $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It wishes to map the pairs of elements, $\\{ \\mathsf{Arr_1[i], \\mathsf{Arr_2[i]}}\\}$ into a single element, $\\mathsf{Arr_3}[i]$ without collisions. It will produce a succinct (independent of $n$) proof that $\\mathsf{Arr_3}$ contains the encoding of $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ according to this mapping.\nFor the mapping scheme, we use random linear combinations, since it is both collision resistant and it can be proven in zero knowledge. To do so, the prover defines $f_i(X) = \\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i] \\cdot X$ for $i \\in [0, n-1]$. Then, the the prover calculates $\\mathsf{Arr_3}[i] = f_i(r)$ for a random field element $r$. Assuming $f_i$ is committed to before $r$ is know, this scheme is collision resistant by the Schwartz-Zippel lemma; if two polynomials are equal at $r$ then with overwhelming probability they are the same polynomial. However, to ensure negligible probability of collisions, $n$ may need to be smaller relative to the field size than initially thought. This is due to the birthday paradox. We are not evaluating the probability that a single one of the $n$ polynomials collides with one of the other $n-1$ polynomials, but rather the probability than any one polynomial out of $n$ collides with any other of the $n-1$ polynomials. The value of the latter is significantly larger, since it compares every possible pair of the $n$ polynomials, instead of just comparing one of the polynomials with the $n-1$ other polynomials. The probability of collisions can, however, still be made sufficiently small by bounding how large $n$ can be relative to the field size.\nIn order to prove the relation, the prover will encode the three arrays into three polynomials: $\\mathsf{Poly}_\\mathsf{Arr_1}$, $\\mathsf{Poly}_\\mathsf{Arr_2}$, and $\\mathsf{Poly}_\\mathsf{Arr_3}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$). It will commit to each polynomial: $K_\\mathsf{Arr_1}$, $K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$. The verifier ($\\mathcal{V}$) cannot check any of the $\\mathsf{Arr_i}$ or $\\mathsf{Poly}_\\mathsf{Arr_i}$ values directly (they may contain secret information, and even if they do not, they are too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$,$K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$. It will use these commitments to verified the constraint $\\mathsf{Arr_3}[i] = \\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i]\\cdot r$.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2, n-1)}]$ $\\mathcal{P}$ generates the random challenge $r$, then computes $\\mathsf{Arr_3}$ as follows: $\\mathsf{Arr_3}[i] = \\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i]\\cdot r$ Polynomial Level # We assume that $\\mathsf{Arr1}$, $\\mathsf{Arr_2}$, and $\\mathsf{Arr_3}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the arrays, the arrays can be padded with zeros.\nRecall the constraint we want to prove:\n$\\mathsf{Arr_3}[i] = f_i(X) =\\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i]\\cdot r$ We write the constraint in polynomial form:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_3}(X) = \\mathsf{Poly}_\\mathsf{Arr_1}(X) + \\mathsf{Poly_{Arr_2}}(X)\\cdot r$ We adjust the constraint to show an equality with 0 and label it:\n$\\mathsf{Poly}_\\mathsf{Vanish}(X)= \\mathsf{Poly}_\\mathsf{Arr_3}(X) - (\\mathsf{Poly}_\\mathsf{Arr_1}(X) + \\mathsf{Poly_{Arr_2}}(X)\\cdot r)= 0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(X)}{X^\\kappa - 1}$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the rotate argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly_{Arr_2}}$, and $\\mathsf{Poly}_\\mathsf{Arr_3}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$ $K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$​ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call this point $r$. We note that since $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ were committed to before $r$ was know, $fi$ is committed to before $r$ is known. This is important for the collision resistance of our encoding scheme. Now, using $r$, the prover can compute and commit to the following polynomials:\n$K_\\mathsf{Arr_3}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_3}(X))$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_3},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish}= \\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly_{Arr_2}}(\\zeta)\\cdot r)$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}_3$ that is a random linear combination of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ using $r$, can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly_{Arr_2}}(\\zeta)\\cdot r) - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly_{Arr_2}}(\\zeta)\\cdot r) - \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(\\zeta)}{\\zeta^\\kappa - 1}(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly_{Arr_2}}(\\zeta)\\cdot r) - (\\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly_{Arr_2}}(\\zeta)) \\cdot r)$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\\kappa -1$. This is true if $\\mathsf{Poly_{Vanish}}(\\zeta)$ is vanishing on $\\mathcal{H}_\\kappa$, i.e. if $(\\mathsf{Poly}_\\mathsf{Arr_3}(X) - (\\mathsf{Poly}_\\mathsf{Arr_1}(X) + \\mathsf{Poly_{Arr_2}}(X)) \\cdot r) = 0 \\space \\forall X \\in \\mathcal{H}_\\kappa$. This is true if if $\\mathsf{Arr}_3 - (\\mathsf{Arr}_1 + \\mathsf{Arr}_2 \\cdot r) = 0 \\space \\forall i \\in [0, \\kappa - 1]$, since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$. But this is precisely the condition we assumed held for our prover, so the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and the transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$, the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_3}(X)$ , $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_3}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Arr_3}[i] \\neq \\mathsf{Arr_1}[i] + \\mathsf{Arr_1}[i]\\cdot r$ for some $i \\in [0, n-1]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, there must be some $i \\in [0, n-1]$ such that $\\mathsf{Arr_3}[i] \\neq \\mathsf{Arr_1}[i] + \\mathsf{Arr_1}[i]\\cdot r$. But then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly_{Arr_2}}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_3}(X)$. All commitments $\\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)$, $\\mathsf{Poly_{Arr_2}}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta)$ can each only feasibly be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}} {(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, $\\mathsf{Poly_{Arr_2}}(\\tau)$, and ${\\mathsf{Poly}_\\mathsf{Arr_3}(\\tau)}$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, and $g^{\\mathsf{Poly}_\\mathsf{Arr_3}(\\tau)}$ to write as the commitments $ K_\\mathsf{Arr_1}$, $ K_\\mathsf{Arr_2}$ and $K_\\mathsf{Arr_3}$. $\\mathcal{S}$ computes $Q(\\tau)$ using the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, and ${\\mathsf{Poly}_\\mathsf{Arr_3}(\\tau)}$. $\\mathcal{S}$ writes the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)}$, and ${\\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta)}$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":8,"href":"/docs/gadgets/folding/","title":"Folding","section":"Gadgets","content":" Folding (Sangria) # The following document is heavily based on the Sangria techincal note and its condensed form.\nIntuition # Given a PLONK circuit, and two private input/public input pairs, we want to reduce the work of checking each of these individually to the work of checking one such relation a single time. This is called folding, and the model we explain here for Plonk, specifically, is called Sangria. Before we get into folding, though, let\u0026rsquo;s review how a PLONK circuit works.\nIn circuit we look at how a circuit with a single gate works, but now we generalize to multi-gate circuits. Here we have vectors $\\mathsf{L}$, $\\mathsf{R}$, $\\mathsf{O}$ $\\in \\mathbb{F}^{s + n +1}$ representing the right and left input, and the output, of each gate, where $n$ is the number of public inputs and $s$ is the number of gates. The $+1$ is an extra row to check the final result, i.e. if the circuit is satisfied. Together, $(\\mathsf{L}, \\mathsf{R}, \\mathsf{O})$ is called the computational trace. These three vectors are divided into $X$, the public inputs, and $W$, the private inputs, or witness. A PLONK proof will show that a public input/private input pair $(X, W)$ satisfies a circuit defined by the tuple $(\\mathsf{Q}, \\mathsf{S})$, where $\\mathsf{Q}$ is the set of selector vectors, and $\\mathsf{S}$ is the set of copy contraints. A circuit being satisfied means that the copy constraints are satisfied, and that each gate is satisfied. The $i^{th}$ gate of the circuit is defined as ${q_L}_i \\cdot l_i + {q_R}_i \\cdot r_i + {q_O}_i \\cdot o_i + {q_M}_i \\cdot l_i \\cdot r_i + {q_c}_i$ where ${q_L}_i, {q_R}_i, {q_O}_i, {q_M}_i, {q_c}_i$ are the $i^{th}$ values of each selector vector, and $l_i, r_i, o_i$ are the $i^{th}$ values of $\\mathsf{L}$, $\\mathsf{R}$, and $\\mathsf{O}$.\nNow, we turn to folding. Say we want to combine the checks for two private input/public input pairs, $(X', W')$ and $(X'', W'')$. We start by trying the most direct appraoch to reducing our two checks down to one: let\u0026rsquo;s take a random linear combination of $(X', W')$ and $(X'', W'')$, and perform the check on it. Then our new private input/public input pair would be $(X, W) := (X' + sX'', W' + sW'')$. We consider this as input to the circuit: $C_{Q,i}(\\mathsf{L}, \\mathsf{R}, \\mathsf{O})$ $= C_{Q,i}(\\mathsf{L}' + s\\mathsf{L}'', \\mathsf{R}' + s\\mathsf{R,}'', \\mathsf{O} + s\\mathsf{O}'')$\n$= {q_L}_i \\cdot (l_{i}' + sl_{i}'' ) + {q_R}_i \\cdot (r_{i}' + sr_{i}'') + {q_O}_i \\cdot (o_{i}' + so_{i}'') + {q_M}_i \\cdot (l_{i}' + s1_{i}'') (r_{i}' + sr_{i}'') + {q_C}_i$\n$= {q_L}_i \\cdot l_{i}' + {q_L}_i \\cdot sl_{i}'' + {q_R}_i \\cdot r_{i}' + {q_R}_i \\cdot sr_{i}'' + {q_O}_i \\cdot o_{i}' + {q_O}_i \\cdot so_{i}'' + {q_M}_i \\cdot (l_{i}'+ s1_{i}'') (r_{i}' + sr_{i}'') + {q_C}_i$\n$\\neq C_{Q,i}(\\mathsf{L}', \\mathsf{R}', \\mathsf{O}')+ C_{Q,i}(\\mathsf{L}'', \\mathsf{R}'', \\mathsf{O}'')$\nWe note the result is no longer of the correct form for a PLONK circuit. We end up with an undesirable crossterms, an $s^2$ in front of at least part of $C_{Q,i}(\\mathsf{L}'', \\mathsf{R}'', \\mathsf{O}'')$, and if we want to claim $C_{Q,i}(\\mathsf{L}, \\mathsf{R}, \\mathsf{O}) = C_{Q,i}(\\mathsf{L}', \\mathsf{R}', \\mathsf{O}')+ C_{Q,i}(\\mathsf{L}'', \\mathsf{R}'', \\mathsf{O}'')$, it simply isn\u0026rsquo;t true. This motivates us to define relaxed PLONK gate equations, which will allow us to deal with these issues. Copy constraints are defined the same in relaxed PLONK, but we defined our gates somewhat differently.\nHere, the $i^{th}$ gate is defined as $u({q_L}_i \\cdot l_i + {q_R}_i \\cdot r_i + {q_O}_i \\cdot o_i) + {q_M}_i \\cdot l_i \\cdot r_i + u^2({q_c}_i) + e_i$ where $u$ is a scalar and $e_i$ is the $i^{th}$ entry in the \u0026ldquo;slack vector\u0026rdquo; $\\mathsf{E}$. We now have $(\\mathsf{L}, \\mathsf{R}, \\mathsf{O}, u, \\mathsf{E})$ as the computational trace. We must also define our public input/private input pair differently, namely for the regular PLONK pair $(X, W)$ we define the relaxed PLONK pair $(U, V)$ as:\n$U := (X, u, \\overline W_l, \\overline W_r, \\overline W_o, \\overline E)$\n$V:= (W, \\mathsf{E}, r_l, r_r, r_o, r_e)$\nWhere $\\overline W_l = \\mathsf{com}(w_l, r_l)$, $\\overline W_r = \\mathsf{com}(w_r, r_r)$, $\\overline W_o = \\mathsf{com}(w_o, r_o)$, $\\overline E = \\mathsf{com}(\\mathsf{E}, r_e)$. For each of these commitments (and elsewhere in this document) the public parameters are including implicitly for cleaner notation.\nWe define the relaxed PLONK gate equation as:\n$C'_{Q,i}= (u) \\cdot [{q_L}_i \\cdot l + {q_R}_i \\cdot r + {q_O}_i \\cdot o] + {q_M}_i \\cdot l r + u^2{q_C}_i + e_i$\nNote that regular PLONK relation can be represented as a relaxed PLONK relation simply by setting $u=1$ and $\\mathsf{E}=\\vec{0}$.\nProtocol Details # Now, we once again try the random linear combination approach, this time with relaxed PLONK gate equations. The verifier is given the verifier key, and the two sets of public inputs $(X', u', \\overline W_l', \\overline W_r', \\overline W_o', \\overline E')$ and $(X'', u'', \\overline W_l'', \\overline W_r'', \\overline W_o'', \\overline E'')$. The prover has the prover key and both sets of corresponding private inputs: $(W', \\mathsf{E}', r_l', r_r', r_o', r_e')$ and $(W'', \\mathsf{E}'', r_l'', r_r'', r_o'', r_e'')$. The protocol (which is a public-coin folding scheme) proceeds as follows:\n$\\mathcal{P}$ computes $\\mathsf{T}= u''(q_L \\circ l' + q_R \\circ r' + q_O \\circ o') + u'(q_L \\circ l'' + q_R \\circ r'' + q_O \\circ o'') + q_M \\circ (l' \\circ r'' + l'' \\circ r') + 2u'u''q_C$ where $\\circ$ denotes element-wise multiplication. This $t$ is used to account for the crossterms. $\\mathcal{P}$ samples a random $r_T$ sends $\\overline T = \\mathsf{com}(\\mathsf{T}, r_T)$. $\\mathcal{V}$ samples a random challenge $r$ and sends it. $\\mathcal{P}$ and $\\mathcal{V}$ output the folded public input $(X, u, \\overline W_l, \\overline W_r, \\overline W_o, \\overline E)$, computed as: $\\quad X = X' + sX''$\n$\\quad u = u' + su''$\n$\\quad \\overline W_l = \\overline W_l' +s\\overline W_l''$\n$\\quad \\overline W_r = \\overline W_r' +s\\overline W_r''$\n$\\quad \\overline W_o = \\overline W_o' +s\\overline W_o''$\n$\\quad \\overline E = \\overline E' -s\\overline T + s^2 \\overline E''$\n$\\mathcal{P}$ outputs the folded private input $(W, \\mathsf{E}, r_l, r_r, r_o, r_e)$, computed as: $\\quad W = W' + sW''$\n$\\quad r_l = r_l' +sr_l''$\n$\\quad r_r = r_r' +sr_r''$\n$\\quad r_o = r_o' +sr_o''$\n$\\quad \\mathsf{E} = \\mathsf{E}' - s\\mathsf{T} + s^2 \\mathsf{E}''$\n$\\quad r_e = r_e' - sr_T + s^2r_e''$\nThe resulting public and private inputs constitute a new PLONK pair $(U, V)$ which is the folding of the two input pairs. The protocol can be made non-interactive via Fiat-Shamir.\nSecurity Proof # Completeness # To show completeness, we observe that $C'_{Q,i}(\\mathsf{L}, \\mathsf{R}, \\mathsf{O}, u, \\mathsf{E})$\n$= C'_{Q,i}(\\mathsf{L}' + s\\mathsf{L}'', \\mathsf{R}' + s\\mathsf{R}'', \\mathsf{O}' + s\\mathsf{O}'', u' + u'', \\mathsf{E}' -s\\mathsf{T} + s^2\\mathsf{E}'')$\n$= (u' + su'') \\cdot [{q_L}_i \\cdot (l_i' + sl_i'') + {q_R}_i \\cdot (r_i' + sr_i'') + {q_O}_i \\cdot (o_i' +so_i'')] + {q_M}_i \\cdot (l_i' + sl_i'') (r_i' + sr_i'') + (u' + su'')^2{q_C}_i + e'_i -st_i + s^2 e''_i$\n$= u'(q_{L_i} \\cdot l_i' + q_{R_i} \\cdot r_i' + q_{O_i} \\cdot o_i' + q_{M_i} \\cdot l_i' \\cdot r_i' + u' \\cdot q_{C_i}) + e'_i + u'' \\cdot s^2(q_{L_i} \\cdot l_i'' + q_{R_i} \\cdot r_i'' + q_{O_i} \\cdot o_i'' + q_{M_i} \\cdot l_i'' \\cdot r_i'' + u'' \\cdot q_{C_i}) + s^2 e''_i \\newline + u''(q_{L_i} \\cdot l_i' + q_{R_i} \\cdot r_i' + q_{O_i} \\cdot oi') + u'(q_{L_i} \\cdot li'' + q_{R_i} \\cdot r_i'' + q_{O_i} \\cdot o_i'') + q_{M_i} \\cdot (l_i' \\cdot r_i'' + l_i'' \\cdot r_i') + 2u'u''q_{C_i} - st_i$\n$= u'(q_{L_i} \\cdot l_i' + q_{R_i} \\cdot r_i' + q_{O_i} \\cdot o_i' + q_{M_i} \\cdot l_i' \\cdot r_i' + u' \\cdot q_{C_i}) + e'_i + u'' \\cdot s^2(q_{L_i} \\cdot l_i'' + q_{R_i} \\cdot r_i'' + q_{O_i} \\cdot o_i'' + q_{M_i} \\cdot l_i'' \\cdot r_i'' + u'' \\cdot q_{C_i}) + s^2 e''_i$\n$ = C'_{Q,i}(\\mathsf{L}', \\mathsf{R}', \\mathsf{O}', u, \\mathsf{E}') + s^2 \\cdot C'_{Q,i}(\\mathsf{L}'', \\mathsf{R}'', \\mathsf{O}'', u, \\mathsf{E}'')$\nSo following the steps of the protocol above provides a folding that satisfies completeness.\nSoundness # The proof for soundness is rather involved, so we provide the intuition for it here, and the technical note for Sangria provides the proof in full. We rely on the fact that a binding commitment is used.\nFirst, we apply the forking lemma for folding (Nova paper lemma 1), to obtain three transcripts. We then show that, using all three transcripts, the extractor can interpolate the values of $\\mathsf{E}', r_e', \\mathsf{E}'', r_e''$. It can also interpolate $(W', r_l', r_r', r_o')$ and $(W'', r_l'', r_r'', r_o'')$ using any two of the transcripts. Finally, we show that the traces these values belong to satisfy the copy constraints and the equality for each gate.\nZero-Knowledge # The proof relies on the fact that the commitment used is hiding, then the only message sent by the prover is a hiding commitment, which means the proof is relatively short and straight forward. We define a simulator, $\\mathcal{S}$, which samples a random vector $\\mathsf{T}$ from $\\mathbb{F}^{n + s +1}$ and a random scalar $r_T$ from $\\mathbb{F}$. From these, it produces the commitment $\\overline T = \\mathsf{com}(\\mathsf{T}, r_T)$. It then generates a random challenge $r$, and uses this $r$ and $\\overline T$ to output the transcript. Since the commitment is hiding, this is computationally indistinguishable from a real transcript.\n"},{"id":9,"href":"/docs/gadgets/lookup1/","title":"Lookup1","section":"Gadgets","content":" Lookup (Type 1) # Recap of types # Type Description Recap This lookup1 $\\mathsf{Arr}[i]\\in \\{0,1\\}$ Each element of array $\\mathsf{Arr}$ is in $\\{0,1\\}$ (or another small set). ✅ lookup2 $\\mathsf{Arr}[i]\\in \\mathsf{Table}$ Each element of array $\\mathsf{Arr}$ is in a disclosed table of values $\\mathsf{Table}$. Relation # $ \\mathcal{R}_{\\mathtt{lookup1}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}], \\\\ \\mathsf{Poly}_\\mathsf{Arr}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}), \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds an array $\\mathsf{Arr}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that each element in $\\mathsf{Arr}$ is in $\\{0,1\\}$ (or another small set). The prover will encode $\\mathsf{Arr}$ into the polynomial $\\mathsf{Poly}_\\mathsf{Arr}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$). It will commit to the polynomial: $K_\\mathsf{Arr}$. The verifier ($\\mathcal{V}$) cannot check any of the $\\mathsf{Arr}$ values directly (they may contain secret information, and even if they do not, they are too long to check) so the verifier only sees $K_\\mathsf{Arr}$.\nIn order to check that each element of $\\mathsf{Arr}$ is either 0 or 1, consider the expression $\\mathsf{Arr}[i] \\cdot (\\mathsf{Arr}[i] - 1)$. If $\\mathsf{Arr}[i]$ is 0, then the first part of the product is zero, and if $\\mathsf{Arr}[i]$ is 1, then the second part of the product is zero. If $\\mathsf{Arr}[i]$ is not 0 or 1, then the expression will be non-zero. Thus, to check our condition, it suffices to check that $\\mathsf{Arr}[i] \\cdot (\\mathsf{Arr}[i] - 1) = 0$ for $i$ from 0 to $n-1$.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers ($a_i \\in \\mathbb{Z}_q$) Polynomial Level # We assume that $\\mathsf{Arr}$ is encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 0 or 1.\nRecall the constraint we want to prove:\n$\\mathsf{Arr}[i] \\cdot (\\mathsf{Arr}[i] - 1) = 0$ for $i$ from 0 to $n-1$ We write our constraint in polynomial form and label it:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Vanish}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(X) - 1) =0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(X)}{X^\\kappa - 1}$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$ Ultimately the lookup1 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X))$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish}=\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) - 1)$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}$ such that $\\mathsf{Arr}[i] \\in \\{0, 1\\} \\forall 0 \\leq i \\leq n$, can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$ = \\mathsf{Poly}_\\mathsf{Arr}(\\zeta) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) - 1) - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$ = \\mathsf{Poly}_\\mathsf{Arr}(\\zeta) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) - 1) - \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(\\zeta)}{\\zeta^\\kappa - 1}\\cdot (\\zeta^\\kappa - 1)$\n$ = \\mathsf{Poly}_\\mathsf{Arr}(\\zeta) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) - 1) - [\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) - 1)]$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\\kappa -1$. This is true if $\\mathsf{Poly_{Vanish}}(\\zeta)$ is vanishing on $\\mathcal{H}_\\kappa$, i.e. if $\\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(X) - 1) = 0 \\space \\forall X \\in \\mathcal{H}_\\kappa$. This is true if $\\mathsf{Arr}[i] \\cdot (\\mathsf{Arr}[i] - 1) = 0 \\space \\forall i \\in [0, \\kappa -1]$, since $\\mathsf{Poly}(\\omega^i) = \\mathsf{Arr}[i] \\space \\forall i \\in [0, \\kappa - 1]$. But this is precisely the condition we assumed held for the prover (since the array gets padded with $1$\u0026rsquo;s or $0$\u0026rsquo;s if $n \\lt \\kappa$), so the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and the transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $Q(X)$.\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Arr}[i]\\neq 0$ and $\\mathsf{Arr}[i]\\neq 1$ for some $i \\in [0, n-1]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, there must be at least one entry is $\\mathsf{Arr}$ that is not 0 or 1. But then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes a commitment to $\\mathsf{Poly}_\\mathsf{Arr}(X)$. Both commitments $\\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)$, can only feasibly be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1}}{(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses an arbitrary value for ${\\mathsf{Poly}_\\mathsf{Arr}(\\tau)}$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr}(\\tau)}$ to write as the commitment $ K_\\mathsf{Arr}$. $\\mathcal{S}$ then generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the value it chose for ${\\mathsf{Poly}_\\mathsf{Arr}(\\tau)}$. $\\mathcal{S}$ writes the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the second random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)}$, to an arbitrary value. This is done using the knowledge of $\\tau$, calculating the witness polynomial $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":10,"href":"/docs/gadgets/lookup2/","title":"Lookup2","section":"Gadgets","content":" Lookup (Type 2) # Recap of types # Type Description Recap This lookup1 $\\mathsf{Arr}[i]\\in \\{0,1\\}$ Each element of array $\\mathsf{Arr}$ is in $\\{0,1\\}$ (or another small set). lookup2 $\\mathsf{Arr}[i]\\in \\mathsf{Table}$ Each element of array $\\mathsf{Arr}$ is in a disclosed table of values $\\mathsf{Table}$. ✅ Relation # $ \\mathcal{R}_{\\mathtt{lookup2}} := \\left\\{ \\begin{array}{l} (\\mathsf{Arr},\\mathsf{T}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr}[i]\\in\\mathsf{T}, 0\\leq i \\leq n-1, \\\\ \\mathsf{Poly}_\\mathsf{Arr}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}), \\\\ \\mathsf{Poly}_\\mathsf{T}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{T}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}), \\\\ K_\\mathsf{T}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T}), \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds an array $\\mathsf{Arr}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that each value in $\\mathsf{Arr}$ is the element of a public table $\\mathsf{T}$. The prover will encode $\\mathsf{Arr}$ and $\\mathsf{T}$ into polynomials: $\\mathsf{Poly}_\\mathsf{Arr}$ and $\\mathsf{Poly}_\\mathsf{T}$. Assume $\\mathsf{Arr}$ is equal to $\\mathsf{T}$, then the prover can complete the proof by simply performing the product check or the permutation check between $\\mathsf{Arr}$ and $\\mathsf{T}$. However, if $\\mathsf{Arr}$ is not equal to $\\mathsf{T}$ (this is the case we want to solve), the prover needs to reveal the points where $\\mathsf{Arr}$ equals to $\\mathsf{T}$, which makes zero knowledge impossible. Thus, the prover needs to construct auxiliary polynomial(s) to prove the constraints between $\\mathsf{Arr}$ and $\\mathsf{T}$ are desired.\nThere are different approaches to achieving the lookup argument, e.g., halo2 and Plookup. We will discuss these two approaches as follows.\nhalo2 # The lookup argument in halo2 requires the prover to construct two auxiliary vectors, $\\mathsf{Arr}^\\prime$ and $\\mathsf{T}^\\prime$, where $\\mathsf{Arr}^\\prime$ is the permutation of $\\mathsf{Arr}$ and sorted (ascending or descending does not matter), $\\mathsf{T}^\\prime$ is the permutation of $\\mathsf{T}$ and sorted by $\\mathsf{Arr}$. For any two sets $A,B$ such that $A\\subset{B}$, we say $B$ is sorted by $A$ when the elements in $A$ have the same order as they do in $B$. Let us demonstrate the halo2 lookup argument with a concrete example, $\\mathsf{Arr}=\\{1,2,1,6,4,5,3,0\\},\\mathsf{T}=\\mathbb{Z}_8$. The prover constructs $\\mathsf{Arr}^\\prime$ and $\\mathsf{T}^\\prime$ such that $$ \\mathsf{Arr}^\\prime=\\{0,1,1,2,3,4,5,6\\} $$ $$ \\mathsf{T}^\\prime=\\{0,1,7,2,3,4,5,6\\} $$ We can observe that $\\mathsf{Arr}^\\prime[i]$ is equal to $\\mathsf{T}^\\prime[i]$ or $\\mathsf{Arr}^\\prime[i-1]$. Since $\\mathsf{Arr}^\\prime[i-1]$ does not exist when $i=0$, we have to enforce the other rule, $\\mathsf{Arr}^\\prime[0]=\\mathsf{T}^\\prime[0]$. With these two constraints and the proof that $\\mathsf{Arr}^\\prime$ is the permutation of $\\mathsf{Arr}$ and $\\mathsf{T}^\\prime$ is the permutation of $\\mathsf{T}$, the prover can prove each element in $\\mathsf{Arr}$ exists in $\\mathsf{T}$.\nPlookup # We start with an unoptimized version of Plookup that is conceptually simpler than the final version and is still fully succinct. The inputs are: an array containing the values of the lookup table $\\mathsf{T}$ of size $n_1$; and an array of length $n_2$ (typically longer than $n_1$ but not necessarily) that will be proven to contain only values from somewhere in $\\mathsf{T}$.\nThe prover will create 5 helper arrays ($\\mathsf{Acc_1}$ to $\\mathsf{Acc_5}$) to demonstrate this overall property ($\\mathsf{Arr}[i]\\in\\mathsf{T}$ for all $i$). The helper arrays will each be of size $n_1+n_2$ with the exception of $\\mathsf{Acc_4}$ which is $n_2$. They are as follows:\n$\\mathsf{Acc_1}=\\mathsf{Arr}||\\mathsf{T}$ $\\mathsf{Acc_2}=\\mathtt{Sort}(\\mathsf{Acc_1})$ $\\mathsf{Acc_3}[i]=\\mathsf{Acc_2}[i+1]-\\mathsf{Acc_2}[i]$ $\\mathsf{Acc_4}[i]=\\mathsf{T}[i+1]-\\mathsf{T}[i]$ $\\mathsf{Acc_5}=\\mathsf{Acc_4}||\\{0\\}^{n_2}$ where $n_1=|\\mathsf{Arr}|$ It is probably worth an example at this point.\n$\\mathsf{T}=[7,0,15,3]$ $\\mathsf{Arr}=[7,0,15,15,7,7,15,0,0,7,15,7]$ $\\mathsf{Acc_1}=[7,0,15,15,7,7,15,0,0,7,15,7,7,0,15,3]$ $\\mathsf{Acc_2}=[7,7,7,7,7,7,0,0,0,0,15,15,15,15,15,3]$ $\\mathsf{Acc_3}=[0,0,0,0,0,-7,0,0,0,15,0,0,0,0,-12,\\bot]$ $\\mathsf{Acc_4}=[-7,15,-12,\\bot]$ $\\mathsf{Acc_5}=[-7,15,-12,\\bot,0,0,0,0,0,0,0,0,0,0,0,0]$ The first array $\\mathsf{Acc_1}$ is the concatenation for $\\mathsf{Arr}$ and $\\mathsf{T}$. The intuition for this is as follows. Every element of $\\mathsf{Arr}$ is in $\\mathsf{T}$ (what is being proven) but the converse is not true, not every element of $\\mathsf{T}$ is necessarily in $\\mathsf{Arr}$. By constructing $\\mathsf{Acc_1}$, the prover has an array where every element of $\\mathsf{T}$ appears at least once. This will be convenient later. Additionally, if the prover can show every element in $\\mathsf{Acc_1}$ is in $\\mathsf{T}$, it implies every element in the original $\\mathsf{Arr}$ is in $\\mathsf{T}$ so it can now move forward with $\\mathsf{Acc_1}$.\nHow does $\\mathsf{Acc_1}$ compare to $\\mathsf{T}$? They both have the same elements but $\\mathsf{Acc_1}$ has a bunch of extra duplicates of values. Also the appearance of elements in $\\mathsf{Acc_1}$ are in a different (arbitrary) order. Next the prover will sort the values of $\\mathsf{Acc_1}$, grouping all duplicates together, and having them appear in the same order as the original $\\mathsf{T}$ (which does not have to be sorted).\nNow how does $\\mathsf{Acc_2}$ compare to $\\mathsf{T}$? They have the same elements in the same order (including 3 which is not in the original $\\mathsf{Arr}$) however $\\mathsf{Acc_2}$ has a bunch of duplicates of some of the elements. Next we want to \u0026ldquo;flag\u0026rdquo; all the elements that are duplicates. The way we do this is to take the difference between each neighbouring elements. If the neighbouring elements are the same (duplicates), this is will place a 0 in that position. If they are not, a non-zero number will appear instead.\nThis is straight-forward until we hit the last element in $\\mathsf{Acc_2}$ and $\\mathsf{Acc_3}$ which has no \u0026ldquo;next\u0026rdquo; element in the array. We will leave it for now as an arbitrary integer $\\bot$.\nWe have marked the duplicates elements but have some other integers when neighbouring elements are not the same. The idea is do the same thing with $\\mathsf{T}$ and we create $\\mathsf{Acc_4}$, which we then pad with $n_2$ zeros.\n$\\mathsf{Acc_5}=[-7,15,-12,\\bot,0,0,0,0,0,0,0,0,0,0,0,0]$ If $\\mathsf{Acc_5}$ is a permutation of $\\mathsf{Acc_3}$ and everything else is correctly constructed, then all elements in $\\mathsf{Arr}$ are from $\\mathsf{T}$.\nThe prover will show that $\\mathsf{Acc_1}$ is constructed correctly with the $\\mathtt{concat}$ gadget. It will not prove that $\\mathsf{Acc_2}$ is sorted correctly (if it does not sort it correctly, the protocol will not work) but it will prove that $\\mathsf{Acc_2}$ is a permutation of $\\mathsf{Acc_1}$ using $\\mathtt{shuffle1}(\\mathsf{Acc_1},\\mathsf{Acc_2})$. It will prove $\\mathsf{Acc_3}$ is constructed correctly by $\\mathsf{add1}(\\mathsf{Acc_2}[i+1],-\\mathsf{Acc_2}[i])$ and $\\mathsf{Acc_3}$ is $\\mathsf{add1}(\\mathsf{T}[i+1],-\\mathsf{T}[i])$. Last, it will prove that $\\mathsf{Acc_5}$ is correctly formed with $\\mathtt{concat}$ and finally, that it is a permutation of $\\mathsf{Acc_3}$ with $\\mathtt{shuffle1}(\\mathsf{Acc_5},\\mathsf{Acc_3})$.\n$\\mathsf{T}$ to the end of $\\mathsf{Arr}$ does not change anything about the argument\nIn fact, the only difference between $\\mathsf{Acc_1}$ and $\\mathsf{T}$ itself is that there are several duplicates\nWith these arrays, the following constraints are demonstrated:\nUses $\\mathtt{concat}$ gadget Uses $\\mathtt{shuffle1}(\\mathsf{Acc_1},\\mathsf{Acc_2})$ Uses $\\mathsf{add1}(\\mathsf{Acc_2}[i+1],-\\mathsf{Acc_2}[i])$ Uses $\\mathsf{add1}(\\mathsf{T}[i+1],-\\mathsf{T}[i])$ Uses $\\mathtt{concat}$ and then $\\mathtt{shuffle1}(\\mathsf{Acc_5},\\mathsf{Acc_3})$ Unlike halo2, Plookup requires only one auxiliary vector, $\\mathsf{S}$, where $\\mathsf{S}$ is the union set of $\\mathsf{Arr}$ and $\\mathsf{T}$, and sorted by $\\mathsf{T}$. The prover encodes $\\mathsf{Arr}$, $\\mathsf{T}$, and $\\mathsf{S}$ into polynomials: $\\mathsf{Poly}_\\mathsf{Arr}$, $\\mathsf{Poly}_\\mathsf{T}$, and $\\mathsf{Poly}_\\mathsf{S}$, and computes $\\prod{\\mathsf{Poly}_\\mathsf{Arr}\\cdot\\prod\\mathsf{Poly}_\\mathsf{T}}$ and $\\prod{\\mathsf{Poly}_\\mathsf{S}}$ with some random challenges. The theorem tells us the two products are equal if and only if: $\\mathsf{Arr}\\subset\\mathsf{T}$, and $\\mathsf{S}=(\\mathsf{Arr},\\mathsf{T})$ and sorted by $\\mathsf{T}$.\nProtocol Details # halo2 # Array Level # $\\mathcal{P}$ and $\\mathcal{V}$ are given a public table $\\mathsf{T}$ $\\mathcal{P}$ holds an array $\\mathsf{Arr}=[a_0,a_1,a_2,\\dots,a_{n-1}]$ of $n$ integers ($a_i\\in\\mathbb{Z}_q$) $\\mathcal{P}$ computes an array $\\mathsf{Arr}^\\prime=[a_0^\\prime,a_1^\\prime,a_2^\\prime,\\dots,a_{n-1}^\\prime]$ of $n$ integers ($a_i^\\prime\\in\\mathbb{Z}_q$) such that: $\\mathsf{Arr}^\\prime$ is a permutation of $\\mathsf{Arr}$ and sorted in ascending or descending $\\mathcal{P}$ computes an array $\\mathsf{T}^\\prime$ such that: $\\mathsf{T}^\\prime$ is a permutation of $\\mathsf{T}$ and sorted by $\\mathsf{Arr}^\\prime$ $\\mathsf{Arr}^\\prime$ and $\\mathsf{T}^\\prime$ have the following relations: $\\mathsf{Arr}^\\prime[0]=\\mathsf{T}^\\prime[0]$ $\\mathsf{Arr}^\\prime[i]=\\mathsf{T}^\\prime[i]\\mid\\mathsf{Arr}^\\prime[i-1],i\\ne{0}$ Polynomial Level # We assume arrays $\\mathsf{Arr}$, $\\mathsf{Arr}^\\prime$, $\\mathsf{T}$, and $\\mathsf{T}^\\prime$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product).\nRecall the four constraints we want to prove:\n$\\mathsf{Arr}^\\prime$ is a permutation of $\\mathsf{Arr}$ $\\mathsf{T}^\\prime$ is a permutation of $\\mathsf{T}$ The first value in $\\mathsf{Arr}^\\prime$ equals to the first value in $\\mathsf{T}^\\prime$ The rest of the values in $\\mathsf{Arr}^\\prime$ are of the form $\\mathsf{Arr}^\\prime[i]=\\mathsf{T}^\\prime[i]\\mid\\mathsf{Arr}^\\prime[i-1],i\\ne{0}$ In polynomial form, the constraints are ($\\alpha,\\beta$ are challenges from $\\mathcal{V}$):\n$\\prod[\\alpha-\\mathsf{Poly}_{\\mathsf{Arr}}(X)]=\\prod[\\alpha-\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)]$ $\\prod[\\beta-\\mathsf{Poly}_{\\mathsf{T}}(X)]=\\prod[\\beta-\\mathsf{Poly}_{\\mathsf{T}^\\prime}(X)]$ For $X=\\omega^0$: $\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)=\\mathsf{Poly}_{\\mathsf{T}^\\prime}(X)$ For all $X\\in\\mathcal{H}_\\kappa\\setminus{\\omega^0}$: $[\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)-\\mathsf{Poly}_{\\mathsf{T}^\\prime}(X)]\\cdot[\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)-\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X\\cdot\\omega^{-1})]=0$ We take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=\\prod[\\alpha-\\mathsf{Poly}_{\\mathsf{Arr}}(X)]-\\prod[\\alpha-\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)]=0$ $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=\\prod[\\beta-\\mathsf{Poly}_{\\mathsf{T}}(X)]-\\prod[\\beta-\\mathsf{Poly}_{\\mathsf{T}^\\prime}(X)]=0$ $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=[\\mathsf{Poly}_{\\mathsf{Arr^\\prime}}(X)-\\mathsf{Poly}_{\\mathsf{T^\\prime}}(X)]\\cdot\\frac{X^\\kappa-1}{X-\\omega^0}=0$ $\\mathsf{Poly}_\\mathsf{Vanish4}(X)=[\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)-\\mathsf{Poly}_{\\mathsf{T}^\\prime}(X)]\\cdot[\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)-\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X\\cdot\\omega^{-1})]\\cdot(X-\\omega^0)=0$ Instead of proving $\\mathsf{Poly}_\\mathsf{Vanish1}$ and $\\mathsf{Poly}_\\mathsf{Vanish2}$ are vanishing through two permutation checks, we can construct an accumulator $\\mathsf{Poly}_\\mathsf{Z}$ to make it more efficient (the domain needs to be expanded to $2\\kappa$, denoted by $k$):\n$\\mathsf{Poly}_\\mathsf{Z}(\\omega^0)=\\mathsf{Poly}_\\mathsf{Z}(\\omega^{k-1})=1$ For all $X\\in\\mathcal{H}_\\kappa\\setminus{\\omega^{k-1}}$: $\\mathsf{Poly}_\\mathsf{Z}(X\\cdot\\omega)=\\mathsf{Poly}_\\mathsf{Z}(X)\\cdot\\frac{[\\mathsf{Poly}_\\mathsf{Arr}(X)+\\alpha]\\cdot[\\mathsf{Poly}_\\mathsf{T}(X)+\\beta]}{[\\mathsf{Poly}_\\mathsf{Arr^\\prime}(X)+\\alpha]\\cdot[\\mathsf{Poly}_\\mathsf{T^\\prime}(X)+\\beta]}$ Now we have the new $\\mathsf{Poly}_\\mathsf{Vanish1}$ and $\\mathsf{Poly}_\\mathsf{Vanish2}$:\n$\\mathsf{Poly}_\\mathsf{Vanish1}=[\\mathsf{Poly}_\\mathsf{Z}(X)-1]\\cdot\\frac{X^k-1}{(X-\\omega^0)\\cdot(X-\\omega^{k-1})}=0$ $\\mathsf{Poly}_\\mathsf{Vanish2}=\\{\\mathsf{Poly}_\\mathsf{Z}(X\\cdot\\omega)\\cdot[\\mathsf{Poly}_\\mathsf{Arr^\\prime}(X)+\\alpha]\\cdot[\\mathsf{Poly}_\\mathsf{T^\\prime}(X)+\\beta]-\\mathsf{Poly}_\\mathsf{Z}(X)\\cdot[\\mathsf{Poly}_\\mathsf{Arr}(X)+\\alpha]\\cdot[\\mathsf{Poly}_\\mathsf{T}(X)+\\beta]\\}\\cdot(X-\\omega^{k-1})=0$ These equations are true for every value of $X \\in \\mathcal{H}_k$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^k - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_k$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish3}(X)$, and $\\mathsf{Poly}_\\mathsf{Vanish4}(X)$ must be vanishing on $\\mathcal{H}_k$ too. Specifically, the prover computes,\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^k - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^k - 1}$ $Q_3(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^k - 1}$ $Q_4(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish4}(X)}{X^k - 1}$ Instead of proving the four polynomials are zero polynomials one by one, we can linearly combine the four polynomials with a random challenge $\\rho$ sent by $\\mathcal{V}$ to compute:\n$W(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}+\\rho^2\\cdot{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}+\\rho^3\\cdot{\\mathsf{Poly}_\\mathsf{Vanish4}(X)}=0$ When $\\mathsf{Poly}_\\mathsf{Vanish1}(X),\\mathsf{Poly}_\\mathsf{Vanish2}(X),\\mathsf{Poly}_\\mathsf{Vanish3}(X),\\mathsf{Poly}_\\mathsf{Vanish4}(X)$ are vanishing on the domain $\\mathcal{H}_k$, $W(X)$ is also vanishing with high probability. Again, if and only if $W(X)$ is vanishing over the field $\\mathcal{H}_k$, $Q(X)=W(X)/(X^k-1)$ exists.\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it): $$ \\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)+\\rho^2\\cdot\\mathsf{Poly}_\\mathsf{Vanish3}(X)+\\rho^3\\cdot\\mathsf{Poly}_\\mathsf{Vanish4}(X)-Q(X)\\cdot(X^n-1)=0 $$ Ultimately the halo2 lookup argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Z}(X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_\\mathsf{Arr^\\prime}(X)$, and $\\mathsf{Poly}_\\mathsf{T^\\prime}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is a zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) are too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Z}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Z}(X))$ $K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X))$ $K_\\mathsf{T}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T}(X))$ $K_\\mathsf{Arr^\\prime}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr^\\prime}(X))$ $K_\\mathsf{T^\\prime}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T^\\prime}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_k$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_k$. Call this point $\\zeta$. The prover will write the three points and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Z}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Z},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Z}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Z},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr^\\prime}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr^\\prime},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr^\\prime}(\\zeta\\omega^{-1})=\\mathsf{KZG.Open}(K_\\mathsf{Arr^\\prime},\\zeta\\omega^{-1})$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta)$ $\\mathsf{Poly}_\\mathsf{T^\\prime}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{T^\\prime},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}=[\\mathsf{Poly}_\\mathsf{Z}(\\zeta)-1]\\cdot\\frac{(\\zeta^k-1)}{(\\zeta-\\omega^0)\\cdot(\\zeta-\\omega^{k-1})}$ $Y_\\mathsf{Vanish2}=\\{\\mathsf{Poly}_\\mathsf{Z}(\\zeta\\omega)\\cdot[\\mathsf{Poly}_\\mathsf{Arr^\\prime}(\\zeta)+\\alpha]\\cdot[\\mathsf{Poly}_\\mathsf{T^\\prime}(\\zeta)+\\beta]-\\mathsf{Poly}_\\mathsf{Z}(\\zeta)\\cdot[\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\alpha]\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\beta]\\}\\cdot(\\zeta-\\omega^{k-1})$ $Y_\\mathsf{Vanish3}=[\\mathsf{Poly}_{\\mathsf{Arr^\\prime}}(\\zeta)-\\mathsf{Poly}_{\\mathsf{T^\\prime}}(\\zeta)]\\cdot\\frac{\\zeta^k-1}{\\zeta-\\omega^0}$ $Y_\\mathsf{Vanish4}=[\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(\\zeta)-\\mathsf{Poly}_{\\mathsf{T}^\\prime}(\\zeta)]\\cdot[\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(\\zeta)-\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(\\zeta\\omega^{-1})]\\cdot(\\zeta-\\omega^0)$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1}+\\rho\\cdot{Y_\\mathsf{Vanish2}}+\\rho^2\\cdot{Y_\\mathsf{Vanish3}}+\\rho^3\\cdot{Y_\\mathsf{Vanish4}}-Q(\\zeta)\\cdot(\\zeta^k - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Plookup # Array Level # $\\mathcal{P}$ and $\\mathcal{V}$ are given a public table $\\mathsf{T}=[t_0,t_1,t_2,\\dots,t_{d-1}]$ of $d$ integers ($t_i\\in\\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr}=[a_0,a_1,a_2,\\dots,a_{n-1}]$ of $n$ integers ($a_i\\in\\mathbb{Z}_q$) $\\mathcal{P}$ constructs an array $\\mathsf{S}=(\\mathsf{Arr},\\mathsf{T})=[s_0,s_1,s_2,\\dots,s_{n+d-1}]$ of $n+d$ integers ($s_i\\in\\mathbb{Z}_q$) such that: $\\mathsf{S}$ is a union set of $\\mathsf{Arr}$ and $\\mathsf{T}$ $\\mathsf{S}$ is sorted by $\\mathsf{T}$ $\\mathsf{Arr}$, $\\mathsf{T}$, and $\\mathsf{S}$ have the following relations: For each $i\\in[0,d-1)$, there exists a $j\\in[0,n+d-1)$ such that $(t_i,t_{i+1})=(s_j,s_{j+1})$ Let $I$ be the set of those $d-1$ indices, and let $I^\\prime:=[0,n+d-1)\\setminus{I}$. For each $i\\in{I^\\prime}$, there exists a $j\\in[0,n)$ such that $s_i=s_{i+1}=a_{j}$ Polynomial Level # We assume arrays $\\mathsf{Arr}$, $\\mathsf{T}$, and $\\mathsf{S}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product).\nRecall the two constraints we want to prove:\nFor each $i\\in[0,d-1)$, there exists a $j\\in[0,n+d-1)$ such that $(t_i,t_{i+1})=(s_j,s_{j+1})$ Let $I$ be the set of those $d-1$ indices, and let $I^\\prime:=[0,n+d-1)\\setminus{I}$. For each $i\\in{I^\\prime}$, there exists a $j\\in[0,n)$ such that $s_i=s_{i+1}=a_{j}$ In polynomial form, the constraints are ($\\alpha,\\beta$ are challenges from $\\mathcal{V}$):\n$(1+\\beta)^n\\prod_{i\u003c{n}}[\\alpha+\\mathsf{Poly}_{\\mathsf{Arr}}(\\omega^i)]\\cdot\\prod_{i\u003c{d-1}}[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(\\omega^{i+1})]=\\prod_{i\u003c{n+d-1}}[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{S}}(\\omega^{i+1})]$ To efficiently prove the above polynomial holds, we can use a similar trick in halo2 lookup by constructing an accumulator :\n$\\mathsf{Poly}_\\mathsf{Z}(\\omega^0)=\\mathsf{Poly}_\\mathsf{Z}(\\omega^{n+d-1})=1$ For $i\\in[0,n+d-1)$: $\\mathsf{Poly}_\\mathsf{Z}(X\\omega)=\\mathsf{Poly}_\\mathsf{Z}(X)\\cdot\\frac{(1+\\beta)[\\alpha+\\mathsf{Poly}_{\\mathsf{Arr}}(X)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(X\\omega)]}{\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{S}}(X\\omega)}$ However, the above accumulator does not exist because the degree of the denominator, $\\mathsf{Poly}_\\mathsf{S}$, is different from $\\mathsf{Poly}_\\mathsf{Arr}$ and $\\mathsf{Poly}_\\mathsf{T}$. Specifically, there are $n$ elements in $\\mathsf{Arr}$, $d$ elements in $\\mathsf{T}$, but $n+d$ elements in $\\mathsf{S}$. Thus we have to decompose the denominator to make it have the same iteration as $\\mathsf{Arr}$ and $\\mathsf{T}$ do. It is worth noting for the numerator, the left term contains $\\mathsf{Poly}_\\mathsf{Arr}(X)$ while the right term contains $\\mathsf{Poly}_\\mathsf{T}(X)$ and $\\mathsf{Poly}_\\mathsf{T}(X\\omega)$. Therefore, it will be convenient to assume $d=n+1$. The order of $\\mathsf{S}$ is $2n+1$. To traverse $\\mathsf{S}$ in $n$ steps, we can halve it to $\\mathsf{S}_\\mathsf{l}=[s_0,s_1,\\dots,s_{n-1},s_n]$ and $\\mathsf{S}_\\mathsf{h}=[s_{n},s_{n+1},\\dots,s_{2n-1},s_{2n}]$, and prove $\\mathsf{S}_\\mathsf{l}[n]=\\mathsf{S}_\\mathsf{h}[0]$. Then we can compute the accumulator such that:\n$\\mathsf{Poly}_\\mathsf{Z}(\\omega^0)=\\mathsf{Poly}_\\mathsf{Z}(\\omega^{\\kappa-1})=1$ For $X\\in\\mathcal{H}_n\\setminus{\\omega^{\\kappa-1}}$: $\\mathsf{Poly}_\\mathsf{Z}(X\\omega)=\\mathsf{Poly}_\\mathsf{Z}(X)\\cdot\\frac{(1+\\beta)[\\alpha+\\mathsf{Poly}_{\\mathsf{Arr}}(X)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(X\\omega)]}{[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X\\omega)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X\\omega)]}$ For $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X)=\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X\\omega)$ Similarly, we take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=[\\mathsf{Poly}_{\\mathsf{Z}}(X)-1]\\cdot\\frac{X^n-1}{(X-\\omega^0)(X-\\omega^{\\kappa-1})}=0$ $\\displaylines{\\mathsf{Poly}_\\mathsf{Vanish2}(X)=\\{\\mathsf{Poly}_\\mathsf{Z}(X\\omega)\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X\\omega)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X\\omega)]-\\\\\\mathsf{Poly}_\\mathsf{Z}(X)\\cdot(1+\\beta)[\\alpha+\\mathsf{Poly}_{\\mathsf{Arr}}(X)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(X\\omega)]\\}\\cdot(X-\\omega^{\\kappa-1})}=0$ $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=[\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X)-\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X\\omega^{n+1})]\\cdot\\frac{X^n-1}{X-\\omega^{\\kappa-1}}=0$ These equations are true for every value of $X\\in\\mathcal{H}_n$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^n-1$, which is a minimal vanishing polynomial for $\\mathcal{H}_n$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$, and $\\mathsf{Poly}_\\mathsf{Vanish3}(X)$ must be vanishing on $\\mathcal{H}_n$ too. Specifically, the prover computes,\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^n - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^n - 1}$ $Q_3(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^n - 1}$ Instead of proving the three polynomials are zero polynomials one by one, we can linearly combine the three polynomials with a random challenge $\\rho$ sent by $\\mathcal{V}$ to compute:\n$W(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}+\\rho^2\\cdot{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}=0$ When $\\mathsf{Poly}_\\mathsf{Vanish1}(X),\\mathsf{Poly}_\\mathsf{Vanish2}(X),\\mathsf{Poly}_\\mathsf{Vanish3}(X)$ are vanishing on the domain $\\mathcal{H}_n$, $W(X)$ is also vanishing with high probability. Again, if and only if $W(X)$ is vanishing over the field $\\mathcal{H}_n$, $Q(X)=W(X)/(X^n-1)$ exists.\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_n$ and outside of it): $$ \\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)+\\rho^2\\cdot\\mathsf{Poly}_\\mathsf{Vanish3}(X)-Q(X)\\cdot(X^n-1)=0 $$ Ultimately the Plookup will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Z}(X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X)$, and $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is a zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) are too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Z}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Z}(X))$ $K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X))$ $K_\\mathsf{T}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T}(X))$ $K_{\\mathsf{S}_\\mathsf{l}}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X))$ $K_{\\mathsf{S}_\\mathsf{h}}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_n$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_n$. Call this point $\\zeta$. The prover will write the three points and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Z}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Z},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Z}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Z},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta)$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta)$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta\\omega)$ $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta)=\\mathsf{KZG.Open}(K_{\\mathsf{S}_\\mathsf{l}},\\zeta)$ $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_{\\mathsf{S}_\\mathsf{l}},\\zeta\\omega)$ $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(\\zeta)=\\mathsf{KZG.Open}(K_{\\mathsf{S}_\\mathsf{h}},\\zeta)$ $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_{\\mathsf{S}_\\mathsf{h}},\\zeta\\omega)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}=[\\mathsf{Poly}_\\mathsf{Z}(\\zeta)-1]\\cdot\\frac{(\\zeta^n-1)}{(\\zeta-\\omega^0)\\cdot(\\zeta-\\omega^{\\kappa-1})}$ $\\displaylines{Y_\\mathsf{Vanish2}=\\{\\mathsf{Poly}_\\mathsf{Z}(\\zeta\\omega)\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta)+\\beta\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta\\omega)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(\\zeta)+\\beta\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(\\zeta\\omega)]-\\\\\\mathsf{Poly}_\\mathsf{Z}(\\zeta)\\cdot(1+\\beta)[\\alpha+\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\beta\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)]\\}\\cdot(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish3}=[\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta)-\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta\\omega^{n+1})]\\cdot\\frac{\\zeta^n-1}{\\zeta-\\omega^{\\kappa-1}}$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1}+\\rho\\cdot{Y_\\mathsf{Vanish2}}+\\rho^2\\cdot{Y_\\mathsf{Vanish3}}-Q(\\zeta)\\cdot(\\zeta^k - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Security Proof # halo2 # Completeness # Any honest prover can do the computations explained above and create an accepting proof.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g,g^\\tau,g^{\\tau^2},\\dots,g^{\\tau^{n-1}}]$, $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{Arr^\\prime}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_\\mathsf{T^\\prime}(X)$, $Q$ $\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{Arr^\\prime}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_\\mathsf{T^\\prime}(X)$, $Q$ $\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$ $\\mathcal{A}$ wins if $\\mathcal{V}$ accepts at the end of the protocol For some $i\\in[0,\\kappa-1]$, $\\mathsf{Arr}[i]\\notin\\mathsf{T}$ Our proof is as follows:\nTo make $Y_\\mathsf{Zero}$ a zero polynomial, $\\mathcal{A}$ has to prove the four vanishing polynomials are correct. For $\\mathsf{Poly}_\\mathsf{Vanish1}$ and $\\mathsf{Poly}_\\mathsf{Vanish2}$, the permutation check tells us the probability that $\\mathcal{V}$ accepts the proof is negligible if some elements in $\\mathsf{Arr}$ are not in $\\mathsf{T}$. By the Schwartz-Zippel lemma, we know the probability that $\\mathsf{Poly}_\\mathsf{Vanish3}$ is vanishing is negligible if $\\mathsf{Poly}_\\mathsf{Arr^\\prime}(\\omega^0)\\ne\\mathsf{Poly}_\\mathsf{T^\\prime}(\\omega^0)$. Therefore, to win the KS game, $\\mathcal{A}$ has to prove $\\mathsf{Poly}_\\mathsf{Vanish4}$ is correct with the winning condition (some elements in $\\mathsf{Arr}$ do not appear in $\\mathsf{T}$). Assume $\\mathsf{Arr}[i^\\prime]\\notin\\mathsf{T},i\u003e0$, to make such $\\mathsf{Poly}_\\mathsf{Vanish4}$ exist, $\\mathsf{Arr}[i^\\prime]$ has to equal to $\\mathsf{Arr}[i^\\prime-1]$. And because $\\mathsf{Arr}[i^\\prime-1]\\ne{\\mathsf{T}[i^\\prime-1]}$, $\\mathsf{Arr}[i^\\prime-1]$ has to equal to $\\mathsf{Arr}[i^\\prime-2]$. Thus, to make the winning condition hold, $\\mathsf{Arr}[i^\\prime]=\\mathsf{Arr}[0]$ must hold, which contradicts to the condition of $\\mathsf{Poly}_\\mathsf{Vanish3}$, $\\mathsf{Arr}[0]=\\mathsf{T}[0]$.\nZero-Knowledge # Before we prove the above protocol is zero-knowledge, it is worth noting the protocol is different from the lookup argument of halo2 in the real world. Specifically, the real halo2 lookup optimizes the two permutation checks into one and fills the table with some random numbers for the PLONK-based proof system. We refer to the official halo2 handbook to see the details. To prove the above protocol is zero-knowledge, we do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ generates an array $\\mathsf{Arr^*}$ by randomly filling it with elements from $\\mathsf{T}$, then follows the same steps a prover would prove the lookup argument. $\\mathcal{S}$ computes $\\mathsf{Arr^{*^\\prime}},\\mathsf{T^\\prime}$ and interpolates the four arrays into their respective polynomials, $\\mathsf{Poly}_\\mathsf{Arr^*}(X)$, $\\mathsf{Poly}_\\mathsf{Arr^{*^\\prime}}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, and $\\mathsf{Poly}_\\mathsf{T^\\prime}(X)$. It computes $Q^*(X)$ and finally outputs the commitments to each of these polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta^*$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_\\mathsf{Arr^*}(\\zeta^*),\\mathsf{Poly}_\\mathsf{Arr^{*^\\prime}}(\\zeta^*),Q^*(\\zeta^*)$, $\\mathsf{Poly}_\\mathsf{T}(\\zeta^*\\omega)$, and $\\mathsf{Poly}_\\mathsf{T^\\prime}(\\zeta^*\\omega)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nPlookup # Completeness # Any honest prover can do the computations explained above and create an accepting proof.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g,g^\\tau,g^{\\tau^2},\\dots,g^{\\tau^{n-1}}]$, $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_\\mathsf{S}(X)$, $Q$ $\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_\\mathsf{S}(X)$, $Q$ $\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$ $\\mathcal{A}$ wins if $\\mathcal{V}$ accepts at the end of the protocol For some $i\\in[0,\\kappa-1]$, $\\mathsf{Arr}[i]\\notin\\mathsf{T}$ Our proof is as follows:\nTo make $Y_\\mathsf{Zero}$ a zero polynomial, $\\mathcal{A}$ has to prove the three vanishing polynomials are correct. It is easy to observe that $\\mathsf{Poly}_\\mathsf{Vanish1}$ and $\\mathsf{Poly}_\\mathsf{Vanish3}$ can be constructed even if some elements in $\\mathsf{Arr}$ do not appear in $\\mathsf{T}$, so we focus on the $\\mathsf{Poly}_\\mathsf{Vanish2}$. By the soundness of the product check, we know $\\mathsf{S}$ must be the union set of $\\mathsf{Arr}$ and $\\mathsf{T}$ if we want to the product of $\\mathsf{S}[i]$ equals to the product of $\\mathsf{Arr}[i]$ and $\\mathsf{T}[i]$. Recall the equation $\\mathcal{A}$ needs to prove: $$ (1+\\beta)^n\\prod_{i\u003c{n}}[\\alpha+\\mathsf{Poly}_{\\mathsf{Arr}}(\\omega^i)]\\cdot\\prod_{i\u003c{d-1}}[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(\\omega^{i+1})]=\\prod_{i\u003c{n+d-1}}[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{S}}(\\omega^{i+1})] $$ Thus, for each $i\\in[0,d-1]$, there exists a factor in the right-hand side of the equation equal to $\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(\\omega^{i+1})$, which means $\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(\\omega^{i+1})=\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{S}}(\\omega^{i+1})$. We can get $\\mathsf{Poly}_{\\mathsf{T}}(\\omega^i)=\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)$ and $\\mathsf{Poly}_{\\mathsf{T}}(\\omega^{i+1})=\\mathsf{Poly}_{\\mathsf{S}}(\\omega^{i+1})$ for $i\\in[0,d-1]$. Similarly, we can get $\\mathsf{Poly}_{\\mathsf{Arr}}(\\omega^i)=\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)=\\mathsf{Poly}_{\\mathsf{S}}(\\omega^{i+1})$ for $i\\in[0,n]$. Since $n$ should be equal to or less than $d$, when $\\mathsf{Poly}_{\\mathsf{Arr}}(\\omega^i)=\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)$, $\\mathsf{Poly}_{\\mathsf{T}}(\\omega^i)=\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)$ must hold at the same time, which contradicts to the winning assumption. Therefore, the protocol is sound.\nZero-Knowledge # To prove the above protocol is zero-knowledge, we do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ generates an array $\\mathsf{Arr^*}$ by randomly filling it with elements from $\\mathsf{T}$, then follows the same steps a prover would prove the lookup argument. $\\mathcal{S}$ computes $\\mathsf{S}_\\mathsf{l}$, $\\mathsf{S}_\\mathsf{h}$, and $\\mathsf{Z}$ and interpolates the five arrays into their respective polynomials, $\\mathsf{Poly}_\\mathsf{Arr^*}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X)$, $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X)$, and $\\mathsf{Poly}_{\\mathsf{Z}}(X)$. It computes $Q^*(X)$ and finally outputs the commitments to each of these polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta^*$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_\\mathsf{Arr^*}(\\zeta^*),\\mathsf{Poly}_\\mathsf{T}(\\zeta^*),\\mathsf{Poly}_\\mathsf{T}(\\zeta^*\\omega),\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta^*),\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta^*\\omega),\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(\\zeta^*),\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(\\zeta^*\\omega),Q^*(\\zeta^*),\\mathsf{Poly}_\\mathsf{Z}(\\zeta^*)$, and $\\mathsf{Poly}_\\mathsf{Z}(\\zeta^*\\omega)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":11,"href":"/docs/gadgets/mult1/","title":"Mult1","section":"Gadgets","content":" Multiplication (Type 1) # Recap of types # Type Description Recap This mult1 $\\mathsf{Arr}_3=\\mathsf{Arr}_1 \\cdot \\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the element-wise multiplication of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. ✅ mult2 $\\mathsf{Prod}_\\mathsf{Arr}=\\prod_{i = 0}^{n-1} \\mathsf{Arr}[i]$ $\\mathsf{Prod}_\\mathsf{Arr}$ is the disclosed product of all the elements in $\\mathsf{Arr}$. mult3 $\\prod_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\prod_{i = 0}^{n-1} \\mathsf{Arr}_2[i]$ $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ have the same undisclosed product. Relation # $ \\mathcal{R}_{\\mathtt{mult1}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr_2},K_\\mathsf{Arr_3}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]\\cdot\\mathsf{Arr_2}[i], 0\\leq i \\leq n-1, \\\\ \\mathsf{Poly}_\\mathsf{Arr_j}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_j}), 1\\leq j \\leq 3, \\\\ K_\\mathsf{Arr_j}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_j}), 1\\leq j \\leq 3, \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds two arrays $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that $\\mathsf{Arr_3}$ is the element-wise product of all the elements in the array: $\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]\\cdot\\mathsf{Arr_2}[i]$. The prover will encode the three arrays into three polynomials: $\\mathsf{Poly}_\\mathsf{Arr_1}$, $\\mathsf{Poly}_\\mathsf{Arr_2}$, and $\\mathsf{Poly}_\\mathsf{Arr_3}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$). It will commit to each polynomial: $K_\\mathsf{Arr_1}$, $K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$. The verifier ($\\mathcal{V}$) cannot check any of the $\\mathsf{Arr_i}$ or $\\mathsf{Poly}_\\mathsf{Arr_i}$ values directly (they may contain secret information, and even if they do not, they are too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$,$K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$.\nIn order to prove$K_\\mathsf{Arr_1}$,$K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$ are consistent, the prover will compute the difference between $(\\mathsf{Poly}_\\mathsf{Arr_1}\\cdot\\mathsf{Poly}_\\mathsf{Arr_2})$ and $(\\mathsf{Poly}_\\mathsf{Arr_3})$ using add1. Next, it will show it is 0 for each evaluation point in the domain $\\mathcal{H}_\\kappa$. Showing a polynomial is zero on the domain is a common sub-protocol used by many gadgets.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ computes or holds an array $\\mathsf{Arr_3} = [a_{(3,0)}, a_{(3,1)}, a_{(3,2)}, \\dots, a_{(3,n-1)}]$ of $n$ integers ($a_{(3,i)} \\in \\mathbb{Z}_q$) such that: $\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]\\cdot\\mathsf{Arr_2}[i]$ for $i$ from 0 to $n-1$ Polynomial Level # We assume the three arrays $\\mathsf{Arr_1}$, $\\mathsf{Arr_2}$ and $\\mathsf{Arr_3}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded.\nRecall the constraint we want to prove:\n$\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]\\cdot\\mathsf{Arr_2}[i]$ for $i$ from 0 to $n-1$ In polynomial form, the constraint is:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_3}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)\\cdot\\mathsf{Poly}_\\mathsf{Arr_2}(X)$ We adjust the constraints to show an equality with 0:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Vanish}(X)=\\mathsf{Poly}_\\mathsf{Arr_3}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X)\\cdot\\mathsf{Poly}_\\mathsf{Arr_2}(X)=0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(X)}{X^\\kappa - 1}$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$ Ultimately the mult1 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_3}(X)$. Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$\n$K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$\n$K_\\mathsf{Arr_3}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_3}(X))$\n$K_Q=\\mathsf{KZG.Commit}(Q(X))$\nThe prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$\n$\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$\n$\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$\n$\\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_3},\\zeta)$\n$Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$\nTo check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish}=\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta)$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Rust Mathematica (Toy Example) Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr_1}, \\mathsf{Arr_2}$ and $\\mathsf{Arr_3}$ such that $\\mathsf{Arr_1}[i] \\cdot \\mathsf{Arr_2}[i] - \\mathsf{Arr_3}[i] = 0 \\space \\forall i \\in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$ = Y_\\mathsf{Vanish} - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$ = \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta) - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta) - \\frac{\\mathsf{Poly_{Vanish}}(\\zeta)}{\\zeta^\\kappa - 1}\\cdot(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)+\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta))$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish}}(X)$ is vanishing on $\\mathcal{H_\\kappa}$, i.e. if $\\mathsf{Poly}_\\mathsf{Arr_1}(X) \\cdot \\mathsf{Poly}_\\mathsf{Arr_2}(X) - \\mathsf{Poly}_\\mathsf{Arr_3}(X) =0 \\space \\forall X \\in \\mathcal{H}_\\kappa$. This is true if if $\\mathsf{Arr_1}[i] \\cdot \\mathsf{Arr_2}[i] - \\mathsf{Arr_3}[i] = 0 \\space \\forall i \\in [0, \\kappa - 1]$, since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$. But $\\mathsf{Arr_1}[i] \\cdot \\mathsf{Arr_2}[i] - \\mathsf{Arr_3}[i] = 0 \\space \\forall i \\in [0, \\kappa - 1]$ is precisely the relation that we assumed held for our prover (if $\\kappa \\gt n$ then the arrays get padded such that this relation still holds), thus the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr3}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr3}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Arr}_3\\neq \\mathsf{Arr}_1 \\cdot \\mathsf{Arr}_2$\nOur proof is as follows:\nFor the second win condition to be fulfilled, the constraint must not hold for at least one index of the arrays. But then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and sends $K_Q = g^{Q(\\tau)}$. It also sends commitments to $\\mathsf{Poly}_\\mathsf{Arr1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr2}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr3}(X)$. Each commitment $\\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr2}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\zeta)$ can only feasibly be opened to one value each. For $\\mathcal{A}$ to have the verifier accept, they must send a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1}}{(\\zeta^\\kappa - 1)}$. This means being able to send $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ choose arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr2}(\\tau)}$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\tau)$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Arr2}(\\tau)}$ , and $g^{\\mathsf{Poly}_\\mathsf{Arr3}(\\tau)}$ to output as the commitments $K_\\mathsf{Arr1}$, $ K_\\mathsf{Arr2}$, and $ K_\\mathsf{Arr3}$. $\\mathcal{S}$ then generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the values they chose for ${\\mathsf{Poly}_\\mathsf{Arr1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr2}(\\tau)}$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\tau)$. $\\mathcal{S}$ outputs the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the second random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Arr2}(\\zeta)}$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\zeta)$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nFor mult2, the proof is written with a simulator that doesn\u0026rsquo;t know the trapdoor; however, with small alterations the proof for mult2 should apply here and vice versa "},{"id":12,"href":"/docs/gadgets/mult2/","title":"Mult2","section":"Gadgets","content":" Multiplication (Type 2) # Recap of types # Type Description Recap This mult1 $\\mathsf{Arr}_3=\\mathsf{Arr}_1 \\cdot \\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the element-wise multiplication of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. mult2 $\\mathsf{Prod}_\\mathsf{Arr}=\\prod_{i = 0}^{n-1} \\mathsf{Arr}[i]$ $\\mathsf{Prod}_\\mathsf{Arr}$ is the disclosed product of all the elements in $\\mathsf{Arr}$. ✅ mult3 $\\prod_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\prod_{i = 0}^{n-1} \\mathsf{Arr}_2[i]$ $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ have the same undisclosed product. Relation # $ \\mathcal{R}_{\\mathtt{mult2}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr},\\mathsf{Prod}_\\mathsf{Arr}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}], \\\\ \\mathsf{Prod}_\\mathsf{Arr} = \\prod_{i = 0}^{n-1} a_i, \\\\ \\mathsf{Poly}_\\mathsf{Arr}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}) \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds an array $\\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers (from $\\mathbb{Z}_q$) and a disclosed integer $\\mathsf{Prod}_\\mathsf{Arr}$. It will produce a succinct (independent of $n$) proof that $\\mathsf{Prod}_\\mathsf{Arr}$ is the product of all the elements in the array. The prover will encode the array into a polynomial $\\mathsf{Poly}_\\mathsf{Arr}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to the polynomial $K_\\mathsf{Arr}$. The verifier ($\\mathcal{V}$) cannot check $\\textsf{Arr}$ or $\\mathsf{Poly}_\\mathsf{Arr}$ directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr}$ and the asserted value $\\mathsf{Prod_\\mathsf{Arr}}$.\nIn order to prove $K_\\mathsf{Arr}$ and $\\mathsf{Prod}_\\mathsf{Arr}$ are consistent, the prover will build a helper array $\\mathsf{Acc}_\\mathsf{Arr}$ called an accumulator (or accumulating array or incremental array). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\\mathsf{Arr}$, the prover will also encode $\\mathsf{Acc}$ as a polynomial and provide a commitment of it to the verifier. The idea is that the prover will prove a relation between $\\mathsf{Arr}$ and $\\mathsf{Acc}$; and a relation between $\\mathsf{Acc}$ and $\\mathsf{Prod_\\mathsf{Arr}}$. Put together, it will imply the correct relation between $\\mathsf{Arr}$ and $\\mathsf{Prod_\\mathsf{Arr}}$.\nConsider a small numeric example in $\\mathbb{Z}_{97}$ where $\\mathsf{Arr}= [84,67,11,92,36,67]$ and $\\mathsf{Prod}_\\mathsf{Arr}=72$. The first idea is to get $\\mathsf{Prod}_\\mathsf{Arr}$ into an array. Say, we just append it: $\\mathsf{Arr}''= [84,67,11,92,36,67,72] $. How does the prover show $\\mathsf{Arr}''$ is correct? The last value of the array depends on every single element that precedes it, which will be a complex constraint to prove.\nAn alternative idea is to create a new array that starts the same as $\\mathsf{Arr}$ and ends up at $\\mathsf{Prod}_\\mathsf{Arr}$ by folding in the integers from $\\mathsf{Arr}$ one-by-one with multiplication. Then each value in the new array will depend on only two values, as below.\nThe first value in $\\mathsf{Acc}$ will be a copy of the first value from $\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$\\mathsf{Acc}= [84, \\bot,\\bot,\\bot,\\bot,\\bot] $\nThe next value will be the multiplication (mod 97) of: 67 (the value at the same index in $\\mathsf{Arr}$) and 84 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$ \\mathsf{Acc} = [84, (67\\cdot84),\\bot,\\bot,\\bot,\\bot] = [84, 2,\\bot,\\bot,\\bot,\\bot]$\nThe next value will be the multiplication of: 11 (the value at the same index in $\\mathsf{Arr}$) and 2 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [84, 2,(11\\cdot2),\\bot,\\bot,\\bot] = [84,2,22,\\bot,\\bot,\\bot]$ $ \\mathsf{Acc} = [84, 2,22,(92\\cdot22),\\bot,\\bot] = [84,2,22,84,\\bot,\\bot]$ $ \\mathsf{Acc} = [84, 2,22,84,(36\\cdot84),\\bot] = [84,2,22,84,17,\\bot]$ $ \\mathsf{Acc} = [84,2,22,84,17,(67\\cdot17)] = [84, 2, 22, 84, 17, 72]$ $\\mathsf{Prod}_\\mathsf{Arr}=72$ Notice the last value in $\\mathsf{Acc}$ is $\\mathsf{Prod_\\mathsf{Arr}}$. The prover wants to show three constraints:\nThe first value in $\\mathsf{Acc}$ matches the first value in $\\mathsf{Arr}$, The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i]\\cdot\\mathsf{Acc}[i-1]$, The last value in $\\mathsf{Acc}$ matches $\\mathsf{Prod}_\\mathsf{Arr}$. If all three constraints are true, then $\\mathsf{Prod}_\\mathsf{Arr}$ is the product of the elements of $\\mathsf{Arr}$.\nLast, while it is not necessary to do, it is often convenient to hold the the value $\\mathsf{Prod}_\\mathsf{Arr}$ at the start of the array $\\mathsf{Acc}$ instead of the end. For this reason, the mathematical explanation below will construct $\\mathsf{Acc}$ \u0026ldquo;backwards\u0026rdquo; (or right-to-left) from the above example, where the last value of $\\mathsf{Acc}$ matches the last value of $\\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\\mathsf{Acc}$ is $\\mathsf{Prod}_\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, \\bot, 67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, 84, 67]$ $\\ldots$ $ \\mathsf{Acc} = [72, 84, 36, 65, 84, 67]$ $\\mathsf{Prod}_\\mathsf{Arr}=72$ Protocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers ($a_i \\in \\mathbb{Z}_q$) $\\mathcal{P}$ computes array $\\mathsf{Acc}$ as follows: $\\mathsf{Acc}[n-1]\\leftarrow\\mathsf{Arr}[n-1]$ $\\mathsf{Acc}[i]\\leftarrow\\mathsf{Arr}[i]\\cdot\\mathsf{Acc}[i+1]$ for $i$ from $n-2$ to 0 $\\mathcal{P}$ computes $\\mathsf{Prod}_\\mathsf{Arr}\\leftarrow\\mathsf{Acc}[0]$ Polynomial Level # We assume arrays $\\mathsf{Arr}$ and $\\mathsf{Acc}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product).\nRecall the three constraints we want to prove (now adjusted to fit with an $\\mathsf{Acc}$ that is constructed \u0026ldquo;backwards,\u0026rdquo; as noted above):\nThe last value in $\\mathsf{Acc}$ matches the last value in $\\mathsf{Arr}$, The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i]\\cdot\\mathsf{Acc}[i-1]$, The first value in $\\mathsf{Acc}$ matches $\\mathsf{Prod}_\\mathsf{Arr}$. In polynomial form, the constraints are:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Prod}_\\mathsf{Arr}$ In constraint 2, $\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ can also be conceptualized as rotate applied to $\\mathsf{Poly}_\\mathsf{Acc}(X)$ by one element (rightward in the array view). Also note that constraint 2 does not hold at $X=\\omega^{\\kappa-1}$ because this value is defined by constraint 1 (for the last value of $X$, the \u0026ldquo;next\u0026rdquo; value, $\\omega X$, wraps back to the first element of the array which is a boundary condition).\nWe adjust each of these constraints to show an equality with 0:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)=0$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)=0$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Prod}_\\mathsf{Arr}=0$ Next we take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X))\\cdot(X-\\omega^{\\kappa-1})=0$ $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Prod}_\\mathsf{Arr})\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These equations are true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$, and $\\mathsf{Poly}_\\mathsf{Vanish3}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes,\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ $Q_3(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$, $Q_2(X)$, and $Q_3(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all three $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all three are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2}{X^\\kappa - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(X) + \\rho^2 \\mathsf{Poly}_\\mathsf{Vanish3}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the mult2 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Acc}(X)$, $\\mathsf{Poly}_\\mathsf{Acc}(\\omega X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, and $\\mathsf{Prod}_\\mathsf{Arr}$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X))$ $K_\\mathsf{Acc}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Acc}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Acc},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}=(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish2}=(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Vanish3}=(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Prod}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)}$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Rust Mathematica (Toy Example) Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}$ such that $\\mathsf{Prod}_\\mathsf{Arr}=\\prod_{i = 0}^{n-1} \\mathsf{Arr}[i] \\space \\forall i \\in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)} \\newline - \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(\\zeta)\\rho^2}{\\zeta^\\kappa - 1} \\cdot(\\zeta^\\kappa - 1)$\n$= (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)} \\newline - ((\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) \\newline + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)})$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(\\zeta)\\rho^2$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish_1}}(X), \\mathsf{Poly_{Vanish_2}}(X)$ and $\\mathsf{Poly_{Vanish_3}}(X),$ are all vanishing on $\\mathcal{H_\\kappa}$, i.e. if all three of the following conditions hold for all $X \\in \\mathcal{H}_\\kappa$:\n$(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$ $ (\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot \\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X))\\cdot(X-\\omega^{\\kappa-1})=0$ $ (\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Prod}_\\mathsf{Arr})\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These conditions, in turn, hold if:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot \\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Prod}_\\mathsf{Arr}$ Where we get the \u0026ldquo;For $X$\u0026rdquo; due to zeroing parts of the polynomials (see zero1). Since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$, the above conditions are true if:\nThe last value in $\\mathsf{Acc}$ matches the last value in $\\mathsf{Arr}$ The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i] \\cdot \\mathsf{Acc}[i-1]$ The first value in $\\mathsf{Acc}$ matches $\\mathsf{Prod}_\\mathsf{Arr}$ Which are precisely the conditions the Intuitions sections explains will hold if the prover constructs their Accumulator by following the protocol and using $\\mathsf{Arr}$ such that $\\mathsf{Prod}_\\mathsf{Arr}=\\prod_{i = 0}^{n-1} \\mathsf{Arr}[i] \\space \\forall i \\in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Acc}(X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Acc}(X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Prod}_\\mathsf{Arr}\\neq\\prod_{i = 0}^{n-1} \\mathsf{Arr}[i]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, one of the three constraints must be false. But then the $\\mathsf{Poly}_\\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Acc}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr}(X)$. Each commitment $\\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta \\cdot \\omega)$ can only feasibly be opened to one value each. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2Y_\\mathsf{Vanish3}}{\\zeta^\\kappa - 1}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2Y_\\mathsf{Vanish3}}{\\zeta^\\kappa - 1}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ generates an array $\\mathsf{Arr'}$ whose product is equal to the disclosed value $\\mathsf{Prod}_\\mathsf{Arr}$ (this array could just have $\\mathsf{Prod}_\\mathsf{Arr}$ in one entry, and $1$\u0026rsquo;s elsewhere), then follows the same steps a prover would to prove the product of this array. So, $\\mathcal{S}$ computes the accumulator $\\mathsf{Acc'}$ and interpolates the two arrays into their respective polynomials, $\\mathsf{Poly}_\\mathsf{Acc'}(X)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(X)$. It computes $Q(X)'$ using $\\mathsf{Poly}_\\mathsf{Acc'}(X)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(X)$ and the random challenge point $\\rho'$ (by strong Fiat-Shamir). $\\mathcal{S}$ commits to each of these three polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta'$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta'), \\space \\mathsf{Poly}_\\mathsf{Arr}(\\zeta'), \\space Q(\\zeta')$, and $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta' \\cdot \\omega)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nThis proof could also be done by defining a simulator that knows the trapdoor $\\tau$ and cant thus create a passing witness for any commitment. The proof for mult1 is done in this style, but with small alterations would work here as well (and vice versa for this style of proof working for mult1) "},{"id":13,"href":"/docs/gadgets/mult3/","title":"Mult3","section":"Gadgets","content":" Multiplication (Type 3) # Recap of types # Type Description Recap This mult1 $\\mathsf{Arr}_3=\\mathsf{Arr}_1 \\cdot \\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the element-wise multiplication of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. mult2 $\\mathsf{Prod}_\\mathsf{Arr}=\\prod_{i = 0}^{n-1} \\mathsf{Arr}[i]$ $\\mathsf{Prod}_\\mathsf{Arr}$ is the disclosed product of all the elements in $\\mathsf{Arr}$. mult3 $\\prod_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\prod_{i = 0}^{n-1} \\mathsf{Arr}_2[i]$ $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ have the same undisclosed product. ✅ Relation # $ \\mathcal{R}_{\\mathtt{mult3}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr2}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}],\\\\ \\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}], \\\\ \\mathsf{Poly}_\\mathsf{Arr_1}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_1}), \\\\ \\mathsf{Poly}_\\mathsf{Arr_2}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_2}), \\\\ K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}),\\\\ K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}), \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds two arrays $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that they have the same undisclosed product. The prover will encode the two arrays into polynomials, $\\mathsf{Poly}_\\mathsf{Arr_1}$ and $\\mathsf{Poly}_\\mathsf{Arr_2}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to them as $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$. The verifier ($\\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$.\nIn order to prove $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$ are consistent, the prover will build two helper arrays $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$ called accumulators (or accumulating arrays or incremental arrays). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$, the prover will also encode $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$ as a polynomials and provide a commitment to the verifier of each one. The idea is that the prover will prove a relation between each $\\mathsf{Arr}$ and its $\\mathsf{Acc}$; and a relation between $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$. Put together, it will imply the correct relation between $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$.\nWe will illustrate a small numerical example in $\\mathbb{Z}_{97}$ of constructing an accumulator $\\mathsf{Acc}$ for the array $\\mathsf{Arr}= [84,67,11,92,36,67]$. The idea is to create a new array, $\\mathsf{Acc}$, that starts the same as $\\mathsf{Arr}$ and ends with the product of all entries of $\\mathsf{Arr}$, by folding in the integers from $\\mathsf{Arr}$ one-by-one with multiplication. Then each value in the new array will depend on only two values, as below.\nThe first value in $\\mathsf{Acc}$ will be a copy of the first value from $\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$\\mathsf{Acc}= [84, \\bot,\\bot,\\bot,\\bot,\\bot] $\nThe next value will be the multiplication (mod 97) of: 67 (the value at the same index in $\\mathsf{Arr}$) and 84 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$ \\mathsf{Acc} = [84, (67\\cdot84),\\bot,\\bot,\\bot,\\bot] = [84, 2,\\bot,\\bot,\\bot,\\bot]$\nThe next value will be the multiplication of: 11 (the value at the same index in $\\mathsf{Arr}$) and 2 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [84, 2,(11\\cdot2),\\bot,\\bot,\\bot] = [84,2,22,\\bot,\\bot,\\bot]$ $ \\mathsf{Acc} = [84, 2,22,(92\\cdot22),\\bot,\\bot] = [84,2,22,84,\\bot,\\bot]$ $ \\mathsf{Acc} = [84, 2,22,84,(36\\cdot84),\\bot] = [84,2,22,84,17,\\bot]$ $ \\mathsf{Acc} = [84,2,22,84,17,(67\\cdot17)] = [84, 2, 22, 84, 17, 72]$ Notice the last value in $\\mathsf{Acc}$ is the product of all the entries in $\\mathsf{Arr}$. The prover wants to show five constraints:\nThe first value in $\\mathsf{Acc_1}$ matches the first value in $\\mathsf{Arr_1}$ The first value in $\\mathsf{Acc_2}$ matches the first value in $\\mathsf{Arr_2}$ The rest of the values in $\\mathsf{Acc}_1$ are of the form $\\mathsf{Acc_1}[i]=\\mathsf{Arr_1}[i]\\cdot\\mathsf{Acc_1}[i-1]$ The rest of the values in $\\mathsf{Acc}_2$ are of the form $\\mathsf{Acc_2}[i]=\\mathsf{Arr_2}[i]\\cdot\\mathsf{Acc_2}[i-1]$ The last value in $\\mathsf{Acc_1}$ matches the last value in $\\mathsf{Acc_2}$ If all five constraints are true, then entries of $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ have the same product.\nLast, while it is not necessary to do, it is often convenient to hold the the value of the product at the start of the array $\\mathsf{Acc}$ instead of the end. For this reason, the mathematical explanation below will construct $\\mathsf{Acc}$ \u0026ldquo;backwards\u0026rdquo; (or right-to-left) from the above example, where the last value of $\\mathsf{Acc}$ matches the last value of $\\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\\mathsf{Acc}$ is the product of all entries:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, \\bot, 67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, 84, 67]$ $\\ldots$ $ \\mathsf{Acc} = [72, 84, 36, 65, 84, 67]$ and the product of all entries in $\\mathsf{Arr}$ is 72 Protocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ computes array $\\mathsf{Acc_j}$ as follows for $j \\in [1,2]$: $\\mathsf{Acc_j}[n-1]\\leftarrow\\mathsf{Arr_j}[n-1]$ $\\mathsf{Acc_j}[i]\\leftarrow\\mathsf{Arr_j}[i]\\cdot\\mathsf{Acc_j}[i+1]$ for $i$ from $n-2$ to 0 Polynomial Level # We assume arrays $\\mathsf{Arr_1}$, $\\mathsf{Arr_2}$, $\\mathsf{Acc_1}$, and $\\mathsf{Acc_2}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product).\nRecall the five constraints we want to prove (now adjusted to fit with an $\\mathsf{Acc}$ that is constructed \u0026ldquo;backwards,\u0026rdquo; as noted above):\nThe last value in $\\mathsf{Acc_1}$ matches the last value in $\\mathsf{Arr_1}$ The last value in $\\mathsf{Acc_2}$ matches the last value in $\\mathsf{Arr_2}$ The rest of the values in $\\mathsf{Acc}_1$ are of the form $\\mathsf{Acc_1}[i]=\\mathsf{Arr_1}[i]\\cdot\\mathsf{Acc_1}[i-1]$ The rest of the values in $\\mathsf{Acc}_2$ are of the form $\\mathsf{Acc_2}[i]=\\mathsf{Arr_2}[i]\\cdot\\mathsf{Acc_2}[i-1]$ The first value in $\\mathsf{Acc_1}$ matches the first value in $\\mathsf{Acc_2}$ In polynomial form, the constraints are:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, For $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Acc_2}(X)$ In constraints 2 and 3, $\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ can also be conceptualized as rotate applied to $\\mathsf{Poly}_\\mathsf{Acc}(X)$ by one element (rightward in the array view). Also note thats constraint 2 and 3 do not hold at $X=\\omega^{\\kappa-1}$ because this value is defined by constraint 1 (for the last value of $X$, the \u0026ldquo;next\u0026rdquo; value, $\\omega X$, wraps back to the first element of the array which is a boundary condition).\nWe adjust each of these constraints to show an equality with 0:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X)=0$, For $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X)=0$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)=0$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)=0$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Acc_2}(X)=0$ Next we take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=(\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$, $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X))\\cdot(X-\\omega^{\\kappa-1})=0$ $\\mathsf{Poly}_\\mathsf{Vanish4}(X)=(\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X))\\cdot(X-\\omega^{\\kappa-1})=0$ $\\mathsf{Poly}_\\mathsf{Vanish5}(X)=(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Acc_2}(X)\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These equations are true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish3}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish4}(X)$, and $\\mathsf{Poly}_\\mathsf{Vanish5}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prove computes,\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ $Q_3(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^\\kappa - 1}$ $Q_4(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish4}(X)}{X^\\kappa - 1}$ $Q_5(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish5}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$, $Q_2(X)$, $Q_3(X)$, $Q_4(X)$, and $Q_5(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all five $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all five are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4}{X^\\kappa - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2} (X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X) \\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4 - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the mult3 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$ $K_\\mathsf{Acc_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Acc_1}(X))$ $K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$ $K_\\mathsf{Acc_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Acc_2}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Acc_1},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Acc_2},\\zeta\\omega)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}= (\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish2}= (\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish3}=(\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Vanish4}= (\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Vanish5}= (\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)-\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)}$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5}- Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ such that $\\prod_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\prod_{i = 0}^{n-1} \\mathsf{Arr}_2[i] \\space \\forall i \\in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$ = Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5}- Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5} - (\\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4}{X^\\kappa - 1})(\\zeta^\\kappa - 1)$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5} - {\\mathsf{Poly}_\\mathsf{Vanish1}(X) - \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho - \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 - \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 - \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4}$\n$= 0$\nWhere the finally equality holds because $Y_{\\mathsf{Vanish_j}}=\\mathsf{Poly_{Vanish_j}}(\\zeta)$.\nNote also that the second equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish_1}}(X), \\mathsf{Poly_{Vanish_2}}(X)$, $\\mathsf{Poly_{Vanish_3}}(X),$ $\\mathsf{Poly_{Vanish_4}}(X)$, and $\\mathsf{Poly_{Vanish_5}}(X),$ are all vanishing on $\\mathcal{H_\\kappa}$, i.e. if all three of the following conditions hold for all $X \\in \\mathcal{H}_\\kappa$:\n$ (\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$ $ (\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$ $(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-(\\mathsf{Poly}_\\mathsf{Arr_1}(X) \\cdot \\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)))\\cdot(X-\\omega^{\\kappa-1})=0$ $ (\\mathsf{Poly}_\\mathsf{Acc_2}(X)-(\\mathsf{Poly}_\\mathsf{Arr_2}(X) \\cdot \\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)))\\cdot(X-\\omega^{\\kappa-1})=0$ $ (\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Acc_2}(X)\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These conditions, in turn, hold if:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)$ For $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X) \\cdot \\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X) \\cdot \\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Acc_2}(X)$ Where we get the \u0026ldquo;For $X$\u0026rdquo; due to zeroing parts of the polynomials (see zero1). Since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$, the above conditions are true if:\nThe last value in $\\mathsf{Acc_1}$ matches the last value in $\\mathsf{Arr_1}$ The last value in $\\mathsf{Acc_2}$ matches the last value in $\\mathsf{Arr_2}$ The rest of the values in $\\mathsf{Acc}_1$ are of the form $\\mathsf{Acc_1}[i]=\\mathsf{Arr_1}[i] \\cdot \\mathsf{Acc_1}[i-1]$ The rest of the values in $\\mathsf{Acc}_2$ are of the form $\\mathsf{Acc_2}[i]=\\mathsf{Arr_2}[i] \\cdot \\mathsf{Acc_2}[i-1]$ The first value in $\\mathsf{Acc_1}$ matches the first value in $\\mathsf{Acc_2}$ Which are precisely the conditions the Intuitions sections explains will hold if the prover constructs their Accumulators by following the protocol and using $\\mathsf{Arr}_1$ and $\\mathsf{Arr_2}$ such that $\\prod_{i = 0}^{n-1} \\mathsf{Arr}_1[i] =\\prod_{i = 0}^{n-1} \\mathsf{Arr}_2[i] \\space \\forall i \\in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_{2}}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_{2}}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_{2}}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_{2}}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}A$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\prod_{i = 0}^{n-1} \\mathsf{Arr_1}[i]\\neq\\prod_{i = 0}^{n-1} \\mathsf{Arr_2}[i]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, one of the five constraints must be false. But then the $\\mathsf{Poly}_\\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, also writes commitments to $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$. Each commitment $\\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta\\omega)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta\\omega)$ can each only feasibly be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4Y_\\mathsf{Vanish5}}{(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4Y_\\mathsf{Vanish5}}{(\\zeta^]kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Acc_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$ and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\tau)$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Acc_1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, and $g^{\\mathsf{Poly}_\\mathsf{Acc_2}(\\tau)}$ to write as the commitments $K_\\mathsf{Arr_1}$, $ K_\\mathsf{Acc_1}$, $K_\\mathsf{Arr_2}$, and $ K_\\mathsf{Acc_2}$. $\\mathcal{S}$ then generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Acc_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$ and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\tau)$. $\\mathcal{S}$ writes the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the second random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta\\omega)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta\\omega)$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4Y_\\mathsf{Vanish5}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nFor mult2, the proof is written with a simulator that doesn\u0026rsquo;t know the trapdoor; however, with small alterations the proof for mult2 should apply here and vice versa "},{"id":14,"href":"/docs/gadgets/range/","title":"Range","section":"Gadgets","content":" Range # Recap of types # Type Description Recap This range $\\mathsf{Arr}[i]\\in[0,r]$ Each element of array $\\mathsf{Arr}$ is in the range $[0,r]$ ✅ Relation # $\\mathcal{R}_{\\mathtt{add1}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr}) \\end{array} \\middle | \\begin{array}{l} 0\\le{\\mathsf{Arr}[i]}\\le{r}, i\\in[0,n), \\\\ \\mathsf{Poly}_\\mathsf{Arr}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}), \\end{array} \\right\\}$\nIntuition # To prove each element of array $\\mathsf{Arr}$ is in the range $[0,r]$, one of the most intuitive ways is we create a vector containing the numbers from $0$ to $r$ and run the lookup argument for $\\mathsf{Arr}$. Another approach is we prove each element is in $[0,r]$. Specifically, we decompose the target number to digits in some base $x$ and prove (i) the digits are valid and (ii) the number can be recovered from the digits and the base. The prover ($\\mathcal{P}$) holds a number $\\eta$ and a vector $\\mathsf{T}$ of $k=\\lceil\\log_x{\\eta}\\rceil$ integers from $\\mathbb{Z}_q$: $[a_0,a_1,a_2,\\dots,a_{k-1}]$. Then $r=x^k$ and the prover shows $\\eta \\in [0, r]$. It will produce a succinct (logarithm base $x$ of $\\eta$; for simplicity, we will use base $2$) proof that the vector $\\mathsf{T}$ satisfies the following conditions: (i) the first value of $\\mathsf{T}$ equals to $\\eta$ (ii) the last value of $\\mathsf{T}$ equals to one or zero (iii) any value minus two times the next value is equal to one or zero in $\\mathsf{T}$. The prover will encode $\\mathsf{Arr}$ and $\\mathsf{T}$ into two polynomials: $\\mathsf{Poly}_\\mathsf{Arr}$ and $\\mathsf{Poly}_\\mathsf{T}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$). It will commit to each polynomial: $K_\\mathsf{Arr}$ and $K_\\mathsf{T}$. The verifier ($\\mathcal{V}$) cannot check any of the $\\mathsf{Arr}$, $\\mathsf{T}$ or $\\mathsf{Poly}_\\mathsf{Arr}$, $\\mathsf{Poly}_\\mathsf{T}$ values directly. Instead the verifier only sees $K_\\mathsf{Arr}$, and $K_\\mathsf{T}$.\nConsider a small numerical example where $\\eta = 14$, working with $x=2$. Since $k=\\lceil\\log_2{\\eta}\\rceil = 4$, we will demonstrate that $\\eta \\in [0,r=2^k]$ by constructing $\\mathsf{Arr}$ consisting of $k$ integers. First, we know $\\mathsf{T}[0] = \\eta = 14$:\n$\\mathsf{T} = [14, \\bot, \\bot, \\bot]$ Now, for $\\mathsf{T}[1]$ we want an integer $a_1$ such that $14 - 2\\cdot a_1$ equals 1 or 0. Since 14 is even, we are looking for $a_1$ such that $14 - 2\\cdot a_1=0$, thus $a_1=7$:\n$\\mathsf{T} = [14, 7, \\bot, \\bot]$ Now we find $a_2$ such that $7-2\\cdot a_2$ equals 1 or 0. Since 7 is odd, we are looking for $a_2$ such that $7-2\\cdot a_2=1$, thus $a_2 = 3$:\n$\\mathsf{T} = [14, 7, 3, \\bot]$ Finally, we find $a_3$ such that $3 - 2\\cdot a_3$ equals 1 or 0. Again, since 3 is odd, we are looking for $a_3$ such that $3-2\\cdot a_3=1$, thus $a_3= 1$:\n$\\mathsf{T} = [14, 7, 3, 1]$ Now, $\\mathsf{Arr}$ is $k$ elements long, and the last element of $\\mathsf{T}$ is one or zero, so we have constructed the desired vector $\\mathsf{T}$. Note that the last element of $\\mathsf{T}$ will only be zero if $\\eta \\leq x^{k-1}$.\nIn order to prove $K_\\mathsf{Arr}$ and $K_\\mathsf{T}$ satisfy the above three conditions, one of the most straightforward methods is to use the additive homomorphic property of the KZG commitment scheme, i.e., prove $K_\\mathsf{Arr}$ and $K_\\mathsf{T}$ satisfy the conditions through the group addition. This method works if the target condition only involves additive operations. However, there are multiplications in the above conditions, so it is infeasible to calculate the product of two KZG commitments unless the t-SDH can be solved. Even if the verifier is given the powers of the KZG commitments, it is inefficient to perform scalar multiplications for two commitments (imagine the time complexity of multiplying two $d$-degree polynomials is $O(d^2)$), which implies this method is hard to be succinct.\nThe second method is more general and widely used. The basic idea is instead of proving the commitments satisfy the conditions, the prover reveals the evaluations of the polynomials at a random point sent by the verifier to prove the evaluations satisfy the conditions; at the same time, the prover proves the evaluations are valid through the binding property of KZG commitment. This method works because of the Schwartz-Zippel lemma, which tells us if the equation (of the polynomials) holds at a random evaluation point on the domain $\\mathcal{H}_\\kappa$, then it holds at any point on $\\mathcal{H}_\\kappa$ with high probability. The probability is $d/|\\mathbb{F}|$, where $d$ is the number of roots of the equation and $\\mathbb{F}$ is the field of the random evaluation point. This means as long as the field is big enough, the probability of failure is negligible. By rearranging the polynomials, the verifier can challenge any point on the group field rather than $\\mathcal{H}_\\kappa$, which makes the probability of failure tend to $0$.\nProtocol Details # Array Level # $\\mathcal{P}$ holds a number $\\eta\\in\\mathbb{Z}$ $\\mathcal{P}$ computes or holds an array $\\mathsf{T}=[t_0,t_1,t_2,\\dots,t_{k-1}]$ of $k$ (recall $k=\\lceil\\log_2{\\eta}\\rceil$) integers ($t_i\\in\\mathbb{Z}$) such that: $\\mathsf{T}[0]=\\eta$ $\\mathsf{T}[k-1]\\in\\{0,1\\}$ $\\mathsf{T}[i]-2\\cdot\\mathsf{T}[i+1]\\in\\{0,1\\}$ Polynomial Level # We assume the array $\\mathsf{T}$ is encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 0 (which will not change the sum).\nRecall the constraints we want to prove:\n$\\mathsf{T}[0]=\\eta$ $\\mathsf{T}[k-1]\\in\\{0,1\\}$ $\\mathsf{T}[i]-2\\cdot\\mathsf{T}[i+1]\\in\\{0,1\\}$ In polynomial form, the constraints are:\nFor $X=\\omega^0$: $\\mathsf{Poly}_\\mathsf{T}(X)=\\eta$ For $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{T}(X)\\in\\{0,1\\}$ For all $X=\\mathcal{H}_\\kappa\\setminus{\\omega^{\\kappa-1}}$: $\\mathsf{Poly}_\\mathsf{T}(X)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega)\\in\\{0,1\\}$ Note because the value of $\\eta$ is a secret, $\\mathcal{P}$ will not reveal $\\eta$ to let $\\mathcal{V}$ verify $\\eta$ is the evaluation of $\\mathsf{Poly}_\\mathsf{T}(\\omega^0)$. $\\mathcal{P}$ will leverage the hiding property of KZG (Pedersen) commitment to prove the committed $\\eta$ is the correct evaluation. Specifically, $\\mathcal{P}$ claims the committed $\\eta$ is the correct one and opens $\\mathsf{Poly}_\\mathsf{T}$ at $\\omega^0$. If the committed $\\eta$ satisfy the KZG verification, $\\mathcal{V}$ can believe the first constraint is satisfied.\nWe take care of the \u0026ldquo;for $X$\u0026rdquo; conditions of constraints 2 and 3 by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=\\mathsf{Poly}_\\mathsf{T}(X)\\cdot[\\mathsf{Poly}_\\mathsf{T}(X)-1]\\cdot\\frac{X^\\kappa-1}{X-\\omega^{\\kappa-1}}=0$ $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=[\\mathsf{Poly}_\\mathsf{T}(X)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(X)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega)-1]\\cdot(X-\\omega^{\\kappa-1})=0$ The two equations are vanishing for every value of $X\\in\\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa-1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$ and $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$, and $Q_2(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all three $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all three are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)-Q(X)\\cdot(X^{\\kappa-1}-1)=0$\nUltimately the range gadget will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{T}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) are too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{T}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta)$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta\\omega)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}=\\mathsf{Poly}_\\mathsf{T}(\\zeta)\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-1]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^{\\kappa-1}}$ $Y_\\mathsf{Vanish2}=[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)-1]\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1}+\\rho\\cdot{Y_\\mathsf{Vanish2}}-Q(\\zeta)\\cdot(\\zeta^\\kappa-1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who runs the protocol with $\\eta$ such that $\\eta \\in [0,r]$, can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish1}+\\rho\\cdot{Y_\\mathsf{Vanish2}}-Q(\\zeta)\\cdot(\\zeta^\\kappa-1)$\n$= \\mathsf{Poly}_\\mathsf{T}(\\zeta)\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-1]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^{\\kappa-1}} +[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)-1]\\cdot(\\zeta-\\omega^{\\kappa-1}) -Q(\\zeta)\\cdot(\\zeta^\\kappa-1)$\n$= \\mathsf{Poly}_\\mathsf{T}(\\zeta)\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-1]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^{\\kappa-1}} +[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)-1]\\cdot(\\zeta-\\omega^{\\kappa-1}) \\newline -\\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta)}{\\zeta^n - 1}\\cdot(\\zeta^\\kappa-1)$\n$= \\mathsf{Poly}_\\mathsf{T}(\\zeta)\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-1]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^{\\kappa-1}} +[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)-1]\\cdot(\\zeta-\\omega^{\\kappa-1}) \\newline - [\\mathsf{Poly}_\\mathsf{T}(\\zeta)\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-1]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^{\\kappa-1}} +[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)-1]\\cdot(\\zeta-\\omega^{\\kappa-1})]$\n$=0$\nWhere the third equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)$ is divisible by $X^\\kappa -1$. This is true if $\\mathsf{Poly_{Vanish1}}(\\zeta)$ and $\\mathsf{Poly_{Vanish2}}(\\zeta)$ are vanishing on $\\mathcal{H}_\\kappa$, i.e. if both of the following conditions hold:\n$ \\mathsf{Poly}_\\mathsf{T}(X)\\cdot[\\mathsf{Poly}_\\mathsf{T}(X)-1]\\cdot\\frac{X^\\kappa-1}{X-\\omega^{\\kappa-1}}=0$ $ [\\mathsf{Poly}_\\mathsf{T}(X)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(X)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega)-1]\\cdot(X-\\omega^{\\kappa-1})=0$ These conditions, in turn, hold if:\nFor $X=\\omega^0$: $\\mathsf{Poly}_\\mathsf{T}(X)=\\eta$ For $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{T}(X)\\in\\{0,1\\}$ For all $X=\\mathcal{H}_\\kappa\\setminus{\\omega^{\\kappa-1}}$: $\\mathsf{Poly}_\\mathsf{T}(X)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega)\\in\\{0,1\\}$ Where we get the \u0026ldquo;For $X$\u0026rdquo; due to zeroing parts of the polynomials (see zero1). Since $\\mathsf{Poly_T}(\\omega^i) = \\mathsf{Arr_T}[i] \\space \\forall i \\in [0, \\kappa - 1]$, the above conditions are true if:\n$\\mathsf{T}[0]=\\eta$ $\\mathsf{T}[k-1]\\in\\{0,1\\}$ $\\mathsf{T}[i]-2\\cdot\\mathsf{T}[i+1]\\in\\{0,1\\}$ Which are precisely the conditions we described in the intuition section that a honest prover will obey when encoding $\\eta$. Thus, the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g,g^\\tau,g^{\\tau^2},\\dots,g^{\\tau^{n-1}}]$, $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{T}(X)$ and $Q$ $\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{T}(X)$ and $Q$ $\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$ $\\mathcal{A}$ wins if $\\mathcal{V}$ accepts at the end of the protocol $\\eta\\notin[0,r]$ Our proof is as follows:\nFirst, we prove $\\eta\\ge{0}$. To make $\\mathsf{Poly}_\\mathsf{Vanish1}$ exist, the last value of $\\mathsf{T}$ must be zero or one. From $\\mathsf{Poly}_\\mathsf{Vanish2}$, it can be observed that $\\mathsf{T}[i]\\ge\\mathsf{T}[i+1]$ for all $i\\in[0,\\kappa-2]$. Thus, $\\mathsf{T}[0]$ is equal to or greater than $\\mathsf{T}[\\kappa-1]$, i.e., $\\eta\\ge{0}$.\nSecond, we prove $\\eta\\le{r}$. For simplicity, we assume $r$ is the power of two (recall $\\kappa=\\log_2{r}$). From $\\mathsf{Poly}_\\mathsf{Vanish2}$, we know $\\mathsf{T}[0]$ is less than or equal to $2^\\kappa$. Therefore, $\\eta\\le{r}$.\nZero-Knowledge # To prove the above protocol is zero-knowledge, we do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ randomly generates an $\\eta^*$, then follows the same steps a prover would prove the lookup argument. $\\mathcal{S}$ computes $\\mathsf{T^*}$ and interpolates $\\mathsf{Poly}_\\mathsf{T^*}$ from $\\mathsf{T^*}$. It computes $Q^*(X)$ and finally outputs the commitments to each of these polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta^*$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_\\mathsf{T^*}(\\zeta^*),\\mathsf{Poly}_\\mathsf{T^*}(\\zeta^*\\omega)$, and $Q^*(\\zeta^*)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":15,"href":"/docs/gadgets/rotate/","title":"Rotate","section":"Gadgets","content":" Rotate # Recap of types # $ \\mathcal{R}_{\\mathtt{rotate}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr}, K_\\mathsf{Arr'}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}],\\\\ \\mathsf{Arr'}[i] = \\mathsf{Arr}[i +\\alpha], \\\\ \\mathsf{Poly}_\\mathsf{Arr}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}),\\\\ \\mathsf{Poly}_\\mathsf{Arr'}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr'}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}),\\\\ K_\\mathsf{Arr'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr'}),\\\\ \\end{array} \\right\\} $\nIntuition # Assume $\\mathsf{Arr}$ is an array of data of size $n$. It is encoded as the y-coordinates into univariant polynomials where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. We call our polynomial $\\mathsf{Poly}_\\mathsf{Arr}(X)$. The goal is to construct an output polynomial $\\mathsf{Poly_\\mathsf{Arr'}}$ where all the elements in $\\mathsf{Arr}$ have been rotated by $\\alpha$ positions; i.e. $\\mathsf{Arr'}[i] \\leftarrow \\mathsf{Arr}[i + \\alpha]$. Here, the index is defined mod $n$.\nWritten in terms the polynomials, the goal is that $\\mathsf{Poly_\\mathsf{Arr'}}(\\omega^i) = \\mathsf{Poly_\\mathsf{Arr}}(\\omega^i\\cdot\\omega^\\alpha)$ for all $i \\in [0, n-1]$. To this end, we define $\\mathsf{Poly_\\mathsf{Arr}}(X) = \\mathsf{Poly_\\mathsf{Arr}}(X)\\cdot\\omega^\\alpha$ and demonstrate below why this satisfies the requirements of the output polynomials.\nConsider $\\mathsf{Poly_\\mathsf{Arr}}(X) = c_{n-1}X^{n-1} + \\dots + c_2X^2 + c_1X + c_0$. Then:\n$\\mathsf{Poly_\\mathsf{Arr'}}(X)$\n$= \\mathsf{Poly_Arr}(X) \\cdot \\omega^\\alpha$\n$= (c_{n-1}X^{n-1} + \\dots + c_2X^2 + c_1X + c_0)(\\omega^\\alpha) $\n$= c_{n-1}X^{n-1}\\cdot\\omega^\\alpha + \\dots + c_2X^2\\cdot\\omega^\\alpha + c_1X\\cdot\\omega^\\alpha + c_0\\cdot\\omega^\\alpha$\n$= \\mathsf{Poly_\\mathsf{Arr}}(X\\cdot\\omega^\\alpha)$\nIn particular, $\\mathsf{Poly_{Arr'}}(\\omega^i) = \\mathsf{Poly_\\mathsf{Arr}}(\\omega^i\\cdot\\omega^\\alpha)$ for $i \\in [0, n-1]$. We also note that $\\omega^n = \\omega^0$, since $\\omega$ is of order $\\kappa$. Thus the exponent of $\\omega$ is defined mod $n$, like the indexing of $\\mathsf{Arr}$. This means that $\\omega^i\\cdot\\omega^\\alpha$ wraps around to have the rotation defined as it should be for $i + \\alpha \\gt n-1$.\nTo prove the relation between $\\mathsf{Arr}$ and $\\mathsf{Arr'}$, the prover must commit to the two polynomials, $\\mathsf{Poly_{Arr}}$ and $\\mathsf{Poly_{Arr'}}$ as $K_{\\mathsf{Arr}}$ and $K_\\mathsf{Arr'}$. The verifier ($\\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$. The relation will be proven by showing $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$ and consistent; this mean verifying that $\\mathsf{Arr'}[i] \\leftarrow \\mathsf{Arr}[i + \\alpha]$.\nProtocol Details # Array Level # * $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers ($a_{i} \\in \\mathbb{Z}_q$)\n* $\\mathcal{P}$ holds or computes $\\mathsf{Arr}'$ such that:\n* $\\mathsf{Arr}'[i]= \\mathsf{Arr}[i+\\alpha]$ for $i \\in [0, n-1]$\nPolynomial Level # We assume that $\\mathsf{Arr}$ and $\\mathsf{Arr'}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the arrays, then $\\mathsf{Arr}$ can be padded with any value (say, all 1s) as long as this is done before the rotation to create $\\mathsf{Arr'}$ is computed.\nRecall the constraint we want to prove:\n$\\mathsf{Arr}'[i]= \\mathsf{Arr}[i+\\alpha]$ for $i \\in [0, n-1]$ We write the constraint in polynomial form:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr'}(X) = \\mathsf{Poly}_\\mathsf{Arr}(X)\\cdot\\omega^\\alpha$ We adjust the constraint to show an equality with 0 and label it:\n$\\mathsf{Poly}_\\mathsf{Vanish}(X)= \\mathsf{Poly}_\\mathsf{Arr'}(X) - \\mathsf{Poly}_\\mathsf{Arr}(X)\\cdot\\omega^\\alpha = 0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(X)}{X^\\kappa - 1}$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the rotate argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr}(X)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X))$\n$K_\\mathsf{Arr'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr'}(X))$\n$K_Q=\\mathsf{KZG.Commit}(Q(X))$\nThe prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$\n$\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta)$\n$\\mathsf{Poly}_\\mathsf{Arr'}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr'},\\zeta)$\n$Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$\nTo check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish}= \\mathsf{Poly}_\\mathsf{Arr'}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr}(\\zeta)\\cdot\\omega^\\alpha$\n$Y_\\mathsf{Zero}=Y_\\mathsf{Vanish} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\nFinally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr'}$ and $\\mathsf{Arr}$ such that $\\mathsf{Arr'}[i] = \\mathsf{Arr}[i +\\alpha] \\space \\forall i \\in [0, n-1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$ = Y_\\mathsf{Vanish} - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$ = \\mathsf{Poly_{Arr'}}(\\zeta) - \\mathsf{Poly_{Arr}}(\\zeta)\\cdot \\omega^\\alpha - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly_{Arr'}}(\\zeta) - \\mathsf{Poly_{Arr}}(\\zeta)\\cdot \\omega^\\alpha - \\frac{\\mathsf{Poly_{Vanish}}(\\zeta)}{\\zeta^\\kappa - 1}\\cdot(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly_{Arr'}}(\\zeta) - \\mathsf{Poly_{Arr}}(\\zeta)\\cdot \\omega^\\alpha - \\mathsf{Poly_{Arr'}}(\\zeta) + \\mathsf{Poly_{Arr}}(\\zeta)\\cdot \\omega^\\alpha$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish}}(X)$ is vanishing on $\\mathcal{H_\\kappa}$, i.e. if $\\mathsf{Poly}_\\mathsf{Arr'}(X) - \\mathsf{Poly}_\\mathsf{Arr}(X)\\cdot\\omega^\\alpha = 0 \\space \\forall X \\in \\mathcal{H_\\kappa}$. This is true if $\\mathsf{Poly}_\\mathsf{Arr'}(X) - \\mathsf{Poly}_\\mathsf{Arr}(X\\cdot\\omega^\\alpha) = 0 \\space \\forall X \\in \\mathcal{H_\\kappa}$, which is in turn true if $\\mathsf{Arr'}[i] - \\mathsf{Arr}[i + \\alpha] = 0 \\space \\forall i \\in [0, \\kappa -1]$, since $\\mathsf{Poly_Arr}(\\omega^i)=\\mathsf{Arr}[i] \\space \\forall i \\in [0, \\kappa -1]$. But $\\mathsf{Arr'}[i] - \\mathsf{Arr}[i + \\alpha] = 0 \\space \\forall i \\in [0, n-1]$ is precisely the relation between $\\mathsf{Arr'}$ and $\\mathsf{Arr}$ that we assumed held for our prover (if $\\kappa \\gt n$ then the arrays get padded such that this relation still holds), thus the $Y_\\mathsf{Zero}(X)$ it creates by following the protocol is the zero polynomial, and its transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$, the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{Arr'}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{Arr'}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Arr'}[i] \\neq \\mathsf{Arr}[i + \\alpha]$ for some $i \\in [0, n-1]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, there must be some $i \\in [0, n-1]$ such that $\\mathsf{Arr'}[i] \\neq \\mathsf{Arr}[i + \\alpha]$. But then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Arr}(X)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(X)$. All commitments $\\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(\\zeta)$ can each only feasibly be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}} {(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr}(\\tau)}$ and ${\\mathsf{Poly}_\\mathsf{Arr'}(\\tau)}$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr}(\\tau)}$ and $g^{\\mathsf{Poly}_\\mathsf{Arr'}(\\tau)}$ to write as the commitments $ K_\\mathsf{Arr}$ and $K_\\mathsf{Arr'}$. $\\mathcal{S}$ computes $Q(\\tau)$ using the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr}(\\tau)}$ and ${\\mathsf{Poly}_\\mathsf{Arr'}(\\tau)}$. $\\mathcal{S}$ writes the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)}$ and ${\\mathsf{Poly}_\\mathsf{Arr'}(\\zeta)}$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":16,"href":"/docs/gadgets/shuffle1/","title":"Shuffle1","section":"Gadgets","content":" Shuffle (Type 1) # Recap of types # Type Description Recap This shuffle1 $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1)$ Array $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ for some undisclosed permutation $\\pi$. ✅ shuffle2 $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1 ,\\pi)$ Array $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ under a disclosed permutation $\\pi$. Relation # $ \\mathcal{R}_{\\mathtt{shuffle1}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr2}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}],\\\\ \\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}], \\\\ \\mathsf{Poly}_\\mathsf{Arr_1}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_1}), \\\\ \\mathsf{Poly}_\\mathsf{Arr_2}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_2}), \\\\ K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}),\\\\ K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}), \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds 2 arrays, $\\mathsf{Arr_1 }$ and $\\mathsf{Arr_2}$, of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ for some undisclosed permutation $\\pi$. The prover will encode the two arrays into polynomials, $\\mathsf{Poly}_\\mathsf{Arr_1}$ and $\\mathsf{Poly}_\\mathsf{Arr_2}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to them as $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$. The verifier ($\\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$.\nOne idea to check that $\\mathsf{Arr_2}$ is a permutation of $\\mathsf{Arr_1}$ might be to perform a product check on the two arrays. If the permutation relation holds, then the products will be equal; however, many arrays can have their entries multiply to the same number, without necessarily containing the same elements.\nInstead, the prover constructs two new arrays, $\\mathsf{Arr_1}'$ and $\\mathsf{Arr_2}'$, where $\\mathsf{Arr_j}'$ contains the points $ \\{r - \\mathsf{Arr_j}[i] \\}_{i \\in [0, n-1]}$ for $r$ a random field element. Then, a product check is run on these two arrays. One way to understand why this works is to think of it as creating two auxiliary polynomials, ${\\mathsf{Poly}}_\\mathsf{Arr_1'}$ and ${\\mathsf{Poly}}_\\mathsf{Arr_2'}$, where $\\mathsf{Poly}_\\mathsf{Arr_j'}(X) = \\prod^{n-1}_{i = 1}(X - \\mathsf{Arr_j}[i])$. If ${\\mathsf{Poly}}_\\mathsf{Arr_1'}$ = $\\mathsf{Poly}_\\mathsf{Arr_2'}$, then they have the same factorization. This means that $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ must contain the same elements (in possibly different orders); in other words, $\\mathsf{Arr}_2$ is a permutation of $\\mathsf{Arr}_1$. To check this equality, a random challenge point $r$ is generated and the products are checked at that point. If they are equal at that point then (with overwhelming probability) the polynomials are equal.\nIn addition to demonstrating the equality of the product of $\\mathsf{Arr_1}'$ and $\\mathsf{Arr_2}'$, it must also be shown that these two arrays are defined correctly in terms of the original arrays. In other words, it must be shown that $\\mathsf{Arr_j}'[i]= r - \\mathsf{Arr_j}[i]$ for $i \\in [0, n-1]$. Once this, in addition to the product check, has been done, we have shown that $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ for some undisclosed permutation $\\pi$.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ generates the random challenge $r$ and computes $\\mathsf{Arr_j}'$ as follows for $j \\in [1,2]$: $\\mathsf{Arr_j}'[i]= r - \\mathsf{Arr_j}[i]$ Polynomial Level # We assume that $\\mathsf{Arr_1}$, $\\mathsf{Arr_2}$, $\\mathsf{Arr_1'}$, and $\\mathsf{Arr_2'}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the arrays, the arrays can be padded with elements all of value 1 (or any other value, as long as it is the same for both arrays).\nRecall the two steps we want to prove:\n$\\prod^{n-1}_{i=0}\\{r - \\mathsf{Arr_1[i]}\\} = \\prod^{n-1}_{i=0}\\{r - \\mathsf{Arr_2[i]}\\}$ $\\mathsf{Arr_j}'[i]= r - \\mathsf{Arr_j}[i]$ for $j \\in [1,2]$, $0 \\leq 1 \\leq n-1$ The first step is done as a mult3 product check, and we write the second step as two constraints in polynomial form. From this point on we focus on the polynomial details of the second step.\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_1'}(X) = (r - \\mathsf{Poly}_\\mathsf{Arr_1}(X))$ For all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_2'}(X) = (r - \\mathsf{Poly}_\\mathsf{Arr_2}(X))$ We adjust each of these constraints to show an equality with 0 and label them:\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)= \\mathsf{Poly}_\\mathsf{Arr_1'}(X) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(X)) = 0$ $\\mathsf{Poly}_\\mathsf{Vanish2}(X)= \\mathsf{Poly}_\\mathsf{Arr_2'}(X) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(X)) = 0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$ and $Q_2(X)$ with a single polynomial $Q(X)$. We can do this because both constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with both $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if both are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho}{X^\\kappa - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the shuffle1 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial In addition, it will show that $\\prod^{n-1}_{i=0}(r - \\mathsf{Arr_1}[i]) = \\prod^{n-1}_{i=0}(r - \\mathsf{Arr_2}[i])$ using a mult3 product check.\nCommitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will create a transcript for the product check, as described in mult3. Below, we give details specific to the second step, showing that $\\mathsf{Arr_j}'[i]= r - \\mathsf{Arr_j}[i]$ for $j \\in [1,2]$, $0 \\leq 1 \\leq n-1$.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$ $K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call this point $r$. It will use this point to define the sets $ \\{r - \\mathsf{Poly}_\\mathsf{Arr_j}(a) \\}_{a \\in \\mathcal{H}_\\kappa}$ and run the product check. It will write the product check into the transcript. However, here we focus only on what is relevant to the second step, the point $r$ and the following polynomials, which it also writes to the transcript:\n$r$ $K_\\mathsf{Arr_1'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1'}(X))$ $K_\\mathsf{Arr_2'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2'}(X))$​ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1'},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2'},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}= \\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))$ $Y_\\mathsf{Vanish2}= \\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Security Proof # Completeness # We assume completeness of the product check (it is proven in mult3) and conduct a proof of completeness for the rest of the protocol.\nIf $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ such that $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1)$, can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))] + \\rho [\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))] - Q(\\zeta) \\cdot (\\zeta^\\kappa - 1)$\n$= [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))] + \\rho [\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))] - \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta)}{X^\\kappa - 1} \\cdot (\\zeta^\\kappa - 1)$\n$= [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))] + \\rho [\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))] - [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)) + \\rho[\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))]]$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(X)$ is divisible by $X^\\kappa -1$. This is true if $\\mathsf{Poly_{Vanish1}}(\\zeta)$ and $\\mathsf{Poly_{Vanish2}}(\\zeta)$ are vanishing on $\\mathcal{H}_\\kappa$, i.e. if $\\mathsf{Poly}_\\mathsf{Arr_1'}(X) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(X)) = 0$ and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(X)) = 0$, $X \\in \\mathcal{H}_\\kappa$. This is true if $\\mathsf{Arr}_1'[i] - (r - \\mathsf{Arr}_1[i]) = 0$ and $\\mathsf{Arr}_2'[i] - (r - \\mathsf{Arr}_1[i]) = 0$, $\\forall 0 \\leq i\\leq \\kappa$, since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$ and $\\mathsf{Poly_j}'(\\omega^i) = \\mathsf{Arr_j}'[i] \\space \\forall i \\in [0, \\kappa - 1]$. But this is precisely how the honest prover defines $\\mathsf{Arr}_1'$ and $\\mathsf{Arr}_2'$, so the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and the transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). We assume soundness of the product check (it is proven in mult3) and conduct a proof of soundness for the rest of the protocol. To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$, the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Arr}_2 \\neq \\mathsf{Permute}(\\mathsf{Arr}_1)$\nOur proof is as follows:\nFor the second win condition to be fulfilled, there must be some $a \\in \\mathsf{Arr_2}, a \\notin \\mathsf{Arr_1}$, or vice versa. Since $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ have different entries, $\\prod^{n-1}_{i = 1}(X - \\mathsf{Arr_1}[i])$ and $\\prod^{n-1}_{i = 1}(X - \\mathsf{Arr_2}[i])$ have different factorizations and are thus different polynomials. By the Schwartz-Zippel lemma, there is negligible probability that they are equal at $r$ (thus the product check will fail). Any strategy to increase this probability to greater than negligible means $\\mathcal{A}$ must pass in $\\mathsf{Arr_j'}$ such that $\\mathsf{Arr_j'}[i] \\neq r - \\mathsf{Arr_j}[i]$ for some index $i$ and $j \\in [1, 2]$. But then $\\mathsf{Poly}_\\mathsf{Vanish_j}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$. All commitments $\\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta)$ can each only feasibly be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2}}{(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We assume the product check is zero-knowledge (it is proven in mult3), and conduct a proof for the rest of the protocol. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$ and ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$ and $g^{\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$ to write as the commitments $ K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_1}$. $\\mathcal{S}$ then generates the random challenge $r$ (by strong Fiat-Shamir). It chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1'}(\\tau)}$ and ${\\mathsf{Poly}_\\mathsf{Arr_2'}(\\tau)}$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1'}(\\tau)}$ and $g^{\\mathsf{Poly}_\\mathsf{Arr_2'}(\\tau)}$ to write as the commitments $ K_\\mathsf{Arr_1'}$ and $K_\\mathsf{Arr_1'}$. It creates a view of the product check as described in the zero-knowledge proof for mult3.\n$\\mathcal{S}$ generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_1'}(\\tau)}$, and ${\\mathsf{Poly}_\\mathsf{Arr_2'}(\\tau)}$. $\\mathcal{S}$ outputs the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta)}$, and ${\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta)}$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":17,"href":"/docs/gadgets/shuffle2/","title":"Shuffle2","section":"Gadgets","content":" Shuffle (Type 2) # Recap of types # Type Description Recap This shuffle1 $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1)$ Array $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ for some undisclosed permutation $\\pi$. shuffle2 $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1 ,\\pi)$ Array $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ under a disclosed permutation $\\pi$. ✅ Relation # $\\mathcal{R}_{\\mathtt{shuffle2}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr2}, K_\\pi) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}],\\\\ \\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}], \\\\ \\mathsf{Arr_\\pi} = [\\pi(\\omega^0), \\pi(\\omega^1), \\pi(\\omega^2), \\dots, \\pi(\\omega^{n-1})], \\\\ \\mathsf{Poly}_\\mathsf{Arr_1}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_1}), \\\\ \\mathsf{Poly}_\\mathsf{Arr_2}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_2}), \\\\ \\mathsf{Poly_\\pi} = \\mathsf{FFT.Interp}(\\omega, \\mathsf{Arr_\\pi}), \\\\ K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}),\\\\ K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}),\\\\K_\\pi = \\mathsf{KZG.Commit(Poly_{\\pi})} \\end{array} \\right\\}$\nIntuition # The prover ($\\mathcal{P}$) holds 2 arrays, $\\mathsf{Arr_1 }$ and $\\mathsf{Arr_2}$, of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It also holds an array $\\mathsf{Arr_\\pi}$, which represents the disclosed permutation $\\pi$. It will produce a succinct (independent of $n$) proof that $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ under the disclosed permutation $\\pi$. The prover will encode the three arrays into polynomials, $\\mathsf{Poly}_\\mathsf{Arr_1}$, $\\mathsf{Poly}_\\mathsf{Arr_2}$, and $\\mathsf{Poly_\\pi}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to them as $K_\\mathsf{Arr_1}$, $K_\\mathsf{Arr_2}$, and $K_\\pi$. The verifier ($\\mathcal{V}$) cannot check any array directly ($\\mathsf{Arr_1 }$ and $\\mathsf{Arr_2}$ may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$, $K_\\mathsf{Arr_2}$ and $K_\\pi$.\nThe idea behind this check is that if $(\\mathsf{Arr_\\pi}[i], \\mathsf{Arr_2}[i]) = (i, \\mathsf{Arr_1}[i])$ for all $0 \\leq i \\leq n-1$, then $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1 ,\\pi)$. To gain some intuition on why this is true, pair up tuples from the left and right hand sides of the equation by matching the first entries. Then, if each pair is equal, it means that $\\mathsf{Arr_2}[i] = \\mathsf{Arr_1}[\\mathsf{Arr_\\pi}[i]]$ for $0 \\leq i \\leq n-1$. In other words, $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1 ,\\pi)$.\nTo check that $(\\mathsf{Arr_\\pi}[i], \\mathsf{Arr_2}[i]) = (i, \\mathsf{Arr_1}[i])$ for all $0 \\leq j \\leq n-1$, we use a similar trick to shuffle1. The prover constructs two arrays: $\\mathsf{Arr_1'} = \\{ r - s\\cdot i - \\mathsf{Arr_1}[i]\\}_{i \\in [0, n-1]}$ and $\\mathsf{Arr_2'} = \\{ r - s\\cdot\\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i]\\}_{i \\in [0, n-1]}$ for random field elements $r, s$. Then, a product check is conducted on the two arrays. One way to understand why this works is to think of it as creating two auxiliary polynomials, ${\\mathsf{Poly}}_\\mathsf{Arr_1'}$ and ${\\mathsf{Poly}}_\\mathsf{Arr_2'}$. Here, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X) = \\prod^{n-1}_{i = 1}(X - Y\\cdot i - \\mathsf{Arr_1}[i])$ and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X) = \\prod^{n-1}_{i = 1}(X - Y\\cdot \\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i])$. If ${\\mathsf{Poly}}_\\mathsf{Arr_1'}$ = $\\mathsf{Poly}_\\mathsf{Arr_2'}$, then they have the same factorization. This means that $\\mathsf{Arr}_1'$ and $\\mathsf{Arr}_2'$ must contain the same elements (in possibly different orders). By the same intuition of matching first entries as above (in this case, we are pairing up factors where $i$ in $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$ equals $\\mathsf{Arr_\\pi}[i]$ in $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$) this shows that $\\mathsf{Arr}_2$ is a permutation of $\\mathsf{Arr}_1$ under $\\pi$. To check the equality of the two auxiliary polynomials, random challenge values $r$ and $s$ are generated and the products are checked at that point. If they are equal at that point then (with overwhelming probability) the polynomials are equal.\nIn addition to demonstrating the equality of the product of $\\mathsf{Arr_1}'$ and $\\mathsf{Arr_2}'$, it must also be shown that these two arrays are defined correctly in terms of the original arrays. In other words, it must be shown that $\\mathsf{Arr_1}'[i]= (i, \\mathsf{Arr_1}[i])$ and $\\mathsf{Arr_2}'[i]= (\\mathsf{Arr_\\pi}[i], \\mathsf{Arr_2}[i])$. Once this, in addition to the product check, has been done, it has been shown that $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ under the disclosed permutation $\\pi$.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$​) $\\mathcal{P}$ holds an array $\\mathsf{Arr_\\pi} = [\\pi(\\omega^0), \\pi(\\omega^1), \\pi(\\omega^2), \\dots, \\pi(\\omega^{n-1})]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ generates the random challenge $r, s$ and computes $\\mathsf{Arr_1}'$ as follows: $\\mathsf{Arr_1}'[i]= r - s\\cdot i - \\mathsf{Arr_1}[i]$ $\\mathcal{P}$ computes $\\mathsf{Arr_2}'$ as follows: $\\mathsf{Arr_2}'[i]= r - s\\cdot \\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i]$ Polynomial Level # We assume that $\\mathsf{Arr_1}$, $\\mathsf{Arr_2}$, $\\mathsf{Arr_\\pi}[i]$, $\\mathsf{Arr_1'}$, and $\\mathsf{Arr_2'}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the arrays, the arrays can be padded with elements all of value 1 (or any other value, as long as it is the same for both arrays).\nRecall the two components we want to prove. First, the product check:\n$\\prod^{n-1}_{i = 1}(r - s\\cdot i - \\mathsf{Arr_1}[i]) = \\prod^{n-1}_{i = 1}(r - s\\cdot \\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i])$\nAs well as the two constraints:\n$\\mathsf{Arr_1}'[i]= r - s\\cdot i - \\mathsf{Arr_1}[i]$ $\\mathsf{Arr_2}'[i]= r - s\\cdot \\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i]$ The first component is done as a mult3 product check, and we write the second component in polynomial form. From this point on we focus on the polynomial details of the second component.\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_1'}(X) = r - s\\cdot X - \\mathsf{Poly}_\\mathsf{Arr_1}(X)$ For all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_2'}(X) = r - s\\cdot \\mathsf{Poly_\\pi}(X) - \\mathsf{Poly}_\\mathsf{Arr_2}(X)$ We adjust each of these constraints to show an equality with 0 and label them:\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)= \\mathsf{Poly}_\\mathsf{Arr_1'}(X) - (r - s\\cdot X - \\mathsf{Poly}_\\mathsf{Arr_1}(X)) = 0$ $\\mathsf{Poly}_\\mathsf{Vanish2}(X)= \\mathsf{Poly}_\\mathsf{Arr_2'}(X) - (r - s\\cdot \\mathsf{Poly_\\pi}(X) - \\mathsf{Poly}_\\mathsf{Arr_2}(X)) = 0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$ and $Q_2(X)$ with a single polynomial $Q(X)$. We can do this because both constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with both $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if both are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho}{X^n - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(X) - Q(X)\\cdot (X^n - 1)=0$\nUltimately the shuffle1 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly_\\pi(X)}$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial In addition, it will show that $\\prod^{n-1}_{i = 1}(X - Y\\cdot i - \\mathsf{Arr_1}[i]) = \\prod^{n-1}_{i = 1}(X - Y\\cdot \\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i])$ using a mult3 product check.\nCommitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will create a transcript for the product check, as described in mult3. Below, we give details specific to the second component, verifying the two constraints.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$ $K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$​ $K_\\pi = \\mathsf{KZG.Commit(Poly_\\pi}(X))$ The prover will generate two random challenge evaluation points (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call these points $r$ and $s$. It will use these points to define the arrays $\\mathsf{Arr_1'} = \\{ r - s\\cdot i - \\mathsf{Arr_1}[i]\\}_{i \\in [0, n-1]}$ and $\\mathsf{Arr_2'} = \\{ r - s\\cdot\\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i]\\}_{i \\in [0, n-1]}$ and run the product check. It will write the product check into the transcript. However, here we focus only on what is relevant to the second component, the points $r$ and $s$ and the following polynomials, which are also written to the transcript:\n$r$ $K_\\mathsf{Arr_1'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1'}(X))$ $K_\\mathsf{Arr_2'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2'}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$​ $\\mathsf{Poly_\\pi}(\\zeta) = \\mathsf{KZG.Open}(K_\\pi, \\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1'},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2'},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}= \\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - s\\cdot \\zeta - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))$ $Y_\\mathsf{Vanish2}= \\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - s\\cdot \\mathsf{Poly_\\pi}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} - Q(\\zeta)\\cdot (\\zeta^n - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Security Proof # Completeness # We assume completeness of the product check (it is proven in mult3) and conduct a proof of completeness for the rest of the protocol.\nIf $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ such that $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1)$, can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - s \\cdot \\zeta - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))] + \\rho [\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - s\\cdot\\mathsf{Poly_{\\pi}(\\zeta)} - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))] - Q(\\zeta) \\cdot (\\zeta^\\kappa - 1)$\n$= [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - s\\cdot\\zeta - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))] + \\rho [\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - s\\cdot \\mathsf{Poly_\\pi}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))] - \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta)}{X^\\kappa - 1} \\cdot (\\zeta^\\kappa - 1)$\n$= [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - s\\cdot\\zeta - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))] + \\rho [\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - s\\cdot \\mathsf{Poly_\\pi}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))] \\newline - [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - s\\cdot\\zeta - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)) + \\rho[\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - s\\cdot\\mathsf{Poly_\\pi}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))]]$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(X)$ is divisible by $X^\\kappa -1$. This is true if $\\mathsf{Poly_{Vanish1}}(\\zeta)$ and $\\mathsf{Poly_{Vanish2}}(\\zeta)$ are vanishing on $\\mathcal{H}_\\kappa$, i.e. if $\\mathsf{Poly}_\\mathsf{Arr_1'}(X) - (r - s\\cdot\\zeta - \\mathsf{Poly}_\\mathsf{Arr_1}(X)) = 0$ and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X) - (r - s\\cdot \\mathsf{Poly_\\pi}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_2}(X)) = 0$, $X \\in \\mathcal{H}_\\kappa$. This is true if $\\mathsf{Arr}_1'[i] - (r - s\\cdot i - \\mathsf{Arr}_1[i]) = 0$ and $\\mathsf{Arr}_2'[i] - (r - s \\cdot \\mathsf{Arr}_\\pi(i) - \\mathsf{Arr}_1[i]) = 0$, $\\forall 0 \\leq i\\leq \\kappa$, since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$, $\\mathsf{Poly_j}'(\\omega^i) = \\mathsf{Arr_j}'[i] \\space \\forall i \\in [0, \\kappa - 1]$, and since $\\mathsf{Poly_\\pi}(\\omega^i) = \\mathsf{Arr_\\pi}[i] \\space \\forall i \\in [0, \\kappa - 1]$ . But this is precisely how the honest prover defines $\\mathsf{Arr}_1'$ and $\\mathsf{Arr}_2'$, so the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and the transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). We assume soundness of the product check (it is proven in mult3) and conduct a proof of soundness for the rest of the protocol. To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly_\\pi}$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly_\\pi}$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Arr}_2 \\neq \\mathsf{Permute}(\\mathsf{Arr}_1 ,\\pi)$\nOur proof is as follows:\nFor the second win condition to be fulfilled, it must be that $(\\mathsf{Arr_\\pi}[i], \\mathsf{Arr_2}[i]) \\neq (i, \\mathsf{Arr_1}[i])$ for some $i \\in [0, n-1]$. But then, $\\mathsf{Arr_1'}$ and $\\mathsf{Arr_2'}$ contain differing element. This means that $\\mathsf{Poly}_\\mathsf{Arr_1'}(X) = \\prod^{n-1}_{i = 1}(X - Y\\cdot i - \\mathsf{Arr_1}[i])$ and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X) = \\prod^{n-1}_{i = 1}(X - Y\\cdot \\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i])$ and different polynomials, and thus by the Schwartz-Zippel lemma, there is negligible probability that they are equal at $X=r$ and $Y=2$ for the random challenge $r, s$ (thus the product check will fail). Any strategy to increase this probability to greater than negligible means $\\mathcal{A}$ must pass in $\\mathsf{Arr_j'}$ for $j = 1$ or $j = 2$ that is not defined according to the its corresponding constraint. But then $\\mathsf{Poly}_\\mathsf{Vanish_j}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calculated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly_\\pi}$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$. All commitments $\\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)$, $\\mathsf{Poly_\\pi(\\zeta)}$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta)$ can only feasibly be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2}}{(\\zeta^n - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2}}{(\\zeta^n - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We assume the product check is zero-knowledge (it is proven in mult3), and conduct a proof for the rest of the protocol. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, and $\\mathsf{Poly_\\pi}(\\tau)$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, $g^{\\mathsf{Poly_\\pi}(\\tau)}$ to write as the commitments $ K_\\mathsf{Arr_1}$, $K_\\mathsf{Arr_1}$, $K_\\pi$. $\\mathcal{S}$ then generates $r$ and $s$ as values for the random challenge (by strong Fiat-Shamir). It then chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1'}(\\tau)}$ and ${\\mathsf{Poly}_\\mathsf{Arr_2'}(\\tau)}$, computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1'}(\\tau)}$ and $g^{\\mathsf{Poly}_\\mathsf{Arr_2'}(\\tau)}$ to write as the commitments $ K_\\mathsf{Arr_1'}$ and $K_\\mathsf{Arr_1'}$. It creates a view of the product check as described in the zero-knowledge proof for mult3.\n$\\mathcal{S}$ generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, $\\mathsf{Poly_\\pi}(\\tau)$, ${\\mathsf{Poly}_\\mathsf{Arr_1'}(\\tau)}$, and ${\\mathsf{Poly}_\\mathsf{Arr_2'}(\\tau)}$. $\\mathcal{S}$ outputs the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the second random challenge, $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)}$, $\\mathsf{Poly_\\pi}(\\zeta)$, ${\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta)}$, and ${\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta)}$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2}}{(\\zeta^n - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":18,"href":"/docs/gadgets/zero1/","title":"Zero1","section":"Gadgets","content":" Zero (Type 1) # Recap of types # Type Description Recap This zero1 $\\mathsf{Arr}[i]\\leftarrow0$ Zero-out elements of an array $\\mathsf{Arr}$ such as: all, first, last, all-but-first, all-but-last. ✅ zero2 $\\mathsf{Arr}[i]\\leftarrow0$ iff $\\mathsf{Sel}[i]=0$ Zero-out elements of an array $\\mathsf{Arr}$ according to a binary array $\\mathsf{Sel}$. Subtypes of $\\texttt{zero1}$ # Operation Output Array Zero all $\\langle 0,0,0,0,0 \\rangle$ Zero first $\\langle 0,\\bot,\\bot,\\bot,\\bot \\rangle$ Zero last $\\langle \\bot,\\bot,\\bot,\\bot,0 \\rangle$ Zero all but first $\\langle \\bot,0,0,0,0 \\rangle$ Zero all but last $\\langle 0,0,0,0,\\bot \\rangle$ Relation # Shown for \u0026ldquo;zero last\u0026rdquo; but can be adapted to the other sub-types of $\\texttt{zero1}$:\n$ \\mathcal{R}_{\\mathtt{mult2}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr},K_\\mathsf{Arr'}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr} = [a_0, a_1, \\dots, a_{n-2}, a_{n-1}], \\\\ \\mathsf{Arr'} = [a'_0, a'_1, \\dots, a'_{n-2}, 0], \\\\ \\mathsf{Poly}_\\mathsf{Arr}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}), \\\\ \\mathsf{Poly}_\\mathsf{Arr'}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr'}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}) \\\\ K_\\mathsf{Arr'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr'}) \\end{array} \\right\\} $\nIntuition # This gadget is a helper gadget that is not very useful as a stand-alone gadget, but is used in nearly all other gadgets to handle things like boundary conditions (see Red Tape). The semantics of the gadget might seem weird but eventually you will see it in use (e.g., $\\texttt{add2}$). The prover ($\\mathcal{P}$) holds an array $\\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers (from $\\mathbb{Z}_q$). It will produce a succinct (independent of $n$) proof that $\\mathsf{Arr'}$ contains a 0 at a selected element (such as the last element). At the other elements, the operation is zero-preserving, meaning it will not replace a 0 in $\\mathsf{Arr}$. If an element in $\\mathsf{Arr}$ is non-zero and the\nit contains $\\bot$ which is an arbitrary integer\nthe same at every element\n$\\mathsf{Prod}_\\mathsf{Arr}$ is the product of all the elements in the array. The prover will encode the array into a polynomial $\\mathsf{Poly}_\\mathsf{Arr}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to the polynomial $K_\\mathsf{Arr}$. The verifier ($\\mathcal{V}$) cannot check $\\textsf{Arr}$ or $\\mathsf{Poly}_\\mathsf{Arr}$ directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr}$ and the asserted value $\\mathsf{Prod_\\mathsf{Arr}}$.Zeroing Parts of an Array\nAssuming an input array of size $n$: $\\langle \\mathsf{data}_0,\\mathsf{data}_1,\\ldots,\\mathsf{data}_{n-1}\\rangle$ and input array encoded into the polynomial. This uses \u0026ldquo;Encoding 2\u0026rdquo; from above (evaluation points) and uses \u0026ldquo;Roots of Unity + FFT\u0026rdquo; from above where $\\omega\\in\\mathbb{G}_\\kappa$ is a generator for the x-coordinates of the points.\n$\\bot$ is an arbitrary non-zero integer.\nOperation Input Array Input Polynomial Output Array Output Polynomial Zero all $\\langle 3,1,3,3,7 \\rangle$ $P(X)$ $\\langle 0,0,0,0,0 \\rangle$ $P(X)\\cdot(X^\\kappa-1)$ Zero first $\\langle 3,1,3,3,7 \\rangle$ $P(X)$ $\\langle 0,\\bot,\\bot,\\bot,\\bot \\rangle$ $P(X)\\cdot(X-\\omega^0)$ Zero last $\\langle 3,1,3,3,7 \\rangle$ $P(X)$ $\\langle \\bot,\\bot,\\bot,\\bot,0 \\rangle$ $P(X)\\cdot(X-\\omega^{\\kappa-1})$ Zero all but first $\\langle 3,1,3,3,7 \\rangle$ $P(X)$ $\\langle \\bot,0,0,0,0 \\rangle$ $P(X)\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}$ Zero all but last $\\langle 3,1,3,3,7 \\rangle$ $P(X)$ $\\langle 0,0,0,0,\\bot \\rangle$ $P(X)\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}$ "},{"id":19,"href":"/docs/gadgets/zero2/","title":"Zero2","section":"Gadgets","content":" Zero (Type 2) # Recap of types # Type Description Recap This zero1 $\\mathsf{Arr}[i]\\leftarrow0$ Zero-out elements of an array $\\mathsf{Arr}$ such as: all, first, last, all-but-first, all-but-last. zero2 $\\mathsf{Arr}[i]\\leftarrow0$ iff $\\mathsf{Sel}[i]=0$ Zero-out elements of an array $\\mathsf{Arr}$ according to a binary array $\\mathsf{Sel}$. ✅ Zeroing Parts of an Array (2) # Assume both $\\mathsf{Arr}$ (an array of data) and $\\mathsf{Sel}$ (a binary array) are of size $n$. They are encoded as the y-coordinates into univariant polynomials where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. We call our polynomials $\\mathsf{Poly}_\\mathsf{Arr}(X)$ and $\\mathsf{Poly}_\\mathsf{Sel}(X)$. The goal is to construct an output polynomial where all the elements in $\\mathsf{Arr}$ that share an index with a zero in $\\mathsf{Sel}$ are zeroed (and non-zero elements in $\\mathsf{Arr}$ that share an index with a one in $\\mathsf{Sel}$ are kept non-zero).\nNote that $\\mathsf{Poly}_\\mathsf{Sel}(X)$ has a root at every point in $\\mathcal{H}_\\kappa$ that corresponds to a zero entry in $\\mathsf{Sel}$, since it has a $y$ value of zero at each of these values of $x$. Denote this set of roots $R = [r_0, r_1, \\dots, r_{m-1}]$, where $m$ is the number of zero entries in $\\mathsf{Sel}$. Denote also $S = [s_0, s_1, \\dots, s_{l-1}]$ the (possibly empty) set of remaining roots of $\\mathsf{Poly}_\\mathsf{Sel}(X)$, for some $l \\in \\mathbb{N}$. Then written in factored form we have $\\mathsf{Poly}_\\mathsf{Sel}(X) = \\prod^{i \\lt m}_{i = 0} (X - r_i) \\cdot \\prod^{i \\lt l}_{i=0}(X-s_i) \\cdot R(X)$ for some $R(X) = \\frac{\\mathsf{Poly}_\\mathsf{Sel}(X)}{\\prod^{i \\lt m}_{i = 0} (X - r_i) \\cdot \\prod^{i \\lt l}_{i=0}(X-s_i)}$. Note that $R(X)$ is indeed a polynomials, and that it has no roots over the field.\nNow, consider $\\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot \\mathsf{Poly}_\\mathsf{Sel}(X) = \\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot \\prod^{i \\lt m}_{i = 0} (X - r_i) \\cdot \\prod^{i \\lt l}_{i=0}(X-s_i) \\cdot R(X)$. First, note it has roots at each $r \\in R$, thus this new polynomial has zeroed out all the elements of $\\mathsf{Arr}$ corresponding to a zero entries in $\\mathsf{Sel}$. Further, the only other roots it has are from $S$, or are roots that were already part of $\\mathsf{Poly}_\\mathsf{Arr}(X)$. Since no value $s \\in S$ is also in $\\mathcal{H}_\\kappa$, all non-zero entries in $\\mathsf{Arr}$ are left non-zero.Thus, $\\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot \\mathsf{Poly}_\\mathsf{Sel}(X)$ is our desired output polynomial.\n"},{"id":20,"href":"/docs/background/overview/","title":"Overview","section":"Background","content":" Overview # Preliminaries # While we may add more background in future iterations, for now we punt on explaining the following concepts and assume you are already familiar with them:\nElliptic curve cryptography Hardness of the discrete logarithm problem and related problems Pairing-based cryptography at a \u0026ldquo;black-box\u0026rdquo; level (what it does, not necessarily how it works) Resources: Lecture (Boneh) Commitment schemes Properties: hiding and binding Construction: Pedersen Commitments Resources: Lecture (Boneh) Zero knowledge proofs (high level idea) Properties: completeness, soundness, zero-knowledge Resources: Lecture (Goldwasser) zk-SNARKs # Plonk is a zk-SNARK proof system. In such a system, one entity (the prover) executes a function $f$ on a set of inputs (say $x,y$) and produces output $z=f(x,y)$. It then issues a proof $\\pi$ that $z$ is correct. It can show $\\pi$ to anyone and it will convince them (the verifier) that $z$ is correct.\nWhat are the assumptions about the function, inputs, and outputs?\nFunction:\n$f$ can be nearly any function. $f$ must be deterministic, meaning that running $f$ on the same inputs always produces the same output. Randomness can be used but it needs to be an input to the function. $f$ is disclosed to the verifier, meaning that to check $\\pi$ is correct requires a copy of $f$ itself. It is possible to make a private $f$ with a hack, see below (under inputs). In Plonk specifically, $f$ takes the form of a circuit with two kinds of gates: addition (takes two inputs and outputs their sum) and multiplication (takes two inputs and outputs their product). It is technically modular addition and multiplication, where the modulus is a large (for example, 256 bit) prime number. It has been proven that using only these two gates is sufficient to emulate any $f$ that can be implemented in any other kind of circuit (it just might result in a larger circuit to capture the same functionality). To use Plonk in practice, you do not need to program circuits. You can use a special-purpose programming language to write $f$ and compilation tools will convert $f$ into the circuit format that Plonk expects. $f$ has a (quite large) upper-bound on its \u0026ldquo;size\u0026rdquo; (for example, less than 1 trillion gates for efficiency in standard cryptographic settings). Inputs:\n$f$ can have any number of inputs which are typically integers (modulus the large prime). Inputs can be disclosed to the verifier (public inputs), meaning that to check $\\pi$ is correct, the verifier also checks that these were the inputs that were used to produce $z$. Inputs can also be undisclosed (private inputs), meaning the verifier does not see them and does need them to check that $\\pi$ is correct. But what does it mean to check $z$ is correct if the inputs are not disclosed? It proves that the verifier knows some input $x$ such that, given function $f$, public input $y$ and public output $z$ that $z=f(x,y)$. This called a \u0026ldquo;proof of knowledge.\u0026rdquo; The $\\pi$ reveals zero information (or \u0026ldquo;zero knowledge\u0026rdquo;) about $x$ (beyond what you can learn by knowing it is a legal input to $f$ that produces $y$). As inferable from the above example, inputs can be a mix of public and private. Outputs:\nThe output $z$ is disclosed to the verifier, meaning that to check $\\pi$ is correct requires a copy of $z$. $z$ does need to be a single integer, it can be a data structure. Proof Output:\nThe output proof $\\pi$ is succinct, meaning that (for Plonk) it is always the same size regardless of how many gates $f$ has. Checking $\\pi$ is correct is (for Plonk) constant-time, meaning it is always the same amount of time regardless of how many gates $f$ has. So why do we need zk-SNARKs? In the case that some of the inputs are undisclosed/private, it is clear zk-SNARKs let us do something \u0026ldquo;magic,\u0026rdquo; prove things about inputs that we are not disclosing. In the case that all inputs are disclosed/public (we call this a SNARK rather than zk-SNARK), note that the verifier knows all values $x,y,f,z$ in $z=f(x,y)$. If the verifier wants to know if $z$ is correct, it does not need a proof $\\pi$, it can just execute $f$ for itself on $x,y$ and see that the output is $z$.\nAt first glance, SNARKs (rather than zk-SNARKs) seem useless but remember that proof outputs are succinct and constant-time. For this reason, it might be cheaper (in terms of time and memory) for the verifier to check $\\pi$ than to re-execute $f$. Whether it is cheaper or not basically comes down to how complex $f$ is. If $f$ is simple, re-executing it will be fastest. But once $f$ becomes sufficiently complex, it will be cheaper to verify $\\pi$. What is sufficiently complex? Roughly any $f$ that would take, say, a millisecond or more to run on a normal device.\nLast, it is important to recognize we are not getting something for \u0026ldquo;free\u0026rdquo; here. In order for the verifier to enjoy fast verification of $f$, someone else (the prover) had to execute $f$ and generate a proof $\\pi$ for $f$ which is substantially more work than just running $f$. So the prover does extra work to save the verifier work. What are some models where this kind of trade-off makes sense for SNARKs (rather than zk-SNARKs)? There are probably many more, but the two big ones are:\nCase 1: there is a powerful (but not trusted) computer like a cloud service and a smaller constrained device (like a phone with battery life). Additionally, the economics need to make sense for the cloud to execute on behalf of the smartphone (fees, subscription, service offered by phone manufacturer, \u0026hellip;). Case 2: there are many verifiers that want to verify the same thing so the system scales better if one party executes and issues a proof $\\pi$ and the verifiers all check the proof rather than re-executing the function. Plonk \u0026amp; its gadgets # There are numerous ways to implement a zk-SNARK system. Plonk uses a templated called a polynomial interactive oracle proof (or Poly-IOP). The next background article will go into more detail about it. Roughly, the prover stores inputs, outputs, gates, and intermediate values in one-dimensional arrays (or vectors). It will also perform a set of operations on the arrays to prove the circuit is executed correctly. Generally proving that array operations are done correctly will require proofs that are proportional (in size and time) to the length of the array.\nThe trick to avoiding this is two-fold: first, the array will be encoded into a polynomial (univariate meaning a single variable) and every operation that is done on the array can be \u0026ldquo;mirrored\u0026rdquo; on the polynomial representation of the array. Second, the verifier will not receive the polynomials themselves but rather a short commitment to them. Again, every operation being done on the arrays and polynomials need to be mirrored on the commitments to the polynomials so the verifier can follow along.\nIn order to work, Plonk establishes a set of Poly-IOP building blocks (or gadgets) and combines them into a somewhat involved protocol that proves a circuit is executed correctly. Once this is done, anyone can write any function into a circuit and have Plonk\u0026rsquo;s circuit gadget prove it is executed correctly.\nflowchart LR Succinctness --\u003e Poly-IOP Poly-IOP --\u003e Univariate Univariate --\u003e Gadgets subgraph Gadgets zero-.-\u003eadd rotate-.-\u003eadd zero-.-\u003emult rotate-.-\u003emult mult-.-\u003eshuffle encode-.-\u003ecircuit shuffle-.-\u003ecircuit add-.-\u003elookup shuffle-.-\u003elookup lookup-.-\u003ecircuit mult-.-\u003erange circuit end Gadgets --Special Purpose--- Protocol1(Function) circuit --General Purpose--- Protocol2(Function) classDef color fill:#9f6; class Protocol1 color class Protocol2 color This gadget book is not for writing Plonk circuits. Writing Plonk circuits is one method for proving a function is correctly executed and is a general purpose method that works for any function. The second method is to realize that the building blocks of Plonk can be used directly, if they are verbose enough to capture what you want $f$ to do. It is a special purpose method, meaning it will not work for all $f$ but if it does work, it should be intuitive that this will be considerably faster for the prover. It is also possible to do a hybrid approach where certain parts of a general purpose circuit are replaced with gadgets and then glued back to the circuit.\n"},{"id":21,"href":"/docs/background/kzg/","title":"PCS","section":"Background","content":" Polynomial Commitment Schemes (PCS) # Comparing Polynomials # Say that Carol sends a polynomial to Alice and the same polynomial to Bob. Later Alice and Bob are sitting together and want to make sure their polynomials, which they got from Carol, are actually the same. How do you compare polynomials? There are many sufficient comparisons, but here are two ways to get started:\nEnsure the degree $d$ is the same and each coefficient is the same, Ensure the degree $d$ is the same and check at $d+1$ unique points. Say Alice and Bob go with the second method for their polynomials from Carol, which are both degree 1000. They start checking points and after checking 500 points, the polynomials are the same so far. How confident are they that they have the same polynomial? They are not 100% confident until they check all $d+1$ points but should they be more than 0% confident?\nImagine Carol is trying to trick them with different polynomials. If Carol knows Alice and Bob will check $P(0),P(1),P(2),\\ldots,P(d+1)$, she can make sure the polynomials are the same at the first set of points, hoping they give up early. So Alice and Bob should be 0% confident after checking 500 points if they know Carol is malicious.\nHowever if Alice and Bob choose random points to compare at, then Carol has to get \u0026ldquo;lucky\u0026rdquo; and hope the polynomials happen to be the same at each of the random points. The nice thing is we can quantify what \u0026ldquo;lucky\u0026rdquo; means for Carol. Two polynomials of degree $d$ can only match at $d$ points (even if the polynomials are very similar to each, say differing only by one coefficient). Every time Alice and Bob check a random point, the probability that Carol gets lucky and does not get caught presenting different polynomials is $\\frac{d}{q}$ where $q$ is the number of points on the polynomial (all values in $\\mathbb{Z}_q$). In a cryptographic setting, $q$ will be a large prime. If $q$ is 256-bits and the polynomial is degree 1000, then the probability Carol can get away with cheating after the first check is $\\frac{1000}{2^{256}}$, which is already negligibly small. So after checking just one random point, Alice and Bob are pretty confident the polynomials are the same if the point matches. Specifically, probability $1-\\frac{1000}{2^{256}}$ which is close enough to 1 for practical purposes:\n$0.99999999999999999999999999999999999999999999999999999999999999999999999999136383\\ldots$\nSo we can add a third probabilistic method for Alice and Bob to use in checking their polynomials:\nEnsure the degree $d$ is the same and check at $1$ random point. Compared to Method 2, it is materially less work for Alice and Bob. In mathematics, this result is commonly known as the Schwartz–Zippel1 lemma. We will use this idea in building a commitment scheme for polynomials.\nA Wishlist for Polynomial Commitments # Recall the Pedersen2 commitment scheme, which for message $m$ and randomness $r$ produces commitment value $K_m=\\mathsf{Commit}(m,r)=g^mh^r$. The commitment scheme is hiding which means that examining $K_m$ does not reveal the message $m$ or any information about what $m$ might be. It is also binding which means the person who creates and circulates $K_m$ can later show how $m$ was used to construct $K_m$ but cannot show that for a different value $m'\\neq m$. This comes under the important caveat that $g$ and $h$ are random group elements and the committer does not know the discrete logarithm between them.\nA second property that Pedersen commitments exhibit is an additive homomorphism, where $K_{m_1}\\cdot K_{m_2}=\\mathsf{Commit}(m_1+m_2,r_1+r_2)$. This is sometimes useful for protocols requiring addition.\nA final property to be considered with commitments is how many $m$ values can be committed to and how many $K_m$ values can be produced. Specifically, are they exactly equal, which would make the commitment function one-to-one. Alternatively, it might be one-to-many or many-to-one. Consider a few variants of Pedersen commitments:\nFeldman commitment: $\\mathsf{Commit}(m)=g^m$ is one-to-one (but not hiding as you can check if your guess at $m$ is right or not). $m\\in\\mathbb{Z}_q$ restricted to exponent group. Hashed Pedersen commitment: $\\mathsf{Commit}(m,r)=g^{\\mathcal{H}(m)}h^r$ is many-to-one for collision-resistant hash function $\\mathcal{H}$. $m\\in\\{0,1\\}^*$ can be any bit-string of any length. Pedersen multi-commitment: $\\mathsf{Commit}(m_1,m_2,m_3,r)=g_1^{m_1}g_2^{m_2}g_3^{m_3}h^r$ is many-to-one. $m_i\\in\\mathbb{Z}_q$ restricted to exponent group. Elgamal: $\\mathsf{Commit}(m,r)=\\{g^r,g^{m}h^r\\}$ is one-to-many. $m\\in\\mathbb{Z}_q$ restricted to exponent group. Next, let us consider committing to polynomials. We can use any of the above schemes to commit to a complete description of a polynomial, where a complete description might be its coefficients, all of its roots, or a sufficient set of points on the polynomial. However we can also consider making a special purpose commitment function for polynomials that might allow us some useful things for dealing with polynomials. A wishlist for a polynomial scheme might look as follows:\nBinding: necessary for commitments. (Optionally) hiding: necessary for using the commitment for zk-SNARKs but not necessary for just SNARKs. Useful homomorphisms: Polynomial addition Polynomial multiplication Selective opening: demonstrating a single chosen point on a polynomial without revealing the rest of the polynomial. Many-to-one (succinct): having $K_{P(X)}$ be constant-size regardless of how \u0026ldquo;big\u0026rdquo; (the degree) polynomial $P(X)$ is. The Kate-Zaverucha-Goldberg (KZG) polynomial commitment scheme gives us most of the above properties. Polynomial multiplication has a little red tape around it but the rest of the properties follow directly from KZG. KZG is only for univariant polynomials (which is all we will use in Plonkbook) however many research papers have shown how to adapt it to multivariant polynomials.\nKZG Commitments # Starting Point # KZG commitments will commit to a univariate polynomial assuming it is in coefficient form. That is: $$ P(\\square)=c_0+c_1\\cdot\\square+c_2\\cdot\\square^2+c_3\\cdot\\square^3+c_4\\cdot\\square^4=\\sum_{i=0}^d c_i\\cdot\\square^i $$ The rough idea is that a commitment will be $K_{P(\\square)}=\\mathsf{Commit}(P(\\square), r)=g^{P(\\square)}h^r$. For simplicity, we will describe the simpler version that is not hiding: $K_{P(\\square)}=\\mathsf{Commit}(P(\\square))=g^{P(\\square)}$.\nWhat does it mean to commit to $P(\\square)$ without specifying what $\\square$ is? Recall that $\\square$ can take on any value (in $\\mathbb{Z}_q$). Probably the most intuitive idea is to use the multi-commitment (above) to commit to the coefficients: $\\mathsf{Commit}(c_0,c_1,c_2,c_3)=g_0^{c_0}g_1^{c_1}g_2^{c_2}g_3^{c_3}$. This hits a few items on our wish list: it is binding, could be hiding (with $h^r$), is additively homomorphic (sum of polynomials is the sum of their coefficients), and is succinct.\nWhat about selective opening? The committer (prover) knows that $y_\\alpha=P(\\alpha)$ for some value $\\alpha$ and wants to prove it. To work toward computing $P(\\alpha)=c_0+c_1\\cdot\\alpha+c_2\\cdot\\alpha^2+c_3\\cdot\\alpha^3$, the prover can create $\\langle \\alpha, \\alpha^2, \\alpha^3\\rangle$ but can the prover get them into the \u0026ldquo;right spot\u0026rdquo; in the commitment: $g_0^{c_0}g_1^{c_1\\cdot\\alpha}g_2^{c_2\\alpha^2}g_3^{c_3\\alpha^3}$? It cannot do it with exponentiation as operations like $(g_0^{c_0}g_1^{c_1}g_2^{c_2}g_3^{c_3})^\\alpha$ will distribute $\\alpha$ to each term: $g_0^{c_0\\cdot\\alpha}g_1^{c_1\\cdot\\alpha}g_2^{c_2\\cdot\\alpha}g_3^{c_3\\cdot\\alpha}$. Even if it got them into the right spot, the prover would have to prove they used the right values. Finally, the prover cannot \u0026ldquo;add\u0026rdquo; the terms up: $g_0^{c_0}g_1^{c_1\\cdot\\alpha}g_2^{c_2\\alpha^2}g_3^{c_3\\alpha^3}\\rightarrow g_0^{c_0+c_1\\cdot\\alpha+c_2\\alpha^2+c_3\\alpha^3}$ without knowing the discrete logarithm between $g_0, g_1, g_2, g_3$ (if it did, it would break the binding property) plus it would have to get rid of the discrete logarithm terms. Anyways, there are three or four roadblocks to adding selective opening to such a commitment.\nKZG takes a different approach. To commit to a polynomial, the idea is to commit to its evaluation at a set of points rather than committing to the coefficients. How many points do we need to commit to? Recall the story about Alice and Bob comparing the polynomials they received from Carol. We concluded that statistically it is sufficient for Alice and Bob to check at $1$ random point.\nThe idea of KZG is to commit to the evaluation of the polynomial at one random point $\\tau$ and have this commitment represent a commitment to the entire polynomial. The important caveat is that no one knows what $\\tau$ is (it is a secret). How do we pull this off? How can the prover figure out the evaluation of their polynomial at $\\tau$ without knowing what $\\tau$ is? And finally, if they can figure out what $P(\\tau)$ is, can they not just reverse engineer what $\\tau$ is (for example, by committing to $y=P(\\tau)=\\tau$)?\nKZG uses a trusted setup to generate a commitment to $\\tau$. It then uses homomorphic operations to let a prover compute a commitment to $P(\\tau)$ using the commitment to $\\tau$ without learning what $\\tau$ is or even what $P(\\tau)$ is. Committing to $P(\\tau)$ is considered as good as committing to the entire polynomial! We will see these details next.\nSetup # Someone trusted chooses a random value (from $\\mathbb{Z}_q$) to use as $\\tau$. They will also generate $d$ powers of $\\tau$ which will be needed to commit to polynomials up to degree $d$. They will commit to each power of $\\tau$ as follows. The output is called a structured random string (SRS) and will be available for the prover to use and the verifier to use:\n$$ \\langle g^{(\\tau^0)}, g^{(\\tau^1)}, g^{(\\tau^2)}, g^{(\\tau^3)}, \\ldots, g^{(\\tau^d)} \\rangle \\equiv SRS $$ What if the person generating the powers of $\\tau$ is not trustworthy? What goes wrong? There are two ways the trusted party can cheat: (1) tell everyone the secret value $\\tau$ (or use it for itself), and (2) generate the SRS with the wrong structure (the values are not successive powers of $\\tau$). We can address both of these issues. To address (1), we can let many parties generate an SRS and combine them into a single SRS. As long as one party deletes $\\tau$ without looking at it, the entire SRS is secure. Many blockchain projects have done this already with thousands of contributors. We can also address (2) through special purpose zero knowledge proofs that demonstrate each contributor\u0026rsquo;s SRS has the correct format without revealing $\\tau$. We will not cover these details but you can learn more from this article (a16z crypto research).\nCommitment # Using the coefficients of the polynomial, the prover can use the SRS to create a commitment to the polynomial evaluated at $\\tau$ as follows: $$ \\begin{align} K_{P(\\tau)}\u0026=\\mathsf{Commit}(P(\\tau))\\\\ \u0026= (g)^{c_0} (g^{\\tau})^{c_1} (g^{\\tau^2})^{c_2} (g^{\\tau^3})^{c_3} \\ldots \\\\ \u0026= g^{c_0 + c_1\\tau + c_2\\tau^2 + c_3\\tau^3 + \\ldots}\\\\ \u0026= g^{P(\\tau)} \\end{align} $$ At the end of the commitment operation, the prover does not know either $\\tau$ nor $P(\\tau)$ and would have to solve a discrete logarithm to learn them. The degree of the polynomial $P(\\square)$ has no impact on the size of $K_{P(\\tau)}$ so it is succinct. However the SRS has to be long enough to have $\\tau^d$ for committing to degree $d$ polynomials.\nCommitment Operations # Open # To completely open the polynomial, the prover will just send the coefficients to the verifier $\\langle c_0,c_1,c_2,c_3,\\ldots \\rangle$ and the verifier will recompute $(g)^{c_0} (g^{\\tau})^{c_1} (g^{\\tau^2})^{c_2} (g^{\\tau^3})^{c_3} \\ldots$ and check it matches $K_{P(\\tau)}$. However this is not very interesting by itself as the prover could have done something simpler like hashing the coefficients. This is why KZG offers additional features tailored to working with polynomials.\nAddition # KZG commitments are homomorphic with respect to the polynomial addition: $K_{P_1(\\tau)}\\cdot K_{P_2(\\tau)}=\\mathsf{Commit}(P_1(\\tau)+P_2(\\tau))$. As is usually the case, scalar multiplication (multiplication by a disclosed integer) can also be performed.\nMultiplication # KZG commitments are not exactly homomorphic with respect to polynomial multiplication but we can get something close. The subtle difference is as follows. For addition, anyone who sees $K_{P_1(\\tau)}$ and $K_{P_2(\\tau)}$ can compute $K_{P_1(\\tau)+P_2(\\tau)}$ directly without involving anyone else. This is not possible with multiplication. However the prover can assert the value for $K_{P_1(\\tau)\\cdot P_2(\\tau)}$ and can convince the verifier it is correct, given $K_{P_1(\\tau)}$ and $K_{P_2(\\tau)}$. The rough idea is to use the bilinear pairing to show: $$ \\begin{align} e(K_{P_1(\\tau)},K_{P_2(\\tau)})\u0026\\stackrel{?}{=}e(K_{P_1(\\tau)+P_2(\\tau)},g)\\\\ e(g^{P_1(\\tau)},g^{P_2(\\tau)})\u0026=e(g^{P_1(\\tau)\\cdot P_2(\\tau)},g) \\\\\u0026=e(g,g)^{P_1(\\tau)\\cdot P_2(\\tau)} \\end{align} $$ There is some red tape with this as the pairing might not be symmetric ($g$ and $h$ are in different groups for $e(g,h)$) and other subtle details. We will show a different approach to multiplications with our $\\texttt{mult}$ gadget.\nSelective Open: Root # The most useful property of KZG (and any polynomial commitment scheme) is being able to open the committed polynomial to certain points. We start with a simple case, the prover wants to show the polynomial is zero at a certain value $P(r)=0$. Recall that $r$ is called a root of the polynomial. Also recall that a set of roots $r_0, r_1, r_2 \\ldots$ can be turned into coefficient form using multiplication: $$ P(\\square)=(\\square-r_0)(\\square-r_1)(\\square-r_2)(\\square-r_3)\\ldots $$ If the prover is correct that $r$ is a root of the polynomial, then it is the case that the term $(\\square-r)$ will evenly divide the polynomial without any remainder. It is also the case that if $r$ is not a root of the polynomial, $P(\\square)/(\\square-r)$ will not be an even division and will result in some remainder. The prover will use this fact to prove $r$ is a root.\nThe prover will compute the quotient polynomial $Q(\\square)=P(\\square)/(\\square-r)$ and provide a commitment to it $K_{Q(\\tau)}$ with KZG and give the commitment to the verifier. Knowing the value $r$, if the verifier can check if $P(\\square)=Q(\\square)(\\square -r)$, it will be convinced that $(r-\\square)$ evenly divides $P(\\square)$ (since $Q$ is a single polynomial) and thus $r$ is a root.\nThe verifier has $r$ and $K_{P(\\tau)}$ and $K_{Q(\\tau)}$. The verifier can compute a commitment to $(\\square-r)$ at $\\tau$ by just treating it as the polynomial $V(\\square)=(\\square-r)=-r+1\\cdot\\square$ and using KZG to produce $K_{V(\\tau)}$. The verifier can then check: $$ \\begin{align} e(K_{P(\\tau)},g)\u0026\\stackrel{?}{=}e(K_{Q(\\tau)},K_{V(\\tau)})\\\\ e(g^{P(\\tau)},g)\u0026=e(g^{Q(\\tau)},g^{V(\\tau)}) \\\\e(g,g)^{P(\\tau)}\u0026=e(g,g)^{Q(\\tau)\\cdot V(\\tau)} \\end{align} $$ Notice that the degree of the polynomial $P(\\square)$ (and thus $Q(\\square)$) has no impact on the size of the proof given to the verifier or the work that the verifier has to do. Even if the degree of $P(\\square)$ is billions, the proof is the same size and time for the verifier. In a sense, this is our first special purpose SNARK and one we will leverage into making SNARKs for all the gadgets in Plonkbook.\nSelective Open: Multiple Roots # If the prover wants to open at multiple roots, it runs the exact same protocol but has the verifier set $V(\\square)=(\\square-r_0)\\cdot(\\square-r_1)\\cdot(\\square-r_2)\\ldots$ for all the roots it wants to prove. Importantly, this does not add any complexity for the verifier once $K_{V(\\tau)}$ has been created.\nSelective Open: Arbitrary Point # Most of the time, the prover wants to prove the polynomial passes through an arbitrary point $\\{x,y\\}=\\{x,P(x)\\}$ where $y$ is some integer that is not zero (and thus $x$ is not a root). Again, this is very easy to prove once we have a protocol for proving roots. The intuition is as follows: if and only if $P(\\square)$ has value $y$ at point $x$, then subtracting $y$ from $P(\\square)$ will create a new polynomial $\\tilde{P}(\\square)=P(\\square)-y$ that is zero at point $x$, making $x$ a root. (Visually you can imagine a polynomial with height $y$ at a point $x$, and subtracting $y$ shifts the whole polynomial down $y$ units, moving that point down to the x-axis.) The verifier can construct $K_{\\tilde{P}(\\tau)}$ from $K_{P(\\tau)}$ using the additive homomorphic property: $K_{\\tilde{P}(\\tau)}=K_{P(tau)\\cdot} g^{-y}$. Then the prover shows $K_{\\tilde{P}(\\tau)}$ has a root at point $x$ using the protocol above for proving roots.\nSelective Open: Batch of Points # If the cost of opening a set of points is roughly the same as the cost of opening a single point, it is called a batch opening. Several variants might be desired:\nBatch open multiple points on the same polynomial: direct from KZG, shown below. Batch open the same point on multiple polynomials: direct from KZG, not shown. Batch open multiple points on multiple polynomials: not directly possible with KZG but possible with variants. To batch open multiple points on the same polynomial $P(\\square)$, the prover asserts the full set of points to the verifier. The verifier will interpolate a polynomial through these points $R(\\square)$ and compute its commitment $K_{R(\\tau)}$. Recall that when proving a single point $\\{x,y\\}$, it would compute $\\tilde{P}(\\square)=P(\\square)-y$. This does not work for multiple points because the amount to \u0026ldquo;slide down\u0026rdquo; the polynomial differs. However $R(\\square)$ has the right amount at every value of $x$ being opened. So the verifier computes $K_{\\tilde{P}(\\tau)}=K_{P(\\tau)} \\cdot (K_{R(\\tau)})^{-1}$ where $\\tilde{P}(\\square)=P(\\square)-R(\\square)$ using the additively homomorphic property, and now all the points are roots, so the prover uses the \u0026ldquo;selective open: multiple roots\u0026rdquo; protocol above on $\\tilde{P}(\\square)$.\nFootnotes # The result was actually pointed out earlier by DeMillo and Lipton, and thus is occasionally referred to as the DeMillo–Lipton–Schwartz–Zippel lemma\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nThe commitment was popularized by Pedersen but Pedersen attributes it to Bos and Chaum in his paper. It appeared even earlier as a bit commitment scheme in a paper by Chaum, Damgard, and van de Graaf.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n"},{"id":22,"href":"/docs/background/poly-iop/","title":"Polynomials","section":"Background","content":" Polynomials # All the gadgets in Plonkbook follow the same high level model, called a polynomial interactive oracle proof (Poly-IOP). Each gadget is defined as an operation on one or more arrays of data. The arrays are encoded into a univariate polynomial (see below) and the polynomial is committed to (next background section) and passed to the verifier. The verifier works with commitments and sees that operations on commitments are mirroring a set of operations being done on the polynomials themselves. And the operations on the polynomials are mirroring operations on the data encoded into them as an array.\nEach gadget description will begin with the array and show the operation being done on the array. It will then show how to manipulate a polynomial holding the array so that the operation is performed on the underlying array. It will then show how the verifier can use only commitments to the polynomials, rather than the full polynomials, to follow along and check every step.\nEncoding Arrays of Data into Polynomials # In the Poly-IOP model, data starts as an array (or vector) of integers and gadgets are defined in terms of operations on arrays. In the proof stage, the arrays are encoded into a polynomial. Array slots contain integers between 0 and $q-1$, where $q$ is a large (generally 256 bit) prime number. Recall that we call this set of integers $\\mathbb{Z}_q$.\n$\\mathsf{data}_0$ $\\mathsf{data}_1$ $\\mathsf{data}_2$ $\\mathsf{data}_3$ $\\mathsf{data}_4$ It is common to denote a polynomial like $P(X)$ where $X$ is the variable of the polynomial. We are going denote the variable with an empty box $\\square$ which can be interpreted as a place where you can put any integer in $\\mathbb{Z}_q$ you want evaluated (or equivalent, where you place an x-coordinate to learn what the y-coordinate is).\nA polynomial in this notation looks like:\n$P(\\square)=c_0+c_1\\cdot\\square+c_2\\cdot\\square^2+c_3\\cdot\\square^3+c_4\\cdot\\square^4=\\sum_{i=0}^d c_i\\cdot\\square^i$ The values $c_i$ are called coefficients. Different arrays of data will (depending on how data is encoded, next) result in different coefficients and thus different polynomials. The degree of the polynomial is the largest exponent. So the polynomial above has degree 4 and thus will have 5 coefficients and 5 terms of the form $c_i\\cdot\\square^i$ (including $i=0$). Sometimes the coefficient will be zero: the term is thus not written down but in a list of coefficients, it will be included as a 0.\nThe main question to tackle is how to \u0026ldquo;encode\u0026rdquo; an array of integers into a polynomial. This is generally done one of three ways:\nCoefficients Evaluation Points Roots Each has its advantages and disadvantages, which we discuss next.\nFast forwarding a bit, once the polynomial is created, it is not shared directly with anyone. Instead, a commitment to it is shared. The commitment does two things: (1) it makes it succinct: e.g., constant size regardless of how long the array is; and (2) it can hide the data in the array as necessary. We will discuss one specific polynomial commitment scheme called KZG. KZG needs the polynomial in the format of a list of its coefficients. If we have the polynomial in a different form, we will have to convert it to coefficients. Thus this needs to be considered when weighing the pros/cons of the three encoding methods.\nEncoding 1: Coefficients # Create polynomial as: $P_1(\\square)=\\mathsf{data}_0+\\square+\\mathsf{data}_2\\cdot\\square^2+\\mathsf{data}_3\\cdot\\square^3+\\mathsf{data}_4\\cdot\\square^4=\\sum_{i=0}^d \\mathsf{data}_i\\cdot\\square^i$\nProperties:\nFast 👍: fastest path to commitment as the output is already in coefficient form. Addition 👍: two arrays can be added together (slot-by-slot) by simply adding the polynomials together Multiplication 👎: no support for multiplication of arrays (Remark: multiplying the polynomials does not multiply the coefficients. It results in a cross multiplication of every term in the first polynomial with every term in the second polynomial. Further the degree of the resulting polynomial will double that of the starting polynomials). Opening 🤷🏻: proving the value of the $i$th element in the array is $\\mathsf{data}_i$ doing polynomial math on $P_1(\\square)$ is not possible. However $\\Sigma$-protocols done directly on KZG may enable this kind of proof. In any case, this is not particularly well explored. Other useful properties 👍: the sum of all values in a array can be computed by evaluating the polynomial at $P_1(\\boxed{1})$! $\\sum_{i=0}^d \\mathsf{data}_i\\cdot\\boxed{1}^i=\\sum_{i=0}^d \\mathsf{data}_i$ . You can also show two arrays have the same sum (called a \u0026ldquo;sum check\u0026rdquo;) by subtracting them and showing $P(\\boxed{1})=0$. Other useful properties 👍: when all coefficients are 0, the polynomial will be the zero polynomial ($P_1(\\square)=0$). Coefficients can be entire polynomials, not just integers. A common optimization in Poly-IOP systems is taking a set of equations of polynomials that should equal 0, placing each into the coefficient of a super-polynomial, and showing the super-polynomial is the zero polynomial (which can be proven overwhelmingly by showing it is 0 at a randomly selected point). Encoding 2: Evaluation Points # Create a list of points $\\{x,y\\}$ for the data: $\\langle\\{0,\\mathsf{data}_0\\},\\{1,\\mathsf{data}_1\\},\\{2,\\mathsf{data}_2\\},\\{3,\\mathsf{data}_3\\},\\{4,\\mathsf{data}_4\\}\\rangle$ and interpolate a polynomial $P_2(\\square)$ through these points.\nProperties:\nSlow (or moderate) 👎: converting a set of points into a set of coefficients is called interpolation and is $O(n^2)$ time generally. A certain optimization allows $O(n\\log n)$ time by choosing $x$ coordinates with a mathematical relationship (more on this later). Addition 👍: two arrays can be added together (slot-by-slot) by simply adding the polynomials together Multiplication 👍: two arrays can be multiplied together (slot-by-slot) by simply multiplying the polynomials together Opening 👍: proving the value of the $i$th element in the array is $\\mathsf{data}_i$ is possible with polynomial math by showing $P_2(\\boxed{i})=\\mathsf{data}_i$ and KZG has a precise algorithm for this. Encoding 3: Roots # Create polynomial as: $P_3(\\square)=(\\square-\\mathsf{data}_0)(\\square-\\mathsf{data}_1)(\\square-\\mathsf{data}_2)(\\square-\\mathsf{data}_3)(\\square-\\mathsf{data}_4)$\nAlternatively, create a list of roots $\\{x,0\\}$ for the data: $\\langle\\{\\mathsf{data}_0,0\\},\\{\\mathsf{data}_1,0\\},\\{\\mathsf{data}_2,0\\},\\{\\mathsf{data}_3,0\\},\\{\\mathsf{data}_4,0\\}\\rangle$ and interpolate a polynomial $P_3(\\square)$ through these points.\nProperties:\nSlow 👎 (or moderate): multiplying out naively requires $O(n^2)$ time. Treating as a set of points and interpolating also requires $O(n^2)$ time (because the x-coordinates are the data, they cannot be chosen freely to optimize interpolation). Applying divide and conquer can provide $O(n \\log^2 n)$.^[1] Addition 👎: two arrays cannot be added from adding (or otherwise manipulating) the polynomials. Multiplication 👎: two arrays cannot be multiplied from multiplying (or otherwise manipulating) the polynomials (but you can do a \u0026ldquo;union\u0026rdquo; operation below). Opening 👍: proving that a value is in the array somewhere is easy and KZG as a precise algorithm for this (opening a root is the same as opening a point, where the y-coordinate is 0). However you cannot show a value is specifically the $i$th value in the array because the polynomial loses the order of the data in the array (see next property). Other useful properties 👍: the order of the data in the array does not matter. The same polynomial will be produced even if the order is changed. This is useful when the array represents a \u0026ldquo;bag\u0026rdquo; of unordered data. You can easily prove two \u0026ldquo;bags\u0026rdquo; of data are the same because the polynomials will be the same. One use-case of this is proving the output of a shuffle/permutation is the same data as the input (just in a different order). Other useful properties 👍: multiplying two polynomials results in a concatenation of the data in the arrays (or conjunction/union of the data in both bags). This might be useful in some protocols. Decision Tree for Encoding # Basically we decide if we specifically need unordered \u0026ldquo;bags\u0026rdquo; of data. If so, encoding as roots is the only option. If not, we consider if we need to ever get the data back from the polynomial. Generally we do and encoding as evaluation points is the most common encoding technique. When do we encode the data and never want it back? Usually when (1) the coefficients are all supposed to be zero so we are just showing that property, or (2) we want back the sum of the data and not the data itself. In these cases, you can still work with evaluation point encoding but it will be faster to just do coefficient encoding.\nflowchart LR; A[Array to Polynomial] --\u003e B{Is the data unordered?}; B -- Unordered --\u003e C[Roots]; B -- Ordered or don't care --\u003e D{Open data from polynomial later?}; D -- Yes --\u003e E[Evaluation Points]; D -- No --\u003e F[Coefficients]; The short answer is to start with evaluation point encoding until you realize you need something different.\nRoots of Unity # Moving forward, we will assume we are using Encoding 2: Evaluation Points. In short, this means placing the elements of our array into the $y$-coordinates ($\\mathsf{data}_i=P(\\boxed{x_i})$) of points on the polynomial. Before commiting to $P(\\square)$, we need to use interpolation to find the coefficients of the polynomial that is fitted to these points. General interpolation algorithms are $O(n^2)$ work for $n$ evaluation points but this can be reduced to $O(n\\log n)$ with an optimization.\nThe optimization we will explore enables interpolation via the fast Fourier transform (FFT). It concerns how to choose the $x$-coordinates, which will serve as the index for accessing the data: evaluating $P(X)$ at $x_i$ will reveal $\\mathsf{data}_i$. First note, $x$-coordinates are from the exponent group ($Z_q$) and the choices exceed what is feasible to use ($2^{255}$ values in bls). Any subset can be used and interpolated. The optimization is to chose them with a mathematical structure. Specifically, instead an additive sequence (e.g., $0,1,2,3,\\ldots$), we use a multiplicative sequence $1,\\omega,\\omega\\cdot\\omega,\\omega\\cdot\\omega\\cdot\\omega,\\ldots$ or equivalently: $\\omega^0,\\omega^1,\\omega^2,\\ldots,\\omega^{\\kappa-1}$. Further, the sequence is closed under multiplication which means that next index after $\\omega^{\\kappa-1}$ wraps back to the first index: $\\omega^{k-1} \\cdot \\omega = \\omega^\\kappa = \\omega^0=1$ (this property is also useful in proving relationships between data in the array and its neighbouring values).\nFor terminology, we say $\\omega$ is a generator with multiplicative order $\\kappa$ in $\\mathbb{Z}_q$ (or $\\omega \\in \\mathbb{G}_\\kappa$). This implies $\\omega^\\kappa=1$. Rearranging, $\\omega=\\sqrt[\\kappa]{1}$. Thus we can equivalently describe $\\omega$ as a $\\kappa$-th root of 1. Finally, as 1 is the unity element in $Z_q$, $\\omega$ is commonly called a $\\kappa$-th root of unity.\nFor practical purposes, $\\kappa$ represents the length of the longest array of data we can use in our protocol. Where does $\\kappa$ come from? Different elements of $Z_q$ will have different multiplicative orders but every order must be a divisor of $q-1$. Thus $\\kappa$ is the largest divisor of the exact value of $q$ used in an elliptic curve standard. BLS12-384 has $\\kappa=2^{32}$ (for terminology, this called a $2$-adicity of $32$). In summary, we can only encode data arrays of length up to $2^{32}=4,294,967,296$.\nInterpolation via FFT # Background # FFT is a fast algorithm for transitions between coefficients (Encoding 1) and evaluation points (Encoding 2) .\nflowchart LR co[coefficients] points[points] co --evaluation--\u003e points points --interpolation--\u003e co Polynomials, interpolation, and Fourier transforms are all big topics that have general theories and applications. This article will not try to explain anything in its full generality. Instead we will simplify as much as possible, limiting ourselves to only what we need for many cryptographic applications.\nHere are the simplifications:\nWe only use integers. No real numbers. No imaginary numbers. Integers are from a bounded range: $[0,q-1]$ or $\\mathbb{Z}_q$ for a large (e.g., 256 bit) prime $q$. Polynomials are univariate (only one variable). Worked Example: Evaluation # Assume $q=97$.\nWe will start with the more intuitive direction: going from a polynomial in coefficient form to a set of points on the polynomial. Consider the following polynomial in coefficient form: $$ P(\\square)=81 \\square^7+57 \\square^6+11 \\square^5+59 \\square^4+60 \\square^3+83 \\square^2+45 \\square+44 $$ In this case, the list of coefficients (from least to greatest) is $\\{44,45,83,60,59,11,57,81\\}$. The degree of the polynomial is 7 and the number of coefficients is 8. Our goal is determine 8 unique points of form ($x_i, y_i=P(x_i))$. Why 8? We need 8 points to fully determine a degree 7 polynomial, so this will let us reverse the process (go from points to coefficients) in the future if need to.\n(Remark: Think of a straight line. It is of form $P(\\square)=c_1\\square+c_0$ which is degree $1$ with $2$ coefficients. You need $2$ points to figure out what the line should be. Generalizing, for a degree $d$ polynomial, $d+1$ coefficients or $d+1$ points are needed to fully determine it.)\nSo the goal is to find $8$ points on the polynomial $P(\\square)$. The points can be at any x-coordinates so we will chose $\\{1,2,3,4,5,6,7,8\\}$ for now. We call this the domain. Finding the points is a simple as plugging the x-coordinates into the $P(\\square)$ equation:\n$$ \\begin{alignat}{1} P(\\boxed{1})=81 \\boxed{1}^7+57 \\boxed{1}^6+11 \\boxed{1}^5+59 \\boxed{1}^4+60 \\boxed{1}^3+83 \\boxed{1}^2+45 \\boxed{1}+44=52 \\\\ P(\\boxed{2})=81 \\boxed{2}^7+57 \\boxed{2}^6+11 \\boxed{2}^5+59 \\boxed{2}^4+60 \\boxed{2}^3+83 \\boxed{2}^2+45 \\boxed{2}+44=59 \\\\ P(\\boxed{3})=81 \\boxed{3}^7+57 \\boxed{3}^6+11 \\boxed{3}^5+59 \\boxed{3}^4+60 \\boxed{3}^3+83 \\boxed{3}^2+45 \\boxed{3}+44=69 \\\\ P(\\boxed{4})=81 \\boxed{4}^7+57 \\boxed{4}^6+11 \\boxed{4}^5+59 \\boxed{4}^4+60 \\boxed{4}^3+83 \\boxed{4}^2+45 \\boxed{4}+44=81 \\\\ P(\\boxed{5})=81 \\boxed{5}^7+57 \\boxed{5}^6+11 \\boxed{5}^5+59 \\boxed{5}^4+60 \\boxed{5}^3+83 \\boxed{5}^2+45 \\boxed{5}+44=12 \\\\ P(\\boxed{6})=81 \\boxed{6}^7+57 \\boxed{6}^6+11 \\boxed{6}^5+59 \\boxed{6}^4+60 \\boxed{6}^3+83 \\boxed{6}^2+45 \\boxed{6}+44=15 \\\\ P(\\boxed{7})=81 \\boxed{7}^7+57 \\boxed{7}^6+11 \\boxed{7}^5+59 \\boxed{7}^4+60 \\boxed{7}^3+83 \\boxed{7}^2+45 \\boxed{7}+44=92 \\\\ P(\\boxed{8})=81 \\boxed{8}^7+57 \\boxed{8}^6+11 \\boxed{8}^5+59 \\boxed{8}^4+60 \\boxed{8}^3+83 \\boxed{8}^2+45 \\boxed{8}+44=36 \\\\ \\end{alignat} $$ In more succinct form, we are moving between a list of 8 coefficients and a list of 8 points on the polynomial.\n$$ \\left( \\begin{array}{cccccccc} 44 \u0026 45 \u0026 83 \u0026 60 \u0026 59 \u0026 11 \u0026 57 \u0026 81 \\\\ \\end{array} \\right) \\leftrightarrow \\left( \\begin{array}{cccccccc} 1 \u0026 2 \u0026 3 \u0026 4 \u0026 5 \u0026 6 \u0026 7 \u0026 8 \\\\ 52 \u0026 59 \u0026 69 \u0026 81 \u0026 12 \u0026 15 \u0026 92 \u0026 36 \\\\ \\end{array} \\right) $$ Before figuring out how to go backward, we are going redo the same thing one more time, this time using matrix notation. The equivalent computation we just did is the following:\n$$ \\left( \\begin{array}{cccccccc} \\boxed{1}^0 \u0026 \\boxed{1}^1 \u0026 \\boxed{1}^2 \u0026 \\boxed{1}^3 \u0026 \\boxed{1}^4 \u0026 \\boxed{1}^5 \u0026 \\boxed{1}^6 \u0026 \\boxed{1}^7\\\\ \\boxed{2}^0 \u0026 \\boxed{2}^1 \u0026 \\boxed{2}^2 \u0026 \\boxed{2}^3 \u0026 \\boxed{2}^4 \u0026 \\boxed{2}^5 \u0026 \\boxed{2}^6 \u0026 \\boxed{2}^7\\\\ \\boxed{3}^0 \u0026 \\boxed{3}^1 \u0026 \\boxed{3}^2 \u0026 \\boxed{3}^3 \u0026 \\boxed{3}^4 \u0026 \\boxed{3}^5 \u0026 \\boxed{3}^6 \u0026 \\boxed{3}^7\\\\ \\boxed{4}^0 \u0026 \\boxed{4}^1 \u0026 \\boxed{4}^2 \u0026 \\boxed{4}^3 \u0026 \\boxed{4}^4 \u0026 \\boxed{4}^5 \u0026 \\boxed{4}^6 \u0026 \\boxed{4}^7\\\\ \\boxed{5}^0 \u0026 \\boxed{5}^1 \u0026 \\boxed{5}^2 \u0026 \\boxed{5}^3 \u0026 \\boxed{5}^4 \u0026 \\boxed{5}^5 \u0026 \\boxed{5}^6 \u0026 \\boxed{5}^7\\\\ \\boxed{6}^0 \u0026 \\boxed{6}^1 \u0026 \\boxed{6}^2 \u0026 \\boxed{6}^3 \u0026 \\boxed{6}^4 \u0026 \\boxed{6}^5 \u0026 \\boxed{6}^6 \u0026 \\boxed{6}^7\\\\ \\boxed{7}^0 \u0026 \\boxed{7}^1 \u0026 \\boxed{7}^2 \u0026 \\boxed{7}^3 \u0026 \\boxed{7}^4 \u0026 \\boxed{7}^5 \u0026 \\boxed{7}^6 \u0026 \\boxed{7}^7\\\\ \\boxed{8}^0 \u0026 \\boxed{8}^1 \u0026 \\boxed{8}^2 \u0026 \\boxed{8}^3 \u0026 \\boxed{8}^4 \u0026 \\boxed{8}^5 \u0026 \\boxed{8}^6 \u0026 \\boxed{8}^7\\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} ? \\\\ ? \\\\ ? \\\\ ? \\\\ ? \\\\ ? \\\\ ? \\\\ ? \\\\ \\end{array} \\right) $$ Evaluating it:\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \u0026 16 \u0026 32 \u0026 64 \u0026 31 \\\\ 1 \u0026 3 \u0026 9 \u0026 27 \u0026 81 \u0026 49 \u0026 50 \u0026 53 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \u0026 62 \u0026 54 \u0026 22 \u0026 88 \\\\ 1 \u0026 5 \u0026 25 \u0026 28 \u0026 43 \u0026 21 \u0026 8 \u0026 40 \\\\ 1 \u0026 6 \u0026 36 \u0026 22 \u0026 35 \u0026 16 \u0026 96 \u0026 91 \\\\ 1 \u0026 7 \u0026 49 \u0026 52 \u0026 73 \u0026 26 \u0026 85 \u0026 13 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \u0026 22 \u0026 79 \u0026 50 \u0026 12 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} 52 \\\\ 59 \\\\ 69 \\\\ 81 \\\\ 12 \\\\ 15 \\\\ 92 \\\\ 36 \\\\ \\end{array} \\right) $$ Efficiency # Let\u0026rsquo;s pause for a moment and think about efficiency. First, consider the matrix: it does not depend on the polynomial values at all. It only depends on the domain (or set of x-values) that you want to evaluate the points at. The domain can be decided ahead of time (e.g., we will always use a domain of 1, 2, 3, \u0026hellip;) and then the matrix can be computed at that time. From a protocol perspective, the matrix can be pre-computed and can be shared between operations on polynomials of the same degree.\nThe multiplication is clearly $O(n^2)$ where $n$ is the number of coefficients/evaluation points. The whole point of FFT to reduce the work to $O(n \\cdot \\log_2{n})$ and that is it. In a world where efficiency is not a concern, you can just do the above and ignore FFT.\nCryptography # Moving back to cryptography, imagine you have the polynomial in encrypted (or committed or secret shared) form and this encryption is additively homomorphic. To compute the evaluation points under encryption only involves multiplying in known values from the matrix (which are not secret and depend only on the domain), and then doing additions under encryption. Therefore we can evaluate (and, as you will see below, interpolate) under encryption. Sometimes doing things on the points of a polynomial is simpler than on the polynomials themselves (e.g., multiplying polynomials were you only care about a subset of the points on the polynomial). And vice-versa (rotating an array of values: if encode values into a set of polynomial points, interpolate it, multiply in some constants into the polynomial coefficients, and convert back to points, the array will be rotated).\nJargon # A matrix with the above form is called a Vandermonde matrix. This process is called a discrete Fourier transform (or DFT). FFT is a special case of DFT and is faster.\nWorked Example: Interpolation # Now assume we have a set of points and want to go backwards to determine the coefficients:\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 2 \u0026 3 \u0026 4 \u0026 5 \u0026 6 \u0026 7 \u0026 8 \\\\ 52 \u0026 59 \u0026 69 \u0026 81 \u0026 12 \u0026 15 \u0026 92 \u0026 36 \\\\ \\end{array} \\right) \\rightarrow \\left( \\begin{array}{cccccccc} 44 \u0026 45 \u0026 83 \u0026 60 \u0026 59 \u0026 11 \u0026 57 \u0026 81 \\\\ \\end{array} \\right) $$ Placing the evaluation process into matrix multiplication makes interpolation very easy to understand. We simply move the matrix to the other side of the equation, which involves inverting it. Above, we did the following (coefficients to points):\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \u0026 16 \u0026 32 \u0026 64 \u0026 31 \\\\ 1 \u0026 3 \u0026 9 \u0026 27 \u0026 81 \u0026 49 \u0026 50 \u0026 53 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \u0026 62 \u0026 54 \u0026 22 \u0026 88 \\\\ 1 \u0026 5 \u0026 25 \u0026 28 \u0026 43 \u0026 21 \u0026 8 \u0026 40 \\\\ 1 \u0026 6 \u0026 36 \u0026 22 \u0026 35 \u0026 16 \u0026 96 \u0026 91 \\\\ 1 \u0026 7 \u0026 49 \u0026 52 \u0026 73 \u0026 26 \u0026 85 \u0026 13 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \u0026 22 \u0026 79 \u0026 50 \u0026 12 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} 52 \\\\ 59 \\\\ 69 \\\\ 81 \\\\ 12 \\\\ 15 \\\\ 92 \\\\ 36 \\\\ \\end{array} \\right) $$ To do interpolation (points to coefficients), we move the matrix to the other side of the equation:\n$$ \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \u0026 16 \u0026 32 \u0026 64 \u0026 31 \\\\ 1 \u0026 3 \u0026 9 \u0026 27 \u0026 81 \u0026 49 \u0026 50 \u0026 53 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \u0026 62 \u0026 54 \u0026 22 \u0026 88 \\\\ 1 \u0026 5 \u0026 25 \u0026 28 \u0026 43 \u0026 21 \u0026 8 \u0026 40 \\\\ 1 \u0026 6 \u0026 36 \u0026 22 \u0026 35 \u0026 16 \u0026 96 \u0026 91 \\\\ 1 \u0026 7 \u0026 49 \u0026 52 \u0026 73 \u0026 26 \u0026 85 \u0026 13 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \u0026 22 \u0026 79 \u0026 50 \u0026 12 \\\\ \\end{array} \\right)^{-1} \\cdot \\left( \\begin{array}{c} 52 \\\\ 59 \\\\ 69 \\\\ 81 \\\\ 12 \\\\ 15 \\\\ 92 \\\\ 36 \\\\ \\end{array} \\right) $$ Solving the inverse matrix, we arrive at:\n$$ \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{cccccccc} 8 \u0026 69 \u0026 56 \u0026 27 \u0026 56 \u0026 69 \u0026 8 \u0026 96 \\\\ 50 \u0026 33 \u0026 54 \u0026 3 \u0026 53 \u0026 10 \u0026 57 \u0026 31 \\\\ 7 \u0026 70 \u0026 8 \u0026 86 \u0026 20 \u0026 39 \u0026 76 \u0026 82 \\\\ 47 \u0026 89 \u0026 24 \u0026 11 \u0026 90 \u0026 12 \u0026 37 \u0026 78 \\\\ 85 \u0026 57 \u0026 80 \u0026 34 \u0026 90 \u0026 63 \u0026 71 \u0026 5 \\\\ 55 \u0026 85 \u0026 43 \u0026 77 \u0026 2 \u0026 67 \u0026 91 \u0026 65 \\\\ 64 \u0026 11 \u0026 45 \u0026 86 \u0026 44 \u0026 12 \u0026 22 \u0026 7 \\\\ 73 \u0026 71 \u0026 78 \u0026 64 \u0026 33 \u0026 19 \u0026 26 \u0026 24 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 52 \\\\ 59 \\\\ 69 \\\\ 81 \\\\ 12 \\\\ 15 \\\\ 92 \\\\ 36 \\\\ \\end{array} \\right) $$ Can we always invert the matrix? The answer is yes, assuming each row of the matrix is unique, which is to say, each evaluation point is unique (no repeats). The complexity analysis is the same as evaluation: the matrix can be pre-computed and the multiplication is $O(n^2)$. The FFT trick will work equally well on this matrix.\nJargon # This process is called the inverse discrete Fourier transform (or iDFT). If each column of the matrix is taken to be a coefficient list of a polynomial, such polynomials are called Lagrange polynomials.\nSpeeding up evaluation and interpolation # Divide-and-conquer # The high level idea of speeding up both processes is called divide-and-conquer. Recall this equation:\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \u0026 16 \u0026 32 \u0026 64 \u0026 31 \\\\ 1 \u0026 3 \u0026 9 \u0026 27 \u0026 81 \u0026 49 \u0026 50 \u0026 53 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \u0026 62 \u0026 54 \u0026 22 \u0026 88 \\\\ 1 \u0026 5 \u0026 25 \u0026 28 \u0026 43 \u0026 21 \u0026 8 \u0026 40 \\\\ 1 \u0026 6 \u0026 36 \u0026 22 \u0026 35 \u0026 16 \u0026 96 \u0026 91 \\\\ 1 \u0026 7 \u0026 49 \u0026 52 \u0026 73 \u0026 26 \u0026 85 \u0026 13 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \u0026 22 \u0026 79 \u0026 50 \u0026 12 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} 52 \\\\ 59 \\\\ 69 \\\\ 81 \\\\ 12 \\\\ 15 \\\\ 92 \\\\ 36 \\\\ \\end{array} \\right) $$ What if we split this up? For example, say we find the evaluation at $\\{1,2,3,4\\}$ using the first four coefficients $\\{44,45,83,60\\}$, then we find the evaluation at $\\{5,6,7,8\\}$ using the last four coefficients $\\{59,11,57,81\\}$:\n$$ \\left( \\begin{array}{cccc} 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \\\\ 1 \u0026 3 \u0026 9 \u0026 27 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} 38 \\\\ 73 \\\\ 24 \\\\ 57 \\\\ \\end{array} \\right) $$ $$ \\left( \\begin{array}{cccc} 1 \u0026 5 \u0026 25 \u0026 28 \\\\ 1 \u0026 6 \u0026 36 \u0026 22 \\\\ 1 \u0026 7 \u0026 49 \u0026 52 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} 24 \\\\ 79 \\\\ 60 \\\\ 65 \\\\ \\end{array} \\right) $$ Next, we need some way to combine $\\{38,73,24,57\\}$ and $\\{24, 79, 60, 65\\}$ to generate $\\{52,59,69,81,12,15,92,36\\}$ (that does not add a bunch more work). Assume we can pull this off, then we can recurse using this trick. Instead of directly computing the above two equations (involving two 4x4 matrices), we can split each of them into 2x2 matrices (for a total of four) using the same process. There is just one problem: there isn\u0026rsquo;t a simple algorithm for the combine step (faster than just computing the entire original matrix) that is going to work for us.\nOne parameter we can change # Reconsider the original problem, moving between coefficients (left) and evaluation points (right): $$ \\left( \\begin{array}{cccccccc} 44 \u0026 45 \u0026 83 \u0026 60 \u0026 59 \u0026 11 \u0026 57 \u0026 81 \\\\ \\end{array} \\right) \\leftrightarrow \\left( \\begin{array}{cccccccc} 1 \u0026 2 \u0026 3 \u0026 4 \u0026 5 \u0026 6 \u0026 7 \u0026 8 \\\\ 52 \u0026 59 \u0026 69 \u0026 81 \u0026 12 \u0026 15 \u0026 92 \u0026 36 \\\\ \\end{array} \\right) $$ We cannot control the coefficients of the polynomial — they are what they are. What the polynomial evaluates to at $\\{1,2,3,\\ldots\\}$ is also what it is, we cannot control it. However the one thing we did get to choose is $\\{1,2,3,\\ldots\\}$ itself (which we call the domain). We can map between coefficients and any domain, assuming there are 8 unique evaluation points. They do not have to be these specific points. So the question is, are there a different set of points that are \u0026ldquo;nicer\u0026rdquo; to deal with than $\\{1,2,3,\\ldots\\}$?\nThe domain shows up in the second column of the matrix:\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \u0026 16 \u0026 32 \u0026 64 \u0026 31 \\\\ 1 \u0026 3 \u0026 9 \u0026 27 \u0026 81 \u0026 49 \u0026 50 \u0026 53 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \u0026 62 \u0026 54 \u0026 22 \u0026 88 \\\\ 1 \u0026 5 \u0026 25 \u0026 28 \u0026 43 \u0026 21 \u0026 8 \u0026 40 \\\\ 1 \u0026 6 \u0026 36 \u0026 22 \u0026 35 \u0026 16 \u0026 96 \u0026 91 \\\\ 1 \u0026 7 \u0026 49 \u0026 52 \u0026 73 \u0026 26 \u0026 85 \u0026 13 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \u0026 22 \u0026 79 \u0026 50 \u0026 12 \\\\ \\end{array} \\right) $$ What if we make the points (the second column) the same values as the second row of the table: a domain of $\\{1,2,4,8,16,32,64,31\\}$? In this case, we will get a symmetric matrix which is a little \u0026ldquo;nicer\u0026rdquo; than one that is asymmetric. We will show both the matrix (using for evaluation) and its inverse (used for interpolation):\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \u0026 16 \u0026 32 \u0026 64 \u0026 31 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \u0026 62 \u0026 54 \u0026 22 \u0026 88 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \u0026 22 \u0026 79 \u0026 50 \u0026 12 \\\\ 1 \u0026 16 \u0026 62 \u0026 22 \u0026 61 \u0026 6 \u0026 96 \u0026 81 \\\\ 1 \u0026 32 \u0026 54 \u0026 79 \u0026 6 \u0026 95 \u0026 33 \u0026 86 \\\\ 1 \u0026 64 \u0026 22 \u0026 50 \u0026 96 \u0026 33 \u0026 75 \u0026 47 \\\\ 1 \u0026 31 \u0026 88 \u0026 12 \u0026 81 \u0026 86 \u0026 47 \u0026 2 \\\\ \\end{array} \\right)= \\left( \\begin{array}{cccccccc} 32 \u0026 41 \u0026 79 \u0026 38 \u0026 34 \u0026 89 \u0026 74 \u0026 2 \\\\ 41 \u0026 29 \u0026 45 \u0026 70 \u0026 42 \u0026 46 \u0026 25 \u0026 90 \\\\ 79 \u0026 45 \u0026 2 \u0026 66 \u0026 43 \u0026 95 \u0026 14 \u0026 44 \\\\ 38 \u0026 70 \u0026 66 \u0026 2 \u0026 44 \u0026 89 \u0026 60 \u0026 19 \\\\ 34 \u0026 42 \u0026 43 \u0026 44 \u0026 47 \u0026 25 \u0026 22 \u0026 34 \\\\ 89 \u0026 46 \u0026 95 \u0026 89 \u0026 25 \u0026 81 \u0026 76 \u0026 81 \\\\ 74 \u0026 25 \u0026 14 \u0026 60 \u0026 22 \u0026 76 \u0026 15 \u0026 5 \\\\ 2 \u0026 90 \u0026 44 \u0026 19 \u0026 34 \u0026 81 \u0026 5 \u0026 16 \\\\ \\end{array} \\right)^{-1} $$ This is nice but once we invert the matrix, is not symmetric any more. Is there a matrix where both the original and its inverse are symmetric? The answer is yes! Consider the domain $\\{1,33,22,47,96,64,75,50\\}$:\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 33 \u0026 22 \u0026 47 \u0026 96 \u0026 64 \u0026 75 \u0026 50 \\\\ 1 \u0026 22 \u0026 96 \u0026 75 \u0026 1 \u0026 22 \u0026 96 \u0026 75 \\\\ 1 \u0026 47 \u0026 75 \u0026 33 \u0026 96 \u0026 50 \u0026 22 \u0026 64 \\\\ 1 \u0026 96 \u0026 1 \u0026 96 \u0026 1 \u0026 96 \u0026 1 \u0026 96 \\\\ 1 \u0026 64 \u0026 22 \u0026 50 \u0026 96 \u0026 33 \u0026 75 \u0026 47 \\\\ 1 \u0026 75 \u0026 96 \u0026 22 \u0026 1 \u0026 75 \u0026 96 \u0026 22 \\\\ 1 \u0026 50 \u0026 75 \u0026 64 \u0026 96 \u0026 47 \u0026 22 \u0026 33 \\\\ \\end{array} \\right)= \\left( \\begin{array}{cccccccc} 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \\\\ 85 \u0026 79 \u0026 70 \u0026 8 \u0026 12 \u0026 18 \u0026 27 \u0026 89 \\\\ 85 \u0026 70 \u0026 12 \u0026 27 \u0026 85 \u0026 70 \u0026 12 \u0026 27 \\\\ 85 \u0026 8 \u0026 27 \u0026 79 \u0026 12 \u0026 89 \u0026 70 \u0026 18 \\\\ 85 \u0026 12 \u0026 85 \u0026 12 \u0026 85 \u0026 12 \u0026 85 \u0026 12 \\\\ 85 \u0026 18 \u0026 70 \u0026 89 \u0026 12 \u0026 79 \u0026 27 \u0026 8 \\\\ 85 \u0026 27 \u0026 12 \u0026 70 \u0026 85 \u0026 27 \u0026 12 \u0026 70 \\\\ 85 \u0026 89 \u0026 27 \u0026 18 \u0026 12 \u0026 8 \u0026 70 \u0026 79 \\\\ \\end{array} \\right)^{-1} $$ With this new domain and the same coefficients, we can find the evaluation points:\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 33 \u0026 22 \u0026 47 \u0026 96 \u0026 64 \u0026 75 \u0026 50 \\\\ 1 \u0026 22 \u0026 96 \u0026 75 \u0026 1 \u0026 22 \u0026 96 \u0026 75 \\\\ 1 \u0026 47 \u0026 75 \u0026 33 \u0026 96 \u0026 50 \u0026 22 \u0026 64 \\\\ 1 \u0026 96 \u0026 1 \u0026 96 \u0026 1 \u0026 96 \u0026 1 \u0026 96 \\\\ 1 \u0026 64 \u0026 22 \u0026 50 \u0026 96 \u0026 33 \u0026 75 \u0026 47 \\\\ 1 \u0026 75 \u0026 96 \u0026 22 \u0026 1 \u0026 75 \u0026 96 \u0026 22 \\\\ 1 \u0026 50 \u0026 75 \u0026 64 \u0026 96 \u0026 47 \u0026 22 \u0026 33 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} 52 \\\\ 13 \\\\ 33 \\\\ 27 \\\\ 46 \\\\ 34 \\\\ 87 \\\\ 60 \\\\ \\end{array} \\right) $$ Or we can find the coefficients, given the evaluation points:\n$$ \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{cccccccc} 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \\\\ 85 \u0026 79 \u0026 70 \u0026 8 \u0026 12 \u0026 18 \u0026 27 \u0026 89 \\\\ 85 \u0026 70 \u0026 12 \u0026 27 \u0026 85 \u0026 70 \u0026 12 \u0026 27 \\\\ 85 \u0026 8 \u0026 27 \u0026 79 \u0026 12 \u0026 89 \u0026 70 \u0026 18 \\\\ 85 \u0026 12 \u0026 85 \u0026 12 \u0026 85 \u0026 12 \u0026 85 \u0026 12 \\\\ 85 \u0026 18 \u0026 70 \u0026 89 \u0026 12 \u0026 79 \u0026 27 \u0026 8 \\\\ 85 \u0026 27 \u0026 12 \u0026 70 \u0026 85 \u0026 27 \u0026 12 \u0026 70 \\\\ 85 \u0026 89 \u0026 27 \u0026 18 \u0026 12 \u0026 8 \u0026 70 \u0026 79 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 52 \\\\ 13 \\\\ 33 \\\\ 27 \\\\ 46 \\\\ 34 \\\\ 87 \\\\ 60 \\\\ \\end{array} \\right) $$ In summary:\n$$ \\left( \\begin{array}{cccccccc} 44 \u0026 45 \u0026 83 \u0026 60 \u0026 59 \u0026 11 \u0026 57 \u0026 81 \\\\ \\end{array} \\right) \\leftrightarrow \\left( \\begin{array}{cccccccc} 1 \u0026 33 \u0026 22 \u0026 47 \u0026 96 \u0026 64 \u0026 75 \u0026 50 \\\\ 52 \u0026 13 \u0026 33 \u0026 27 \u0026 46 \u0026 34 \u0026 87 \u0026 60 \\\\ \\end{array} \\right) $$ Two questions:\nHow did we find the domain $\\{1,33,22,47,96,64,75,50\\}$? If we use $\\{1,33,22,47,96,64,75,50\\}$, can we do the divide-and-conquer strategy? Is there a combine function that is workable and efficient for these \u0026ldquo;nice\u0026rdquo; matrices? Generating symmetric matrices # $\\{1,33,22,47,96,64,75,50\\}$ is a special form. It is of the form $\\{\\omega^0,\\omega^1,\\omega^2,\\omega^3,\\omega^4,\\omega^5,\\omega^6,\\omega^7\\}$ where $\\omega=33$. Why 33? The size of the domain is $8$, so we choose 33 because the multiplicative order of $\\omega=33$ in $q=97$ is also $8$. Equivalently (in different jargon):\n33 is a generator that generates a multiplicative subgroup of size 8 (mod 97) 33 is an 8-th root of unity of 97 So the trick is setting the $x$-values to be generators of a subgroup of the same size as the number of points/coefficients you have. Here we have 8, so we found a generator of order 8.\nCan we find a generator of order 9 or 10 or 11 instead? The answer is no. Only certain sized subgroups exist. What dictates it? The answer is the value of $q$. Once $q$ is chosen, then the sizes of subgroups are locked in. Specifically the sizes available are the divisors of $q-1$. So if we factor $96$, we get $96=2^5\\cdot3$. That means we have subgroups of size: $\\{1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 96\\}$. The value of $q$ for cryptography depends on the elliptic curve used. Something like $\\texttt{bls12-381}$ uses a $q$ that purposefully has lots of subgroups: $\\{2,4,8,\\ldots,2^{32}\\}$.\nThe idea is that you find the degree of your polynomial $d$, then you need $d+1$ coefficients/points to represent it, and then you round $d+1$ up to the nearest power of 2 as necessary. The leading coefficients are set to 0.\nRevisiting divide-and-conquer # The remaining question is whether we can split the matrices into smaller (halve) matrices, and then combine the results. The answer is yes if the domain is based on roots of unity (for completeness, the answer is not necessarily no for other kinds of domains, but we do not explore that here).\nRecall, with the new domain, we have:\n$$ \\left( \\begin{array}{cccccccc} 44 \u0026 45 \u0026 83 \u0026 60 \u0026 59 \u0026 11 \u0026 57 \u0026 81 \\\\ \\end{array} \\right) \\leftrightarrow \\left( \\begin{array}{cccccccc} 1 \u0026 33 \u0026 22 \u0026 47 \u0026 96 \u0026 64 \u0026 75 \u0026 50 \\\\ 52 \u0026 13 \u0026 33 \u0026 27 \u0026 46 \u0026 34 \u0026 87 \u0026 60 \\\\ \\end{array} \\right) $$ Instead of dividing the coefficients into the first half and second halves, we will divide them into even coefficients (coefficients of terms $x^i$ where $i$ is even, including 0) and odd coefficients. We treat these two sets of coefficients as new polynomials $P_\\mathsf{even}(\\square)$ and $P_\\mathsf{odd}(\\square)$. Then we combine the two based on the following property:\n$$ P(\\square)=P_{\\mathsf{even}}(\\square^2)+\\square\\cdot P_{\\mathsf{odd}}(\\square^2) $$ How does this save computation? We compute the following values:\n$$ \\begin{alignat}{1} P_\\mathsf{even}(\\boxed{\\omega^0}^2)=P_\\mathsf{even}(1)=57 \\boxed{1}^3+59 \\boxed{1}^2+83 \\boxed{1}^1+44=49 \\\\ P_\\mathsf{even}(\\boxed{\\omega^1}^2)=P_\\mathsf{even}(22)=57 \\boxed{22}^3+59 \\boxed{22}^2+83 \\boxed{22}^1+44=72 \\\\ P_\\mathsf{even}(\\boxed{\\omega^2}^2)=P_\\mathsf{even}(96)=57 \\boxed{96}^3+59 \\boxed{96}^2+83 \\boxed{96}^1+44=60 \\\\ P_\\mathsf{even}(\\boxed{\\omega^3}^2)=P_\\mathsf{even}(75)=57 \\boxed{75}^3+59 \\boxed{75}^2+83 \\boxed{75}^1+44=92 \\\\ \\hline P_\\mathsf{odd}(\\boxed{\\omega^0}^2)=P_\\mathsf{odd}(1)=81\\boxed{1}^3+11\\boxed{1}^2+60\\boxed{1}^1+45=3 \\\\ P_\\mathsf{odd}(\\boxed{\\omega^1}^2)=P_\\mathsf{odd}{(22})= 81\\boxed{22}^3+11\\boxed{22}^2+60\\boxed{22}^1+45=57 \\\\ P_\\mathsf{odd}(\\boxed{\\omega^2}^2)=P_\\mathsf{odd}(96)=81\\boxed{96}^3+11\\boxed{96}^2+60\\boxed{96}^1+45=12 \\\\ P_\\mathsf{odd}(\\boxed{\\omega^3}^2)=P_\\mathsf{odd}(75)=81\\boxed{75}^3+11\\boxed{75}^2+60\\boxed{75}^1+45=11 \\\\ \\end{alignat} $$ We are not done, we have to figure out what to do with these 8 values still. But before showing that, note that while we are performing 8 evaluations, the evaluations only have 4 coefficients, so this is half the work of not using divide-and-conquer. Further, through recursion, we will be halving this over and over again anyways.\nAlso note that $P_\\mathsf{even}(\\boxed{\\omega^0}^2)=P_\\mathsf{even}(\\boxed{\\omega^4}^2)$ (or the multiplicative order of $\\omega^2$ is half of $\\omega$) which is why we only need to evaluate the first 4 values.\nTo combine these values, we take the output of the even evaluations: $\\{49, 72, 60, 92\\}$ and repeat it: $E=\\{49, 72, 60, 92,49, 72, 60, 92\\}$. We do the same with odd: $O=\\{3, 57, 12, 11,3, 57, 12, 11\\}$. We then compute: $E+O\\cdot\\mathsf{domain}$ (where multiplication is element-wise):\n$$ \\{49, 72, 60, 92,49, 72, 60, 92\\}+(\\{3, 57, 12, 11,3, 57, 12, 11\\}\\cdot\\{1,33,22,47,96,64,75,50\\})\\\\ =\\{52, 13, 33, 27, 46, 34, 87, 60\\} $$ That completes the operation and we have.\n$$ \\left( \\begin{array}{cccccccc} 44 \u0026 45 \u0026 83 \u0026 60 \u0026 59 \u0026 11 \u0026 57 \u0026 81 \\\\ \\end{array} \\right) \\leftrightarrow \\left( \\begin{array}{cccccccc} 1 \u0026 33 \u0026 22 \u0026 47 \u0026 96 \u0026 64 \u0026 75 \u0026 50 \\\\ 52 \u0026 13 \u0026 33 \u0026 27 \u0026 46 \u0026 34 \u0026 87 \u0026 60 \\\\ \\end{array} \\right) $$ Footnotes # ^[1]: Hat tip Pratyush Mishra for suggesting a state-of-the-art algorithm.\n"},{"id":23,"href":"/docs/background/proofs/","title":"Proofs","section":"Background","content":" Security Proofs # To be added.\nDefinitions # Definition 1 (Polynomial Commitment Scheme). A polynomial commitment scheme (PCS) is an interactive proof system that enables $\\mathcal{P}$ to convince $\\mathcal{V}$ that he knows a polynomial, without revealing the polynomial directly. $\\mathcal{P}$ and $\\mathcal{V}$ run the protocol in three moves: gen, com, and open. [Plonk]\nDefinition 2 (Polynomial IOP). Let $\\mathcal{R}$ be a set of the relations among polynomials $\\{P_i\\}$. Let $\\mathcal{C}_f$ is the commitment to $f$. Given common input $\\mathcal{R}(\\{P_i\\})$ to $\\mathcal{P}$ and $\\mathcal{V}$, and private input $\\{P_i\\}$ to $\\mathcal{P}$, they run the following protocol:\n$\\mathcal{P}$ converts the relations into polynomials $\\{Q_j\\}$ $\\mathcal{P}$ commits to $\\{P_i\\}$ and $\\{Q_j\\}$, and sends the commitments to $\\mathcal{V}$ $\\mathcal{V}$ sends a random challenge $\\xi$ $\\mathcal{P}$ runs open for $\\{P_i(\\xi)\\}$ and $\\{Q_j(\\xi)\\}$ and outputs the result $\\mathcal{V}$ checks: the evaluations of $P_i(\\xi)$ and $Q_j(\\xi)$ are correct $\\{Q_j\\}$ satisfy $\\mathcal{R}(\\{P_i\\})$ At the end of the protocol, $\\mathcal{V}$ outputs $\\textbf{acc}$ if and only if the two conditions hold, otherwise $\\textbf{rej}$.\nMoreover, a Poly-IOP has to satisfy the following properties.\nDefinition 3 (Completeness). If each pair of $(\\mathcal{C}_{P_i},P_i)$ and $(\\mathcal{C}_{Q_j},Q_j)$ is valid and $\\{Q_j\\}$ satisfy $\\mathcal{R}(\\{P_i\\})$, $\\text{Pr}[out_{\\mathcal{V}}=\\textbf{acc}]=1$.\nDefinition 4 (Soundness). If $(\\mathcal{C}_{P_i},P_i)$ or $(\\mathcal{C}_{Q_j},Q_j)$ are not a valid pair, or $\\{Q_j\\}$ does not satisfy $\\mathcal{R}(\\{P_i\\})$, $\\text{Pr}[out_{\\mathcal{V}}=\\textbf{rej}]\\ge{1-\\text{negl}(k)}$.\nDefinition 5 (Zero Knowledge). For every possible set of relations $\\mathcal{R}$, there exists a probabilistic polynomial time simulator $\\mathcal{S}$ that can produce $\\{\\mathcal{C}_{P_i}^*\\},\\{\\mathcal{C}_{Q_i}^*\\}$ and the corresponding proofs making $\\mathcal{V}$ output $\\textbf{acc}$; the proofs generated by $\\mathcal{S}$ are computationally indistinguishable from those produced by $\\mathcal{P}$.\n"},{"id":24,"href":"/docs/background/red-tape/","title":"Red Tape","section":"Background","content":" Red Tape # Generally speaking, the gadgets are quite flexible and work well as defined. However there are some subtle issues to pay attention to when using them.\nMax array size # Arrays can be very large but encoding points into a multiplicative domain (using roots of unity) means a root of unity must exist that is the same or larger than the array size. A domain of size $\\kappa$ exists only if $\\kappa$ divides $q-1$, where $q$ is the modulus that applies to exponents in the elliptic curve. For BLS12-384, the largest $\\kappa=2^{32}$. In summary, we can only encode data arrays of length up to $2^{32}=4,294,967,296$. We can use smaller domains. If $2^{32}$ divides $q-1$, so does $2^{31}$ or $2^{30}$ or any lesser power of 2. For terminology, this called a $2$-adicity of $32$.\nIn a sense, $2^{32}$ is an artificial limit since we do not need to encode data into multiplicative domains. We can use any domain, we just need spending more time interpolating with Lagrange. But since we only consider doing this when the domain gets really large, quadratic-time algorithms might be prohibitively expensive for numbers this big.\nTrusted setup # Recall that KZG polynomial commitments require a trusted setup, which implicitly impacts the maximum length an array can take on. Interpolating an array of length $n$ into a univariate polynomial will output a polynomial of degree $n-1$. The trusted setup needs to have an SRS with $n$ elements.\nArray expansions # Some gadgets operate on arrays of size $n$ but create temporary arrays that are larger than $n$ in order to prove the operation is done correctly. In particular, two gadgets are guilty of this:\nIn $\\texttt{lookup2}$, there are a few methods. In the method based on plookup, the temporary arrays need length $n_1$ + $n_2$ where $n_1$ is the length of the array and $n_2$ is the length of the lookup table. In $\\mathtt{range}$, each element is decomposed into binary. So if integers are shown to be the range $\\{0,1\\}^b$, an array of length $n$ needs a temporary array of size $n\\cdot2^b$. This can quickly lead to an array length exceeding the maximum root of unity. See the $\\texttt{range}$ gadget for discussion of other options. You need to ensure you have long enough arrays for all operations.\nPadding arrays # Usually the domain of the array is larger than what is needed since we are stuck with sizes like powers of 2 assuming we are using standard elliptic curves. This is fine, we just add some dummy elements to the end of the array to pad it out. The dummy elements can be zeroed out at any time with $\\texttt{zero1}$ or $\\texttt{zero2}$. However if we choose padding mindfully, we can avoid this extra work. For example, in $\\texttt{add2}$, padding with $0$ does not impact the protocol, while padding with $1$ does not impact $\\texttt{mult2}$.\nBoundary conditions # Many gadgets involve comparisons between neighbouring values in the same array (or across two arrays). This comparison works until you hit the last element of the array and there is no \u0026ldquo;next\u0026rdquo; element in the array. In practice, there is always a \u0026ldquo;next\u0026rdquo; element but attention needs to be paid to what it is. Using a multiplicative domain, the next element will be a dummy element if the array is smaller than the domain, or it will \u0026ldquo;wrap\u0026rdquo; back to the first element of the array if it is full. Many gadgets will just let the constraint end up with some arbitrary value in the last element, and then manually zero it out with $\\texttt{zero2}$.\nAdditional reading # Article (Thaler): includes points comparing univariate Poly-IOP to other zk-SNARK models Paper (Nikolaenko): trusted setup ceremony "}] \ No newline at end of file diff --git a/en.search-data.min.b3da462909c11499509a5595d9bfd93ab5120cfadab575f568dd98af79163e5d.json b/en.search-data.min.b3da462909c11499509a5595d9bfd93ab5120cfadab575f568dd98af79163e5d.json deleted file mode 100644 index 80c3d14..0000000 --- a/en.search-data.min.b3da462909c11499509a5595d9bfd93ab5120cfadab575f568dd98af79163e5d.json +++ /dev/null @@ -1 +0,0 @@ -[{"id":0,"href":"/docs/background/","title":"Background","section":"Docs","content":"Select a background topic from the menu.\n"},{"id":1,"href":"/docs/gadgets/","title":"Gadgets","section":"Docs","content":"Select a gadget from the menu.\n"},{"id":2,"href":"/docs/gadgets/add1/","title":"Add1","section":"Gadgets","content":" Addition (Type 1) # Recap of types # Type Description Recap This add1 $\\mathsf{Arr}_3=\\mathsf{Arr}_1 + \\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the element-wise addition of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. ✅ add2 $\\mathsf{Sum}_\\mathsf{Arr}=\\sum_{i = 0}^{n-1} \\mathsf{Arr}[i]$ $\\mathsf{Sum}_\\mathsf{Arr}$ is the disclosed sum of all the elements in $\\mathsf{Arr}$. add3 $\\sum_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\sum_{i = 0}^{n-1} \\mathsf{Arr}_2[i]$ $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ have the same undisclosed sum. Relation # $ \\mathcal{R}_{\\mathtt{add1}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr_2},K_\\mathsf{Arr_3}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i], 0\\leq i \\leq n, \\\\ \\mathsf{Poly}_\\mathsf{Arr_j}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_j}), 1\\leq j \\leq 3, \\\\ K_\\mathsf{Arr_j}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_j}), 1\\leq j \\leq 3, \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds two arrays $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that $\\mathsf{Arr_3}$ is the element-wise sum of all the elements in the array: $\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i]$. The prover will encode the three arrays into three polynomials: $\\mathsf{Poly}_\\mathsf{Arr_1}$, $\\mathsf{Poly}_\\mathsf{Arr_2}$, and $\\mathsf{Poly}_\\mathsf{Arr_3}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$). It will commit to each polynomial: $K_\\mathsf{Arr_1}$,$K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$. The verifier ($\\mathcal{V}$) cannot check any of the $\\mathsf{Arr_i}$ or $\\mathsf{Poly}_\\mathsf{Arr_i}$ values directly (they may contain secret information, and even if they do not, they are too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$,$K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$.\nIn order to prove $K_\\mathsf{Arr_1}$,$K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$ are consistent, the prover can use one of two methods.\nThe most straight-forward method is to use the additive homomorphic property of the KZG polynomial commitment scheme which states that for equal-sized polynomials on the same domain:\n$K_\\mathsf{Arr_1}\\otimes K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}\\oplus \\mathsf{Poly}_\\mathsf{Arr_2})$ Here $\\otimes$ is multiplication in the KZG group (e.g., $\\mathbb{G}_1$ in BLS12-381) while $\\oplus$ is addition in $\\mathbb{Z}_q$ of each evaluation point in $ \\mathsf{Poly}_\\mathsf{Arr_1}$ with each evaluation point in $\\mathsf{Poly}_\\mathsf{Arr_2}$. If the prover ($\\mathcal{P}$) can set $K_\\mathsf{Arr_3}\\leftarrow K_\\mathsf{Arr_1}\\otimes K_\\mathsf{Arr_2}$, then the verifier can check $K_\\mathsf{Arr_3}\\stackrel{?}{=}K_\\mathsf{Arr_1}\\otimes K_\\mathsf{Arr_2}$.\nHowever a second method is needed in other cases. Note that there are many different polynomials that interpolate $\\mathsf{Arr_3}$ on the domain $\\mathcal{H}_\\kappa$ (but are different elsewhere in the polynomial outside of $\\mathcal{H}_\\kappa)$. Each of these polynomials will have a unique commitment value. So it is possible that $K_\\mathsf{Arr_3}\\neq K_\\mathsf{Arr_1}\\otimes K_\\mathsf{Arr_2}$, and yet $\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i]$ for all $i$. This arrises when $\\mathsf{Poly}_\\mathsf{Arr_3}$ comes from a different part of the protocol than $\\mathsf{Poly}_\\mathsf{Arr_1}$ and $\\mathsf{Poly}_\\mathsf{Arr_2}$.\nThe second method is more general so it can be used in place of the first method (but is more expensive), as well as covering all cases where $\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i]$. The idea is to show $\\mathsf{Arr_3}[i]-\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i]=0$ for each evaluation point in the domain $\\mathcal{H}_\\kappa$. Showing a polynomial is zero on the domain (a \u0026ldquo;vanishing polynomial\u0026rdquo;) is a common sub-protocol used by many gadgets.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ computes or holds an array $\\mathsf{Arr_3} = [a_{(3,0)}, a_{(3,1)}, a_{(3,2)}, \\dots, a_{(3,n-1)}]$ of $n$ integers ($a_{(3,i)} \\in \\mathbb{Z}_q$) such that: $\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i]$ for $i$ from 0 to $n-1$ Polynomial Level # We assume the three arrays $\\mathsf{Arr_1}$, $\\mathsf{Arr_2}$, and $\\mathsf{Arr_3}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 0 (which will not change the sum).\nRecall the constraint we want to prove:\n$\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Arr_2}[i]$ for $i$ from 0 to $n-1$ In polynomial form, the constraint is:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_3}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Arr_2}(X)$ We adjust the constraints to show an equality with 0 and label it:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Vanish}(X)= \\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Arr_2}(X) - \\mathsf{Poly}_\\mathsf{Arr_3}(X)=0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(X)}{X^\\kappa - 1}$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$ Ultimately the add1 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_3}(X)$. Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) are too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$\n$K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$\n$K_\\mathsf{Arr_3}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_3}(X))$\n$K_Q=\\mathsf{KZG.Commit}(Q(X))$\nThe prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$\n$\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$\n$\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$\n$\\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_3},\\zeta)$\n$Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$\nTo check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish}=\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)+\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta)$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Rust Mathematica (Toy Example) Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr_1}, \\mathsf{Arr_2}$ and $\\mathsf{Arr_3}$ such that $\\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i] - \\mathsf{Arr_3}[i] = 0 \\space \\forall i \\in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$ = Y_\\mathsf{Vanish} - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$ = \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta) - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta) - \\frac{\\mathsf{Poly_{Vanish}}(\\zeta)}{\\zeta^\\kappa - 1}\\cdot(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)+\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta))$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish}}(X)$ is vanishing on $\\mathcal{H_\\kappa}$, i.e. if $\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Arr_2}(X) - \\mathsf{Poly}_\\mathsf{Arr_3}(X) =0 \\space \\forall X \\in \\mathcal{H}_\\kappa$. This is true if if $\\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i] - \\mathsf{Arr_3}[i] = 0 \\space \\forall i \\in [0, \\kappa - 1]$, since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$. But $\\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i] - \\mathsf{Arr_3}[i] = 0 \\space \\forall i \\in [0, \\kappa - 1]$ is precisely the relation tnat we assumed held for our prover (if $\\kappa \\gt n$ then the arrays get padded such that this relation still holds), thus the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr3}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr3}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{\\mathcal{V}}$ accepts at the end of the protocol\nii) $\\mathsf{Arr}_3\\neq \\mathsf{Arr}_1 + \\mathsf{Arr}_2$\nOur proof is as follows:\nFor the second win condition to be fulfilled, the constraint must not hold for at least one index of the arrays. But then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calculate the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Arr1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr2}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr3}(X)$. Each commitment $\\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr2}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\zeta)$ can only feasibliy be opened to one value each. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr2}(\\tau)}$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\tau)$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Arr2}(\\tau)}$, and $g^{\\mathsf{Poly}_\\mathsf{Arr3}(\\tau)}$ to write as the commitments $K_\\mathsf{Arr1}$, $ K_\\mathsf{Arr2}$, and $ K_\\mathsf{Arr3}$. $\\mathcal{S}$ then generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr2}(\\tau)}$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\tau)$. $\\mathcal{S}$ writes the commitment $K_Q = g^{Q(\\tau)}$ to the transcript.\nNow, $\\mathcal{S}$ generates the second random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Arr2}(\\zeta)}$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\zeta)$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generated from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nFor add2, the proof is written with a simulator that doesn\u0026rsquo;t know the trapdoor; however, with small alterations the proof for add2 should apply here and vice versa "},{"id":3,"href":"/docs/gadgets/add2/","title":"Add2","section":"Gadgets","content":" Addition (Type 2) # Recap of types # Type Description Recap This add1 $\\mathsf{Arr}_3=\\mathsf{Arr}_1 + \\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the element-wise addition of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. add2 $\\mathsf{Sum}_\\mathsf{Arr}=\\sum_{i = 0}^{n-1} \\mathsf{Arr}[i]$ $\\mathsf{Sum}_\\mathsf{Arr}$ is the disclosed sum of all the elements in $\\mathsf{Arr}$. ✅ add3 $\\sum_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\sum_{i = 0}^{n-1} \\mathsf{Arr}_2[i]$ $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ have the same undisclosed sum. Relation # $ \\mathcal{R}_{\\mathtt{add2}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr},\\mathsf{Sum}_\\mathsf{Arr}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}], \\\\ \\mathsf{Sum}_\\mathsf{Arr} = \\sum_{i = 0}^{n-1} a_i, \\\\ \\mathsf{Poly}_\\mathsf{Arr}(X)=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X)) \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds an array $\\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers (from $\\mathbb{Z}_q$) and a disclosed integer $\\mathsf{Sum}_\\mathsf{Arr}$. It will produce a succinct (independent of $n$) proof that $\\mathsf{Sum}_\\mathsf{Arr}$ is the sum of all the elements in the array. The prover will encode the array into a polynomial $\\mathsf{Poly}_\\mathsf{Arr}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to the polynomial $K_\\mathsf{Arr}$. The verifier ($\\mathcal{V}$) cannot check $\\textsf{Arr}$ or $\\mathsf{Poly}_\\mathsf{Arr}$ directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr}$ and the asserted value $\\mathsf{Sum_\\mathsf{Arr}}$.\nIn order to prove $K_\\mathsf{Arr}$ and $\\mathsf{Sum}_\\mathsf{Arr}$ are consistent, the prover will build a helper array $\\mathsf{Acc}_\\mathsf{Arr}$ called an accumulator (or accumulating array or incremental array). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\\mathsf{Arr}$, the prover will also encode $\\mathsf{Acc}$ as a polynomial and provide a commitment of it to the verifier. The idea is that the prover will prove a relation between $\\mathsf{Arr}$ and $\\mathsf{Acc}$; and a relation between $\\mathsf{Acc}$ and $\\mathsf{Sum_\\mathsf{Arr}}$. Put together, it will imply the correct relation between $\\mathsf{Arr}$ and $\\mathsf{Sum_\\mathsf{Arr}}$.\nConsider a small numeric example in $\\mathbb{Z}_{97}$ where $\\mathsf{Arr}= [84,67,11,92,36,67]$ and $\\mathsf{Sum}_\\mathsf{Arr}=66$. The first idea is to get $\\mathsf{Sum}_\\mathsf{Arr}$ into an array. Say, we just append it: $\\mathsf{Arr}''= [84,67,11,92,36,67,66] $. How does the prover show $\\mathsf{Arr}''$ is correct? The last value of the array depends on every single element that precedes it, which will be a complex constraint to prove.\nAn alternative idea is to create a new array that starts the same as $\\mathsf{Arr}$ and ends up at $\\mathsf{Sum}_\\mathsf{Arr}$ by folding in the integers from $\\mathsf{Arr}$ one-by-one with addition. Then each value in the new array will depend on only two values, as below.\nThe first value in $\\mathsf{Acc}$ will be a copy of the first value from $\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$\\mathsf{Acc}= [84, \\bot,\\bot,\\bot,\\bot,\\bot] $\nThe next value will be the addition (mod 97) of: 67 (the value at the same index in $\\mathsf{Arr}$) and 84 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$ \\mathsf{Acc} = [84, (67+84),\\bot,\\bot,\\bot,\\bot] = [84, 54,\\bot,\\bot,\\bot,\\bot]$\nThe next value will be the addition of: 11 (the value at the same index in $\\mathsf{Arr}$) and 54 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [84, 54,(11+54),\\bot,\\bot,\\bot] = [84,54,65,\\bot,\\bot,\\bot]$ $ \\mathsf{Acc} = [84, 54, 65,(92+65),\\bot,\\bot] = [84,54,65, 60,\\bot,\\bot]$ $ \\mathsf{Acc} = [84,54,65, 60,(36 + 60),\\bot] = [84,54,65, 60, 96,\\bot]$ $ \\mathsf{Acc} = [84,54,65, 60, 96, (67+96)] = [84,54,65, 60, 96, 66]$ $\\mathsf{Sum}_\\mathsf{Arr}=66$ Notice the last value in $\\mathsf{Acc}$ is $\\mathsf{Sum_\\mathsf{Arr}}$. The prover wants to show three constraints:\nThe first value in $\\mathsf{Acc}$ matches the first value in $\\mathsf{Arr}$, The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i]+\\mathsf{Acc}[i-1]$, The last value in $\\mathsf{Acc}$ matches $\\mathsf{Sum}_\\mathsf{Arr}$. If all three constraints are true, then $\\mathsf{Sum}_\\mathsf{Arr}$ is the sum of the elements of $\\mathsf{Arr}$.\nLast, while it is not necessary to do, it is often convenient to hold the the value $\\mathsf{Sum}_\\mathsf{Arr}$ at the start of the array $\\mathsf{Acc}$ instead of the end. For this reason, the mathematical explaination below will construct $\\mathsf{Acc}$ \u0026ldquo;backwards\u0026rdquo; (or right-to-left) from the above example, where the last value of $\\mathsf{Acc}$ matches the last value of $\\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\\mathsf{Acc}$ is $\\mathsf{Sum}_\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, \\bot, 67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, 6, 67]$ $\\ldots$ $ \\mathsf{Acc} = [66, 79, 12, 1, 6, 67]$ $\\mathsf{Sum}_\\mathsf{Arr}=66$ Protocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers ($a_i \\in \\mathbb{Z}_q$) $\\mathcal{P}$ computes array $\\mathsf{Acc}$ as follows: $\\mathsf{Acc}[n-1]\\leftarrow\\mathsf{Arr}[n-1]$ $\\mathsf{Acc}[i]\\leftarrow\\mathsf{Arr}[i]+\\mathsf{Acc}[i+1]$ for $i$ from $n-2$ to 0 $\\mathcal{P}$ computes $\\mathsf{Sum}_\\mathsf{Arr}\\leftarrow\\mathsf{Acc}[0]$ Polynomial Level # We assume arrays $\\mathsf{Arr}$ and $\\mathsf{Acc}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 0 (which will not change the sum).\nRecall the three constraints we want to prove (now adjusted to fit with an $\\mathsf{Acc}$ that is constructed \u0026ldquo;backwards,\u0026rdquo; as noted above):\nThe last value in $\\mathsf{Acc}$ matches the last value in $\\mathsf{Arr}$, The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i]+\\mathsf{Acc}[i-1]$, The first value in $\\mathsf{Acc}$ matches $\\mathsf{Sum}_\\mathsf{Arr}$. In polynomial form, the constraints are:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Sum}_\\mathsf{Arr}$ In constraint 2, $\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ can also be conceptualized as rotate applied to $\\mathsf{Poly}_\\mathsf{Acc}(X)$ by one element (rightward in the array view). Also note that constraint 2 does not hold at $X=\\omega^{\\kappa-1}$ because this value is defined by constraint 1 (for the last value of $X$, the \u0026ldquo;next\u0026rdquo; value, $\\omega X$, wraps back to the first element of the array which is a boundary condition).\nWe adjust each of these constraints to show an equality with 0:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)=0$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)=0$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Sum}_\\mathsf{Arr}=0$ Next we take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X))\\cdot(X-\\omega^{\\kappa-1})=0$ $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These equations are true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$, and $\\mathsf{Poly}_\\mathsf{Vanish3}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prove computes,\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ $Q_3(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$, $Q_2(X)$, and $Q_3(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all three $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all three are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2}{X^\\kappa - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(X) + \\rho^2 \\mathsf{Poly}_\\mathsf{Vanish3}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the add2 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Acc}(X)$, $\\mathsf{Poly}_\\mathsf{Acc}(\\omega X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, and $\\mathsf{Sum}_\\mathsf{Arr}$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X))$ $K_\\mathsf{Acc}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Acc}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Acc},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}=(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish2}=(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Vanish3}=(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)}$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Rust Mathematica (Toy Example) Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}$ such that $\\mathsf{Sum}_\\mathsf{Arr}=\\sum_{i = 0}^{n-1} \\mathsf{Arr}[i] \\space \\forall i \\in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)} \\newline - \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(\\zeta)\\rho^2}{\\zeta^\\kappa - 1} \\cdot(\\zeta^\\kappa - 1)$\n$= (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)} \\newline - ((\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) \\newline + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)})$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(\\zeta)\\rho^2$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish_1}}(X), \\mathsf{Poly_{Vanish_2}}(X)$ and $\\mathsf{Poly_{Vanish_3}}(X),$ are all vanishing on $\\mathcal{H_\\kappa}$, i.e. if all three of the following conditions hold for all $X \\in \\mathcal{H}_\\kappa$:\n$(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$ $ (\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X))\\cdot(X-\\omega^{\\kappa-1})=0$ $ (\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These conditions, in turn, hold if:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Sum}_\\mathsf{Arr}$ Where we get the \u0026ldquo;For $X$\u0026rdquo; due to zeroing parts of the polynomials (see zero1). Since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$, the above conditions are true if:\nThe last value in $\\mathsf{Acc}$ matches the last value in $\\mathsf{Arr}$ The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i]+\\mathsf{Acc}[i-1]$ The first value in $\\mathsf{Acc}$ matches $\\mathsf{Sum}_\\mathsf{Arr}$ Which are precisely the conditions the Intuitions sections explains will hold if the prover contructs their Accumulator by following the protocol and using $\\mathsf{Arr}$ such that $\\mathsf{Sum}_\\mathsf{Arr}=\\sum_{i = 0}^{n-1} \\mathsf{Arr}[i] \\space \\forall i \\in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Acc}(X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Acc}(X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Sum}_\\mathsf{Arr}\\neq\\sum_{i = 0}^{n-1} \\mathsf{Arr}[i]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, one of the three constraints must be false. But then the $\\mathsf{Poly}_\\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Acc}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr}(X)$. Each commitment $\\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta \\cdot \\omega)$ can only feasibliy be opened to one value each. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2Y_\\mathsf{Vanish3}}{\\zeta^\\kappa - 1}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2Y_\\mathsf{Vanish3}}{\\zeta^\\kappa - 1}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $A$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ generates an array $\\mathsf{Arr'}$ whose product is equal to the disclosed value $\\mathsf{Sum}_\\mathsf{Arr}$ (this array could just have $\\mathsf{Prod}_\\mathsf{Sum}$ in one entry, and $0$\u0026rsquo;s elsewhere), then follows the same steps a prover would to prove the sum of this array. So, $\\mathcal{S}$ computes the accumulator $\\mathsf{Acc'}$ and interpolates the two arrays into their respective polynomials, $\\mathsf{Poly}_\\mathsf{Acc'}(X)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(X)$. It computes $Q(X)'$ using $\\mathsf{Poly}_\\mathsf{Acc'}(X)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(X)$ and the random challenge point $\\rho'$ (by strong Fiat-Shamir). $\\mathcal{S}$ commits to each of these three polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta'$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_\\mathsf{Acc'}(\\zeta'), \\space \\mathsf{Poly}_\\mathsf{Arr'}(\\zeta'), \\space Q(\\zeta')'$, and $\\mathsf{Poly}_\\mathsf{Acc'}(\\zeta' \\cdot \\omega)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nThis proof could also be done by defining a simulator that knows the trapdoor $\\tau$ and can thus create a passing witness for any commitment. The proof for add1 is done in this style, but with small alterations would work here as well (and vice versa with this style of proof working for add1) "},{"id":4,"href":"/docs/gadgets/add3/","title":"Add3","section":"Gadgets","content":" Addition (Type 3) # Recap of types # Type Description Recap This add1 $\\mathsf{Arr}_3=\\mathsf{Arr}_1 + \\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the element-wise addition of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. add2 $\\mathsf{Sum}_\\mathsf{Arr}=\\sum_{i = 0}^{n-1} \\mathsf{Arr}[i]$ $\\mathsf{Sum}_\\mathsf{Arr}$ is the disclosed sum of all the elements in $\\mathsf{Arr}$. add3 $\\sum_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\sum_{i = 0}^{n-1} \\mathsf{Arr}_2[i]$ $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ have the same undisclosed sum. ✅ Relation # $ \\mathcal{R}_{\\mathtt{add3}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr2}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}],\\\\ \\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}], \\\\ \\mathsf{Poly}_\\mathsf{Arr_1}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_1}), \\\\ \\mathsf{Poly}_\\mathsf{Arr_2}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_2}), \\\\ K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}),\\\\ K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}), \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds two arrays $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that they have the same undisclosed sum. The prover will encode the two arrays into polynomials, $\\mathsf{Poly}_\\mathsf{Arr_1}$ and $\\mathsf{Poly}_\\mathsf{Arr_2}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to them as $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$. The verifier ($\\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$.\nIn order to prove $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$ are consistent, the prover will build two helper arrays $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$ called accumulators (or accumulating arrays or incremental arrays). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$, the prover will also encode $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$ as a polynomials and provide a commitment to the verifier of each one. The idea is that the prover will prove a relation between each $\\mathsf{Arr}$ and its $\\mathsf{Acc}$; and a relation between $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$. Put together, it will imply the correct relation between $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$.\nWe will illustrate a small numerical example in $\\mathbb{Z}_{97}$ of constructing an accumulator $\\mathsf{Acc}$ for the array $\\mathsf{Arr}= [84,67,11,92,36,67]$. The idea is to create a new array, $\\mathsf{Acc}$, that starts the same as $\\mathsf{Arr}$ and ends with the sum of all entries of $\\mathsf{Arr}$, by folding in the integers from $\\mathsf{Arr}$ one-by-one with multiplication. Then each value in the new array will depend on only two values, as below.\nThe first value in $\\mathsf{Acc}$ will be a copy of the first value from $\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$\\mathsf{Acc}= [84, \\bot,\\bot,\\bot,\\bot,\\bot] $\nThe next value will be the addition (mod 97) of: 67 (the value at the same index in $\\mathsf{Arr}$) and 84 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$ \\mathsf{Acc} = [84, (67+84),\\bot,\\bot,\\bot,\\bot] = [84, 54,\\bot,\\bot,\\bot,\\bot]$\nThe next value will be the addition of: 11 (the value at the same index in $\\mathsf{Arr}$) and 54 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [84, 54,(11+54),\\bot,\\bot,\\bot] = [84,54,65,\\bot,\\bot,\\bot]$ $ \\mathsf{Acc} = [84, 54, 65,(92+65),\\bot,\\bot] = [84,54,65, 60,\\bot,\\bot]$ $ \\mathsf{Acc} = [84,54,65, 60,(36 + 60),\\bot] = [84,54,65, 60, 96,\\bot]$ $ \\mathsf{Acc} = [84,54,65, 60, 96, (67+96)] = [84,54,65, 60, 96, 66]$ $\\mathsf{Sum}_\\mathsf{Arr}=66$ Notice the last value in $\\mathsf{Acc}$ is $\\mathsf{Sum_\\mathsf{Arr}}$. The prover wants to show three constraints:\nThe first value in $\\mathsf{Acc}$ matches the first value in $\\mathsf{Arr}$, The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i]+\\mathsf{Acc}[i-1]$, The last value in $\\mathsf{Acc}$ matches $\\mathsf{Sum}_\\mathsf{Arr}$. If all three constraints are true, then $\\mathsf{Sum}_\\mathsf{Arr}$ is the sum of the elements of $\\mathsf{Arr}$.\nLast, while it is not necessary to do, it is often convenient to hold the the value $\\mathsf{Sum}_\\mathsf{Arr}$ at the start of the array $\\mathsf{Acc}$ instead of the end. For this reason, the mathematical explaination below will construct $\\mathsf{Acc}$ \u0026ldquo;backwards\u0026rdquo; (or right-to-left) from the above example, where the last value of $\\mathsf{Acc}$ matches the last value of $\\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\\mathsf{Acc}$ is $\\mathsf{Sum}_\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, \\bot, 67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, 6, 67]$ $\\ldots$ $ \\mathsf{Acc} = [66, 79, 12, 1, 6, 67]$ and the sum of all entries in $\\mathsf{Acc}$ is 66 Protocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ computes array $\\mathsf{Acc_j}$ as follows for $j \\in [1,2]$: $\\mathsf{Acc_j}[n-1]\\leftarrow\\mathsf{Arr_j}[n-1]$ $\\mathsf{Acc_j}[i]\\leftarrow\\mathsf{Arr_j}[i]+\\mathsf{Acc_j}[i+1]$ for $i$ from $n-2$ to 0 Polynomial Level # We assume arrays $\\mathsf{Arr_1}$, $\\mathsf{Arr_2}$, $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 0 (which will not change the sum).\nRecall the five constraints we want to prove (now adjusted to fit with an $\\mathsf{Acc}$ that is constructed \u0026ldquo;backwards,\u0026rdquo; as noted above):\nThe last value in $\\mathsf{Acc_1}$ matches the last value in $\\mathsf{Arr_1}$ The last value in $\\mathsf{Acc_2}$ matches the last value in $\\mathsf{Arr_2}$ The rest of the values in $\\mathsf{Acc}_1$ are of the form $\\mathsf{Acc_1}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Acc_1}[i-1]$ The rest of the values in $\\mathsf{Acc}_2$ are of the form $\\mathsf{Acc_2}[i]=\\mathsf{Arr_2}[i]+\\mathsf{Acc_2}[i-1]$ The first value in $\\mathsf{Acc_1}$ matches the first value in $\\mathsf{Acc_2}$ In polynomial form, the constraints are:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, For $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)+\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Acc_2}(X)$ In constraints 2 and 3, $\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ can also be conceptualized as rotate applied to $\\mathsf{Poly}_\\mathsf{Acc}(X)$ by one element (rightward in the array view). Also note that constraints 2 and 3 do not hold at $X=\\omega^{\\kappa-1}$ because this value is defined by constraint 1 (for the last value of $X$, the \u0026ldquo;next\u0026rdquo; value, $\\omega X$, wraps back to the first element of the array which is a boundary condition).\nWe adjust each of these constraints to show an equality with 0:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X)=0$, For $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X)=0$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)=0$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X)+\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)=0$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Acc_2}(X)=0$ Next we take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=(\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$, $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-(\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)))\\cdot(X-\\omega^{\\kappa-1})=0$ $\\mathsf{Poly}_\\mathsf{Vanish4}(X)=(\\mathsf{Poly}_\\mathsf{Acc_2}(X)-(\\mathsf{Poly}_\\mathsf{Arr_2}(X)+\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)))\\cdot(X-\\omega^{\\kappa-1})=0$ $\\mathsf{Poly}_\\mathsf{Vanish5}(X)=(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Acc_2}(X)\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These equations are true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish3}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish4}(X)$, and $\\mathsf{Poly}_\\mathsf{Vanish5}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prove computes,\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ $Q_3(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^\\kappa - 1}$ $Q_4(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish4}(X)}{X^\\kappa - 1}$ $Q_5(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish5}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$, $Q_2(X)$, $Q_3(X)$, $Q_4(X)$, and $Q_5(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all five $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all five are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4}{X^\\kappa - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2} (X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X) \\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4 - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the add3 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$ $K_\\mathsf{Acc_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Acc_1}(X))$ $K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$ $K_\\mathsf{Acc_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Acc_2}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Acc_1},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Acc_2},\\zeta\\omega)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}= (\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish2}= (\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish3}=(\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)-(\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot \\zeta)))\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Vanish4}= (\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)-(\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot \\zeta)))\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Vanish5}= (\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)-\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)}$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5}- Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ such that $\\sum_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\sum_{i = 0}^{n-1} \\mathsf{Arr}_2[i] \\space \\forall i \\in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$ = Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5}- Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5} - (\\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4}{X^\\kappa - 1})(\\zeta^\\kappa - 1)$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5} - {\\mathsf{Poly}_\\mathsf{Vanish1}(X) - \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho - \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 - \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 - \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4}$\n$= 0$\nWhere the finally equality holds becaue $Y_{\\mathsf{Vanish_j}}=\\mathsf{Poly_{Vanish_j}}(\\zeta)$.\nNote also that the second equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish_1}}(X), \\mathsf{Poly_{Vanish_2}}(X)$, $\\mathsf{Poly_{Vanish_3}}(X),$ $\\mathsf{Poly_{Vanish_4}}(X)$, and $\\mathsf{Poly_{Vanish_5}}(X),$ are all vanishing on $\\mathcal{H_\\kappa}$, i.e. if all three of the following conditions hold for all $X \\in \\mathcal{H}_\\kappa$:\n$ (\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$ $ (\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$ $(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-(\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)))\\cdot(X-\\omega^{\\kappa-1})=0$ $ (\\mathsf{Poly}_\\mathsf{Acc_2}(X)-(\\mathsf{Poly}_\\mathsf{Arr_2}(X)+\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)))\\cdot(X-\\omega^{\\kappa-1})=0$ $ (\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Acc_2}(X)\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These conditions, in turn, hold if:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)$ For $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)+\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)+\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Acc_2}(X)$ Where we get the \u0026ldquo;For $X$\u0026rdquo; due to zeroing parts of the polynomials (see zero1). Since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$, the above conditions are true if:\nThe last value in $\\mathsf{Acc_1}$ matches the last value in $\\mathsf{Arr_1}$ The last value in $\\mathsf{Acc_2}$ matches the last value in $\\mathsf{Arr_2}$ The rest of the values in $\\mathsf{Acc}_1$ are of the form $\\mathsf{Acc_1}[i]=\\mathsf{Arr_1}[i]+\\mathsf{Acc_1}[i-1]$ The rest of the values in $\\mathsf{Acc}_2$ are of the form $\\mathsf{Acc_2}[i]=\\mathsf{Arr_2}[i]+\\mathsf{Acc_2}[i-1]$ The first value in $\\mathsf{Acc_1}$ matches the first value in $\\mathsf{Acc_2}$ Which are precisely the conditions the Intuitions sections explains will hold if the prover contructs their Accumulators by following the protocol and using $\\mathsf{Arr}_1$ and $\\mathsf{Arr_2}$ such that $\\sum_{i = 0}^{n-1} \\mathsf{Arr}_1[i] =\\sum_{i = 0}^{n-1} \\mathsf{Arr}_2[i] \\space \\forall i \\in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_{2}}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_{2}}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_{2}}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_{2}}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\sum_{i = 0}^{n-1} \\mathsf{Arr_1}[i]\\neq\\sum_{i = 0}^{n-1} \\mathsf{Arr_2}[i]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, one of the five constraints must be false. But then the $\\mathsf{Poly}_\\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$. Each commitment $\\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta \\cdot \\omega)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta \\cdot \\omega)$ can each only feasibliy be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4Y_\\mathsf{Vanish5}}{(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4Y_\\mathsf{Vanish5}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Acc_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$ and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\tau)$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Acc_1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, and $g^{\\mathsf{Poly}_\\mathsf{Acc_2}(\\tau)}$ to write as the commitments $K_\\mathsf{Arr_1}$, $ K_\\mathsf{Acc_1}$, $K_\\mathsf{Arr_2}$, and $ K_\\mathsf{Acc_2}$. $\\mathcal{S}$ then generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Acc_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$ and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\tau)$. $\\mathcal{S}$ writes the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the second random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta \\cdot \\omega)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)}$, and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta\\cdot\\omega)$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4Y_\\mathsf{Vanish5}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nFor mult2, the proof is written with a simulator that doesn\u0026rsquo;t know the trapdoor; however, with small alterations the proof for mult2 should apply here and vice versa "},{"id":5,"href":"/docs/gadgets/circuit/","title":"Circuit","section":"Gadgets","content":" Circuit # Recap of types # Type Description Recap This circuit $z=\\mathsf{Circ}(x,y)$ $z$ is the output of disclosed arithmetic circuit $\\mathsf{Circ}$ with disclosed (and/or undisclosed) inputs $x$ and $y$. ✅ Relation # $\\mathcal{R}_{\\mathtt{circ}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{T},K_\\mathsf{In}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{In}=[i_0,i_1,i_2,i_3], \\\\ \\mathsf{T}=[t_0,t_1,t_2,t_3], \\\\ \\mathsf{T}[3]\\in\\{0,1\\}, \\\\ \\mathsf{T}[3]\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{T}[0]+\\mathsf{In}[1]\\cdot\\mathsf{T}[1])+(1-\\mathsf{T}[3])\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{In}[1]\\cdot\\mathsf{T}[2])+\\mathsf{In}[2]=\\mathsf{In}[3], \\\\ \\mathsf{Poly}_\\mathsf{T}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{T}), \\\\ \\mathsf{Poly}_\\mathsf{In}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{In}), \\\\ K_\\mathsf{T}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T}), \\\\ K_\\mathsf{In}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{In}) \\\\ \\end{array} \\right\\}$\nIntuition # The prover ($\\mathcal{P}$) and the verifier ($\\mathcal{V}$) are both given a circuit $\\mathsf{T}$, where $\\mathsf{T}[0]$ and $\\mathsf{T}[1]$ are the coefficients of the two inputs respectively, $\\mathsf{T}[2]$ is the coefficient of the product of the two inputs, and $\\mathsf{T}[3]$ is the selector of the gate ($\\mathsf{T}[3]$ is one for addition gate and zero for multiplication gate). The prover wants to prove he knows an input vector $\\mathsf{In}$ satisfying $\\mathsf{T}$. Specifically, we define $\\mathsf{In}[0]$ and $\\mathsf{In}[1]$ are the inputs of the circuit, $\\mathsf{In}[2]$ is a constant, and $\\mathsf{In}[3]$ is the output. Thus, the prover will produce a succinct proof that $\\mathsf{In}$ satisfies the following condition: the equation $\\mathsf{T}[3]\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{T}[0]+\\mathsf{In}[1]\\cdot\\mathsf{T}[1])+(1-\\mathsf{T}[3])\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{In}[1]\\cdot\\mathsf{T}[2])+\\mathsf{In}[2]=\\mathsf{In}[3]$ holds.\nThis means that if $\\mathsf{T}[3] = 0$, this is the circuit which must be satisfied:\nflowchart LR in0[\"In[0]\"] \u0026 in1[\"In[1]\"] --\u003e id1((x)) t2[\"T[2]\"] \u0026 id1 --\u003e id2((x)) in2[\"In[2]\"] \u0026 id2 --\u003e id3((+)) id3 --\u003e in3[\"In[3]\"] And if $\\mathsf{T}[3] = 1$, this is the circuit which must be satisfied:\nflowchart LR in0[\"In[0]\"] \u0026 t0[\"T[0]\"] --\u003e id1((x)) in1[\"In[1]\"] \u0026 t1[\"T[1]\"] --\u003e id2((x)) id1 \u0026 id2 --\u003e id3((+)) in2[\"In[2]\"] \u0026 id3 --\u003e id4((+)) id4 --\u003e in3[\"In[3]\"] Consider, as an example, the circuit $5x+6y$. Thus, $\\mathsf{T}=[5,6,0,1]$. Since $\\mathsf{T}$ is publicly known to both parties, $\\mathsf{Poly}_\\mathsf{T}$ is also known and the prover does not need to prove the correctness of $\\mathsf{T}$. Now the prover claims $\\mathsf{In}=[6,5,0,60]$ satisfies the circuit. Indeed, $5\\cdot 6+ 6\\cdot 5 + 0 = 60$. Instead of sending each element of $\\mathsf{In}$ one by one to show this, the prover interpolates a polynomial $\\mathsf{Poly}_\\mathsf{In}$ from $\\mathsf{In}$ and computes a vanishing polynomial with $\\mathsf{Poly}_\\mathsf{T}$ and $\\mathsf{Poly}_\\mathsf{In}$. If the prover can prove the polynomial is vanishing, the verifier will be convinced that the prover knows a valid $\\mathsf{In}$.\nProtocol Details # Array Level # $\\mathsf{P}$ and $\\mathsf{V}$ hold the array of the circuit $\\mathsf{T}=[t_0,t_1,t_2,t_3]$ $\\mathsf{P}$ holds an input array $\\mathsf{In}=[i_0,i_1,i_2,i_3]$ $\\mathsf{T}$ and $\\mathsf{In}$ satisfy the following conditions $\\mathsf{T}[3]\\in\\{0,1\\}$ $\\mathsf{T}[3]\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{T}[0]+\\mathsf{In}[1]\\cdot\\mathsf{T}[1])+(1-\\mathsf{T}[3])\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{In}[1]\\cdot\\mathsf{T}[2])+\\mathsf{In}[2]=\\mathsf{In}[3]$ Polynomial Level # We assume arrays $\\mathsf{T}$ and $\\mathsf{In}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product). In this case, $\\kappa$ is $4$.\nRecall the constraint we want to prove:\n$\\mathsf{T}[3]\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{T}[0]+\\mathsf{In}[1]\\cdot\\mathsf{T}[1])+(1-\\mathsf{T}[3])\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{In}[1]\\cdot\\mathsf{T}[2])+\\mathsf{In}[2]=\\mathsf{In}[3]$ In polynomial form, the constraint is:\nFor $X=\\omega^0$: $\\displaylines{\\mathsf{Poly}_\\mathsf{T}(X\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(X)\\cdot\\mathsf{Poly}_\\mathsf{T}(X)+\\mathsf{Poly}_\\mathsf{In}(X\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega))\\\\+(1-\\mathsf{Poly}_\\mathsf{T}(X\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(X)\\cdot\\mathsf{Poly}_\\mathsf{In}(X\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega^2))+\\mathsf{Poly}_\\mathsf{In}(X\\omega^2)=\\mathsf{Poly}_\\mathsf{In}(X\\omega^3)}$ We take care of the \u0026ldquo;for $X$\u0026rdquo; condition by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\displaylines{\\mathsf{Poly}_\\mathsf{Vanish}(X)=[\\mathsf{Poly}_\\mathsf{T}(X\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(X)\\cdot\\mathsf{Poly}_\\mathsf{T}(X)+\\mathsf{Poly}_\\mathsf{In}(X\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega))\\\\+(1-\\mathsf{Poly}_\\mathsf{T}(X\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(X)\\cdot\\mathsf{Poly}_\\mathsf{In}(X\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega^2))+\\\\\\mathsf{Poly}_\\mathsf{In}(X\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(X\\omega^3)]\\cdot\\frac{X^\\kappa-1}{X-\\omega^0}}$ The equation is vanishing for every value of $X\\in\\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\\kappa-1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$$ Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(X)}{X^\\kappa-1} $$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish}(X)-Q(X)\\cdot(X^{\\kappa}-1)=0$\nUltimately the range gadget will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{T}(X)$ and $\\mathsf{Poly}_\\mathsf{In}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the vector $\\mathsf{In}$ or the polynomial $\\mathsf{Poly}_\\mathsf{In}$. It is undisclosed because it either (i) contains private data or (ii) is too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{T}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T}(X))$ $K_\\mathsf{In}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{In}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta)$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta\\omega^2)$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta\\omega^3)$ $\\mathsf{Poly}_\\mathsf{In}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{In},\\zeta)$ $\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{In},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)=\\mathsf{KZG.Open}(K_\\mathsf{In},\\zeta\\omega^2)$ $\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)=\\mathsf{KZG.Open}(K_\\mathsf{In},\\zeta\\omega^3)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$$ \\displaylines{Y_\\mathsf{Vanish}=[\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega))\\\\+(1-\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2))+\\\\\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^0}} $$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{In}$ that satisfies the circuit $\\mathsf{T}$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= \\mathsf{Poly}_\\mathsf{Vanish}(\\zeta)-Q(\\zeta)\\cdot(\\zeta^{\\kappa}-1)$\n$= [\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega))+(1-\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2))+\\\\\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^0} -Q(\\zeta)\\cdot(\\zeta^\\kappa-1)$\n$= [\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega))+(1-\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2))+\\\\\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^0} - \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(\\zeta)}{\\zeta^\\kappa-1} \\cdot(\\zeta^\\kappa-1)$\n$= [\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega))+(1-\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2))+\\\\\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^0} \\newline - [[\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega))+(1-\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2))+\\\\\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^0} \\cdot(\\zeta^\\kappa-1)]$\n$=0$\nWhere the third equality relies on the fact that $\\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\\kappa -1$. This is true if $\\mathsf{Poly_{Vanish}}(\\zeta)$ is vanishing on $\\mathcal{H}_\\kappa$, i.e. if:\n$\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega))+(1-\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega^2))\\\\+\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^2)-\\mathsf{Poly}_\\mathsf{In}(\\zeta\\omega^3)]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^0} = 0$\nWhich hold if, for $X=\\omega^0$:\n$ \\mathsf{Poly}_\\mathsf{T}(X\\omega^3)\\cdot(\\mathsf{Poly}_\\mathsf{In}(X)\\cdot\\mathsf{Poly}_\\mathsf{T}(X)+\\mathsf{Poly}_\\mathsf{In}(X\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega))+(1-\\mathsf{Poly}_\\mathsf{T}(X\\omega^3))\\cdot(\\mathsf{Poly}_\\mathsf{In}(X)\\cdot\\mathsf{Poly}_\\mathsf{In}(X\\omega)\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega^2))\\\\+\\mathsf{Poly}_\\mathsf{In}(X\\omega^2)=\\mathsf{Poly}_\\mathsf{In}(X\\omega^3)$\nWhere we get the \u0026ldquo;for $X = \\omega^0$\u0026rdquo; due to zeroing parts of the polynomials (see zero1). Since $\\mathsf{Poly_T}(\\omega^i) = \\mathsf{T}[i]$ and $\\mathsf{Poly_{In}}(\\omega^i) = \\mathsf{In}[i]$, $\\forall i \\in [0, \\kappa - 1]$, the above conditions are true if:\n$\\mathsf{T}[3]\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{T}[0]+\\mathsf{In}[1]\\cdot\\mathsf{T}[1])+(1-\\mathsf{T}[3])\\cdot(\\mathsf{In}[0]\\cdot\\mathsf{In}[1]\\cdot\\mathsf{T}[2])+\\mathsf{In}[2]=\\mathsf{In}[3]$\nBut this means precisely that $\\mathsf{In}$ satisfies the circuit $\\mathsf{T}$, which was the condition we assumed about the prover. Thus, the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g,g^\\tau,g^{\\tau^2},\\dots,g^{\\tau^{n-1}}]$, $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{In}(X)$ and $Q$ $\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{In}(X)$ and $Q$ $\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$ $\\mathcal{A}$ wins if $\\mathcal{V}$ accepts at the end of the protocol the values in $\\mathsf{In}$ do not satisfy the circuit The proof is trivial: to make $\\mathsf{Poly}_\\mathsf{Vanish}$ exist, the values in $\\mathsf{In}$ have to satisfy the circuit. By the Schwartz-Zippel lemma, the soundness error is $\\kappa/|\\mathbb{F}|$, which is negligible since $\\kappa=4$ and $\\mathbb{F}$ is enormous for any widely used elliptic curve.\nZero-Knowledge # To prove the above protocol is zero-knowledge, we do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ randomly generates $a$ and $b$ as the inputs of the circuit, and runs the circuit to compute the output $c$. Then $\\mathcal{S}$ follows the same steps a prover would prove the lookup argument. $\\mathcal{S}$ interpolates $\\mathsf{Poly}_\\mathsf{In^*}$ from $\\mathsf{In^*}$. It computes $Q^*(X)$ and finally outputs the commitments to each of these polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta^*$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_\\mathsf{T^*}$ and $\\mathsf{Poly}_\\mathsf{In^*}$ at $\\zeta^*,\\zeta^*\\omega,\\zeta^*\\omega^2,\\zeta^*\\omega^3$ respectively, and $Q^*(\\zeta^*)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":6,"href":"/docs/gadgets/concat/","title":"Concat","section":"Gadgets","content":" Concatenation # Recap of types # Type Description Recap This concat $\\mathsf{Arr}_3=\\mathsf{Arr}_1\\cup\\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the concatenation of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ ✅ Relation # $$ \\mathcal{R}_{\\mathtt{mult1}} := \\left\\{ \\begin{array}{l} (K_{\\mathsf{Arr}_1},K_{\\mathsf{Arr}_2},K_{\\mathsf{Arr}_3}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr}_3=\\mathsf{Arr}_1\\cup\\mathsf{Arr}_2, \\\\ \\mathsf{Arr}_3[i]=\\mathsf{Arr}_1[i],i\\in[0,n_1), \\\\ \\mathsf{Arr}_3[i+n_1]=\\mathsf{Arr}_2[i],i\\in[0,n_2), \\\\ \\mathsf{Poly}_\\mathsf{Arr_j}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_j}), 1\\leq j \\leq 3, \\\\ K_\\mathsf{Arr_j}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_j}), 1\\leq j \\leq 3, \\end{array} \\right\\} $$ Intuition # The prover ($\\mathcal{P}$) holds three arrays $\\mathsf{Arr}_1$, $\\mathsf{Arr}_2$ and $\\mathsf{Arr_3}$. He wants to convince the verifier ($\\mathcal{V}$) $\\mathsf{Arr}_3$ is the concatenation of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. Specifically, assume there are $n_1$, $n_2$, and $n_3$ elements in $\\mathsf{Arr}_1$, $\\mathsf{Arr}_2$, and $\\mathsf{Arr}_3$ respectively, then the prover will prove: (i) $\\mathsf{Arr}_3[i]=\\mathsf{Arr}_1[i],i\\in[0,n_1)$ (ii) $\\mathsf{Arr}_3[i+n_1]=\\mathsf{Arr}_2[i],i\\in[0,n_2)$. It is intuitive to think about using the grand product check in the Plookup. However, the product check of Plookup holds if and only if (i) $\\mathsf{Arr}_1$ is the subset of $\\mathsf{Arr}_2$ (ii) $\\mathsf{Arr}_3$ is the union set of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ (iii) $\\mathsf{Arr}_3$ is sorted by $\\mathsf{Arr}$. Thus, we cannot use the product check directly, but we can leverage the same fact in the product check of Plookup: the product of $\\mathsf{Arr}_3$ equals the product of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ if and only if $\\mathsf{Arr}_3$ is the union set of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ (permutation check). Additionally, we need to prove the concatenation relationship rather than the permutation. To solve this problem, we can break $\\mathsf{Arr}_3$ to two sub arrays $\\mathsf{Arr}_{3_l}$ and $\\mathsf{Arr}_{3_h}$ as we do in Plookup, and prove the product of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ equals the product of $\\mathsf{Arr}_{3_l}$ and $\\mathsf{Arr}_{3_h}$.\nThe other approach is fill $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ with zero to $n_1+n_2$, and construct a new vector $\\mathsf{Arr}_2^\\prime$ by rotating right $\\mathsf{Arr}_2$ by $n_1$, so that $\\mathsf{Arr}_3$ is the sum of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2^\\prime$. Instead of performing the product check in the previous approach, the prover proves three things: (i) $\\mathsf{Arr}_2^\\prime$ is rotated from $\\mathsf{Arr}_2$ (ii) $\\mathsf{Arr}_3=\\mathsf{Arr}_1+\\mathsf{Arr}_2^\\prime$ (iii) $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ are correctly fill with zero. Since we already discussed how product check in the plookup works, we will focus on the second solution in this post.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr}_1=[a_{(1,0)},a_{(1,1),\\dots,a_{(1,n_1-1)}}]$ of $n_1$ integers and fills it with zero to $n_1+n_2$ such that $\\mathsf{Arr}_1[i]=a_{(1,i)},i\\in[0,n_1)$ $\\mathsf{Arr}_1[i]=0,i\\in[n_1,n_1+n_2)$ $\\mathcal{P}$ holds an array $\\mathsf{Arr}_2=[a_{(2,0)},a_{(2,1),\\dots,a_{(2,n_1-1)}}]$ of $n_2$ integers and fills it with zero to $n_1+n_2$ such that $\\mathsf{Arr}_2[i]=a_{(2,i)},i\\in[0,n_2)$ $\\mathsf{Arr}_2[i]=0,i\\in[n_2,n_1+n_2)$ $\\mathcal{P}$ holds an array $\\mathsf{Arr}_3$ of $n_1+n_2$ integers $\\mathcal{P}$ computes or holds an arrays $\\mathsf{Arr}_2^\\prime$ of $n_1+n_2$ integers such that $\\mathsf{Arr}_2^\\prime[i+n_1]=\\mathsf{Arr}_2[i],i\\in[0,n_1+n_2)$ $\\mathsf{Arr}_1$, $\\mathsf{Arr}_2^\\prime$, and $\\mathsf{Arr}_3$ satisfy: $\\mathsf{Arr}_3[i]=\\mathsf{Arr}_1[i]+\\mathsf{Arr}_2^\\prime[i],i\\in[0,n_1+n_2)$ Polynomial Level # We assume arrays $\\mathsf{Arr}_1$, $\\mathsf{Arr}_2$, and $\\mathsf{Arr}_3$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product).\nRecall the constraints we want to prove:\n$\\mathsf{Arr}_3[i]=\\mathsf{Arr}_1[i]+\\mathsf{Arr}_2^\\prime[i],i\\in[0,n_1+n_2)$ $\\mathsf{Arr}_2^\\prime[i+n_1]=\\mathsf{Arr}_2[i],i\\in[n_1,n_1+n_2)$ $\\mathsf{Arr}_1[i]=0,i\\in[n_1,n_1+n_2)$ $\\mathsf{Arr}_2[i]=0,i\\in[n_2,n_1+n_2)$ In polynomial form, the constraints are:\n$\\mathsf{Poly}_{\\mathsf{Arr}_3}(X)=\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)+\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X)$ $\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)=\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X\\omega^{n_1})$ For $X\\in[n_1,n_1+n_2)$, $\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)=0$ For $X\\in[n_2,n_1+n_2)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)=0$ Next we take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=\\mathsf{Poly}_{\\mathsf{Arr}_3}(X)-\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)-\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X)$ $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)-\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X\\omega^{n_1})$ $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)\\cdot\\frac{X^\\kappa-1}{\\prod_{i=n_1}^{n_1+n_2-1}(X-\\omega^i)}$ $\\mathsf{Poly}_\\mathsf{Vanish4}(X)=\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)\\cdot\\frac{X^\\kappa-1}{\\prod_{i=n_2}^{n_1+n_2-1}(X-\\omega^i)}$ The four equations are vanishing for every value of $X\\in\\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa-1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$ and $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q_1(X)=\\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa-1}$ $Q_2(X)=\\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa-1}$ $Q_3(X)=\\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^\\kappa-1}$ $Q_4(X)=\\frac{\\mathsf{Poly}_\\mathsf{Vanish4}(X)}{X^\\kappa-1}$ We can replace polynomials $Q_1(X)$, $Q_2(X)$, $Q_3(X)$, and $Q_4(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all two $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all three are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$$ Q(X)=\\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)+\\rho^2\\cdot\\mathsf{Poly}_\\mathsf{Vanish3}(X)+\\rho^3\\cdot\\mathsf{Poly}_\\mathsf{Vanish4}(X)}{X^\\kappa-1} $$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$$ \\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)+\\rho^2\\cdot\\mathsf{Poly}_\\mathsf{Vanish3}(X)+\\rho^3\\cdot\\mathsf{Poly}_\\mathsf{Vanish4}(X)-Q(X)\\cdot(X^{\\kappa-1}-1)=0 $$ Ultimately the range gadget will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)$, and $\\mathsf{Poly}_{\\mathsf{Arr}_3}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) are too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_{\\mathsf{Arr}_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_{\\mathsf{Arr}_1}(X))$ $K_{\\mathsf{Arr}_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_{\\mathsf{Arr}_2}(X))$ $K_{\\mathsf{Arr}_3}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_{\\mathsf{Arr}_3}(X))$ $K_{\\mathsf{Arr}_2^\\prime}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_{\\mathsf{Arr}_1}(\\zeta)=\\mathsf{KZG.Open}(K_{\\mathsf{Arr}_1},\\zeta)$ $\\mathsf{Poly}_{\\mathsf{Arr}_2}(\\zeta)=\\mathsf{KZG.Open}(K_{\\mathsf{Arr}_2},\\zeta)$ $\\mathsf{Poly}_{\\mathsf{Arr}_3}(\\zeta)=\\mathsf{KZG.Open}(K_{\\mathsf{Arr}_3},\\zeta)$ $\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(\\zeta\\omega^{n_1})=\\mathsf{KZG.Open}(K_{\\mathsf{Arr}_2^\\prime},\\zeta\\omega^{n_1})$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}=\\mathsf{Poly}_{\\mathsf{Arr}_3}(\\zeta)-\\mathsf{Poly}_{\\mathsf{Arr}_1}(\\zeta)-\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(\\zeta)$ $Y_\\mathsf{Vanish2}=\\mathsf{Poly}_{\\mathsf{Arr}_2}(\\zeta)-\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(\\zeta\\omega^{n_1})$ $Y_\\mathsf{Vanish3}=\\mathsf{Poly}_{\\mathsf{Arr}_1}(\\zeta)\\cdot\\frac{\\zeta^\\kappa-1}{\\prod_{i=n_1}^{n_1+n_2-1}(\\zeta-\\omega^i)}$ $Y_\\mathsf{Vanish4}=\\mathsf{Poly}_{\\mathsf{Arr}_2}(\\zeta)\\cdot\\frac{\\zeta^\\kappa-1}{\\prod_{i=n_2}^{n_1+n_2-1}(\\zeta-\\omega^i)}$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1}+\\rho\\cdot{Y_\\mathsf{Vanish2}}+\\rho^2\\cdot{Y_\\mathsf{Vanish3}}+\\rho^3\\cdot{Y_\\mathsf{Vanish4}}-Q(\\zeta)\\cdot(\\zeta^n-1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Security Proof # Completeness # Any honest prover can do the computations explained above and create an accepting proof.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g,g^\\tau,g^{\\tau^2},\\dots,g^{\\tau^{n-1}}]$, $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_3}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X)$, and $Q$ $\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_{\\mathsf{Arr}_1}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_3}(X)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2^\\prime}(X)$, and $Q$ $\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$ $\\mathcal{A}$ wins if $\\mathcal{V}$ accepts at the end of the protocol $\\mathsf{Arr}_3$ is not the concatenation of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ Our proof is as follows:\nWhen $\\mathsf{Arr}_3$ is not the concatenation of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$, there are three cases: some elemnets in $\\mathsf{Arr}_1$ do not appear in $\\mathsf{Arr}_3$, or some elements in $\\mathsf{Arr}_2$ do not appear in $\\mathsf{Arr}_3$, or both of the previous situations. Since $\\mathcal{A}$ has to win the KS game in the first and the second cases if $\\mathcal{A}$ wants to win the game in the last case, it suffices to check any one of the first two situations. Now assume there are some elements in $\\mathsf{Arr}_1$ do not exist in $\\mathsf{Arr}_3$. Because the first $n_1$ elements in $\\mathsf{Arr}_2^\\prime$ are zero, we know that the equation $\\mathsf{Arr}_3[i]=\\mathsf{Arr}_1[i]+\\mathsf{Arr}_2^\\prime[i]$ does not hold for some $i\\in[0,n_1)$. Thus, for $\\mathsf{Poly}_\\mathsf{Vanish1}$, $Q_1$ does not exist (it is a rational function, not a polynomial), which means the probability that $Y_\\mathsf{Zero}$ is a zero polynomial is negligible.\nZero-Knowledge # To prove the above protocol is zero-knowledge, we do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ randomly generates $\\mathsf{Arr}_1^*$ and $\\mathsf{Arr}_2^*$ and computes $\\mathsf{Arr}_3^*$, then follows the same steps a prover would prove the concatenation. $\\mathcal{S}$ computes $\\mathsf{Arr}_2^{\\prime*}$ and interpolates $\\mathsf{Poly}_{\\mathsf{Arr}_1^*}$, $\\mathsf{Poly}_{\\mathsf{Arr}_2^*}$, $\\mathsf{Poly}_{\\mathsf{Arr}_3^*}$, and $\\mathsf{Poly}_{\\mathsf{Arr}_2^{\\prime*}}$. It computes $Q^*(X)$ and finally outputs the commitments to each of these polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta^*$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_{\\mathsf{Arr}_1^*}(\\zeta^*)$, $\\mathsf{Poly}_{\\mathsf{Arr}_2^*}(\\zeta^*)$, $\\mathsf{Poly}_{\\mathsf{Arr}_3^*}(\\zeta^*)$, and $\\mathsf{Poly}_{\\mathsf{Arr}_2^{\\prime*}}(\\zeta^*\\omega^{n_1})$, and $Q^*(\\zeta^*)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":7,"href":"/docs/gadgets/encode/","title":"Encode","section":"Gadgets","content":" Encode # Relation # $ \\mathcal{R}_{\\mathtt{mult3}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr2}, \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}],\\\\ \\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}], \\\\ \\mathsf{Poly}_\\mathsf{Arr_1}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_1}), \\\\ \\mathsf{Poly}_\\mathsf{Arr_2}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_2}), \\\\ K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}),\\\\ K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}), \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds two arrays $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It wishes to map the pairs of elements, $\\{ \\mathsf{Arr_1[i], \\mathsf{Arr_2[i]}}\\}$ into a single element, $\\mathsf{Arr_3}[i]$ without collisions. It will produce a succinct (independent of $n$) proof that $\\mathsf{Arr_3}$ contains the encoding of $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ according to this mapping.\nFor the mapping scheme, we use random linear combinations, since it is both collision resistant and it can be proven in zero knowledge. To do so, the prover defines $f_i(X) = \\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i] \\cdot X$ for $i \\in [0, n-1]$. Then, the the prover calculates $\\mathsf{Arr_3}[i] = f_i(r)$ for a random field element $r$. Assuming $f_i$ is commited to before $r$ is know, this scheme is collision resistant by the Schwartz-Zippel lemma; if two polynomials are equal at $r$ then with overwhelming probability they are the same polynomial. However, to ensure negligible probabilty of collisions, $n$ may need to be smaller relative to the field size than initially thought. This is due to the birthday paradox. We are not evaluating the probability that a single one of the $n$ polynomials collides with one of the other $n-1$ polynomials, but rather the probability than any one polynomial out of $n$ collides with any other of the $n-1$ polynomials. The value of the latter is significantly larger, since it compares every possible pair of the $n$ polynomials, instead of just comparing one of the polynomials with the $n-1$ other polynomials. The probability of collisions can, however, still be made sufficiently small by bounding how large $n$ can be relative to the field size.\nIn order to prove the relation, the prover will encode the three arrays into three polynomials: $\\mathsf{Poly}_\\mathsf{Arr_1}$, $\\mathsf{Poly}_\\mathsf{Arr_2}$, and $\\mathsf{Poly}_\\mathsf{Arr_3}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$). It will commit to each polynomial: $K_\\mathsf{Arr_1}$, $K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$. The verifier ($\\mathcal{V}$) cannot check any of the $\\mathsf{Arr_i}$ or $\\mathsf{Poly}_\\mathsf{Arr_i}$ values directly (they may contain secret information, and even if they do not, they are too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$,$K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$. It will use these commitments to verified the constraint $\\mathsf{Arr_3}[i] = \\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i]\\cdot r$.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2, n-1)}]$ $\\mathcal{P}$ generates the random challenge $r$, then computes $\\mathsf{Arr_3}$ as follows: $\\mathsf{Arr_3}[i] = \\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i]\\cdot r$ Polynomial Level # We assume that $\\mathsf{Arr1}$, $\\mathsf{Arr_2}$, and $\\mathsf{Arr_3}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the arrays, the arrays can be padded with zeros.\nRecall the constraint we want to prove:\n$\\mathsf{Arr_3}[i] = f_i(X) =\\mathsf{Arr_1}[i] + \\mathsf{Arr_2}[i]\\cdot r$ We write the constraint in polynomial form:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_3}(X) = \\mathsf{Poly}_\\mathsf{Arr_1}(X) + \\mathsf{Poly_{Arr_2}}(X)\\cdot r$ We adjust the constraint to show an equality with 0 and label it:\n$\\mathsf{Poly}_\\mathsf{Vanish}(X)= \\mathsf{Poly}_\\mathsf{Arr_3}(X) - (\\mathsf{Poly}_\\mathsf{Arr_1}(X) + \\mathsf{Poly_{Arr_2}}(X)\\cdot r)= 0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(X)}{X^\\kappa - 1}$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the rotate argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly_{Arr_2}}$, and $\\mathsf{Poly}_\\mathsf{Arr_3}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$ $K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$​ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call this point $r$. We note that since $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ were commited to before $r$ was know, $fi$ is commited to before $r$ is known. This is important for the collision resistance of our encoding scheme. Now, using $r$, the prover can compute and commit to the following polynomials:\n$K_\\mathsf{Arr_3}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_3}(X))$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_3},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish}= \\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly_{Arr_2}}(\\zeta)\\cdot r)$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}_3$ that is a random linear combination of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ using $r$, can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly_{Arr_2}}(\\zeta)\\cdot r) - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly_{Arr_2}}(\\zeta)\\cdot r) - \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(\\zeta)}{\\zeta^\\kappa - 1}(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly_{Arr_2}}(\\zeta)\\cdot r) - (\\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly_{Arr_2}}(\\zeta)) \\cdot r)$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\\kappa -1$. This is true if $\\mathsf{Poly_{Vanish}}(\\zeta)$ is vanishing on $\\mathcal{H}_\\kappa$, i.e. if $(\\mathsf{Poly}_\\mathsf{Arr_3}(X) - (\\mathsf{Poly}_\\mathsf{Arr_1}(X) + \\mathsf{Poly_{Arr_2}}(X)) \\cdot r) = 0 \\space \\forall X \\in \\mathcal{H}_\\kappa$. This is true if if $\\mathsf{Arr}_3 - (\\mathsf{Arr}_1 + \\mathsf{Arr}_2 \\cdot r) = 0 \\space \\forall i \\in [0, \\kappa - 1]$, since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$. But this is precisely the condition we assumed held for our prover, so the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and the transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$, the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_3}(X)$ , $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_3}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Arr_3}[i] \\neq \\mathsf{Arr_1}[i] + \\mathsf{Arr_1}[i]\\cdot r$ for some $i \\in [0, n-1]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, there must be some $i \\in [0, n-1]$ such that $\\mathsf{Arr_3}[i] \\neq \\mathsf{Arr_1}[i] + \\mathsf{Arr_1}[i]\\cdot r$. But then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly_{Arr_2}}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_3}(X)$. All commitments $\\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)$, $\\mathsf{Poly_{Arr_2}}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta)$ can each only feasibliy be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}} {(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, $\\mathsf{Poly_{Arr_2}}(\\tau)$, and ${\\mathsf{Poly}_\\mathsf{Arr_3}(\\tau)}$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, and $g^{\\mathsf{Poly}_\\mathsf{Arr_3}(\\tau)}$ to write as the commitments $ K_\\mathsf{Arr_1}$, $ K_\\mathsf{Arr_2}$ and $K_\\mathsf{Arr_3}$. $\\mathcal{S}$ computes $Q(\\tau)$ using the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, and ${\\mathsf{Poly}_\\mathsf{Arr_3}(\\tau)}$. $\\mathcal{S}$ writes the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)}$, and ${\\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta)}$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":8,"href":"/docs/gadgets/folding/","title":"Folding","section":"Gadgets","content":" Folding (Sangria) # The following document is heavily based on the Sangria techincal note and its condensed form.\nIntuition # Given a PLONK circuit, and two private input/public input pairs, we want to reduce the work of checking each of these individually to the work of checking one such relation a single time. This is called folding, and the model we explain here for Plonk, specifically, is called Sangria. Before we get into folding, though, let\u0026rsquo;s review how a PLONK circuit works.\nIn circuit we look at how a circuit with a single gate works, but now we generalize to multi-gate circuits. Here we have vectors $\\mathsf{L}$, $\\mathsf{R}$, $\\mathsf{O}$ $\\in \\mathbb{F}^{s + n +1}$ representing the right and left input, and the output, of each gate, where $n$ is the number of public inputs and $s$ is the number of gates. The $+1$ is an extra row to check the final result, i.e. if the circuit is satisfied. Together, $(\\mathsf{L}, \\mathsf{R}, \\mathsf{O})$ is called the computational trace. These three vectors are divided into $X$, the public inputs, and $W$, the private inputs, or witness. A PLONK proof will show that a public input/private input pair $(X, W)$ satisfies a circuit defined by the tuple $(\\mathsf{Q}, \\mathsf{S})$, where $\\mathsf{Q}$ is the set of selector vectors, and $\\mathsf{S}$ is the set of copy contraints. A circuit being satisfied means that the copy constraints are satisfied, and that each gate is satisfied. The $i^{th}$ gate of the circuit is defined as ${q_L}_i \\cdot l_i + {q_R}_i \\cdot r_i + {q_O}_i \\cdot o_i + {q_M}_i \\cdot l_i \\cdot r_i + {q_c}_i$ where ${q_L}_i, {q_R}_i, {q_O}_i, {q_M}_i, {q_c}_i$ are the $i^{th}$ values of each selector vector, and $l_i, r_i, o_i$ are the $i^{th}$ values of $\\mathsf{L}$, $\\mathsf{R}$, and $\\mathsf{O}$.\nNow, we turn to folding. Say we want to combine the checks for two private input/public input pairs, $(X', W')$ and $(X'', W'')$. We start by trying the most direct appraoch to reducing our two checks down to one: let\u0026rsquo;s take a random linear combination of $(X', W')$ and $(X'', W'')$, and perform the check on it. Then our new private input/public input pair would be $(X, W) := (X' + sX'', W' + sW'')$. We consider this as input to the circuit: $C_{Q,i}(\\mathsf{L}, \\mathsf{R}, \\mathsf{O})$ $= C_{Q,i}(\\mathsf{L}' + s\\mathsf{L}'', \\mathsf{R}' + s\\mathsf{R,}'', \\mathsf{O} + s\\mathsf{O}'')$\n$= {q_L}_i \\cdot (l_{i}' + sl_{i}'' ) + {q_R}_i \\cdot (r_{i}' + sr_{i}'') + {q_O}_i \\cdot (o_{i}' + so_{i}'') + {q_M}_i \\cdot (l_{i}' + s1_{i}'') (r_{i}' + sr_{i}'') + {q_C}_i$\n$= {q_L}_i \\cdot l_{i}' + {q_L}_i \\cdot sl_{i}'' + {q_R}_i \\cdot r_{i}' + {q_R}_i \\cdot sr_{i}'' + {q_O}_i \\cdot o_{i}' + {q_O}_i \\cdot so_{i}'' + {q_M}_i \\cdot (l_{i}'+ s1_{i}'') (r_{i}' + sr_{i}'') + {q_C}_i$\n$\\neq C_{Q,i}(\\mathsf{L}', \\mathsf{R}', \\mathsf{O}')+ C_{Q,i}(\\mathsf{L}'', \\mathsf{R}'', \\mathsf{O}'')$\nWe note the result is no longer of the correct form for a PLONK circuit. We end up with an undesirable crossterms, an $s^2$ in front of at least part of $C_{Q,i}(\\mathsf{L}'', \\mathsf{R}'', \\mathsf{O}'')$, and if we want to claim $C_{Q,i}(\\mathsf{L}, \\mathsf{R}, \\mathsf{O}) = C_{Q,i}(\\mathsf{L}', \\mathsf{R}', \\mathsf{O}')+ C_{Q,i}(\\mathsf{L}'', \\mathsf{R}'', \\mathsf{O}'')$, it simply isn\u0026rsquo;t true. This motivates us to define relaxed PLONK gate equations, which will allow us to deal with these issues. Copy constraints are defined the same in relaxed PLONK, but we defined our gates somewhat differently.\nHere, the $i^{th}$ gate is defined as $u({q_L}_i \\cdot l_i + {q_R}_i \\cdot r_i + {q_O}_i \\cdot o_i) + {q_M}_i \\cdot l_i \\cdot r_i + u^2({q_c}_i) + e_i$ where $u$ is a scalar and $e_i$ is the $i^{th}$ entry in the \u0026ldquo;slack vector\u0026rdquo; $\\mathsf{E}$. We now have $(\\mathsf{L}, \\mathsf{R}, \\mathsf{O}, u, \\mathsf{E})$ as the computational trace. We must also define our public input/private input pair differently, namely for the regular PLONK pair $(X, W)$ we define the relaxed PLONK pair $(U, V)$ as:\n$U := (X, u, \\overline W_l, \\overline W_r, \\overline W_o, \\overline E)$\n$V:= (W, \\mathsf{E}, r_l, r_r, r_o, r_e)$\nWhere $\\overline W_l = \\mathsf{com}(w_l, r_l)$, $\\overline W_r = \\mathsf{com}(w_r, r_r)$, $\\overline W_o = \\mathsf{com}(w_o, r_o)$, $\\overline E = \\mathsf{com}(\\mathsf{E}, r_e)$. For each of these commitments (and elsewhere in this document) the public parameters are including implicitly for cleaner notation.\nWe define the relaxed PLONK gate equation as:\n$C'_{Q,i}= (u) \\cdot [{q_L}_i \\cdot l + {q_R}_i \\cdot r + {q_O}_i \\cdot o] + {q_M}_i \\cdot l r + u^2{q_C}_i + e_i$\nNote that regular PLONK relation can be represented as a relaxed PLONK relation simply by setting $u=1$ and $\\mathsf{E}=\\vec{0}$.\nProtocol Details # Now, we once again try the random linear combination approach, this time with relaxed PLONK gate equations. The verifier is given the verifier key, and the two sets of public inputs $(X', u', \\overline W_l', \\overline W_r', \\overline W_o', \\overline E')$ and $(X'', u'', \\overline W_l'', \\overline W_r'', \\overline W_o'', \\overline E'')$. The prover has the prover key and both sets of corresponding private inputs: $(W', \\mathsf{E}', r_l', r_r', r_o', r_e')$ and $(W'', \\mathsf{E}'', r_l'', r_r'', r_o'', r_e'')$. The protocol (which is a public-coin folding scheme) proceeds as follows:\n$\\mathcal{P}$ computes $\\mathsf{T}= u''(q_L \\circ l' + q_R \\circ r' + q_O \\circ o') + u'(q_L \\circ l'' + q_R \\circ r'' + q_O \\circ o'') + q_M \\circ (l' \\circ r'' + l'' \\circ r') + 2u'u''q_C$ where $\\circ$ denotes element-wise multiplication. This $t$ is used to account for the crossterms. $\\mathcal{P}$ samples a random $r_T$ sends $\\overline T = \\mathsf{com}(\\mathsf{T}, r_T)$. $\\mathcal{V}$ samples a random challenge $r$ and sends it. $\\mathcal{P}$ and $\\mathcal{V}$ output the folded public input $(X, u, \\overline W_l, \\overline W_r, \\overline W_o, \\overline E)$, computed as: $\\quad X = X' + sX''$\n$\\quad u = u' + su''$\n$\\quad \\overline W_l = \\overline W_l' +s\\overline W_l''$\n$\\quad \\overline W_r = \\overline W_r' +s\\overline W_r''$\n$\\quad \\overline W_o = \\overline W_o' +s\\overline W_o''$\n$\\quad \\overline E = \\overline E' -s\\overline T + s^2 \\overline E''$\n$\\mathcal{P}$ outputs the folded private input $(W, \\mathsf{E}, r_l, r_r, r_o, r_e)$, computed as: $\\quad W = W' + sW''$\n$\\quad r_l = r_l' +sr_l''$\n$\\quad r_r = r_r' +sr_r''$\n$\\quad r_o = r_o' +sr_o''$\n$\\quad \\mathsf{E} = \\mathsf{E}' - s\\mathsf{T} + s^2 \\mathsf{E}''$\n$\\quad r_e = r_e' - sr_T + s^2r_e''$\nThe resulting public and private inputs constitute a new PLONK pair $(U, V)$ which is the folding of the two input pairs. The protocol can be made non-interactive via Fiat-Shamir.\nSecurity Proof # Completeness # To show completeness, we observe that $C'_{Q,i}(\\mathsf{L}, \\mathsf{R}, \\mathsf{O}, u, \\mathsf{E})$\n$= C'_{Q,i}(\\mathsf{L}' + s\\mathsf{L}'', \\mathsf{R}' + s\\mathsf{R}'', \\mathsf{O}' + s\\mathsf{O}'', u' + u'', \\mathsf{E}' -s\\mathsf{T} + s^2\\mathsf{E}'')$\n$= (u' + su'') \\cdot [{q_L}_i \\cdot (l_i' + sl_i'') + {q_R}_i \\cdot (r_i' + sr_i'') + {q_O}_i \\cdot (o_i' +so_i'')] + {q_M}_i \\cdot (l_i' + sl_i'') (r_i' + sr_i'') + (u' + su'')^2{q_C}_i + e'_i -st_i + s^2 e''_i$\n$= u'(q_{L_i} \\cdot l_i' + q_{R_i} \\cdot r_i' + q_{O_i} \\cdot o_i' + q_{M_i} \\cdot l_i' \\cdot r_i' + u' \\cdot q_{C_i}) + e'_i + u'' \\cdot s^2(q_{L_i} \\cdot l_i'' + q_{R_i} \\cdot r_i'' + q_{O_i} \\cdot o_i'' + q_{M_i} \\cdot l_i'' \\cdot r_i'' + u'' \\cdot q_{C_i}) + s^2 e''_i \\newline + u''(q_{L_i} \\cdot l_i' + q_{R_i} \\cdot r_i' + q_{O_i} \\cdot oi') + u'(q_{L_i} \\cdot li'' + q_{R_i} \\cdot r_i'' + q_{O_i} \\cdot o_i'') + q_{M_i} \\cdot (l_i' \\cdot r_i'' + l_i'' \\cdot r_i') + 2u'u''q_{C_i} - st_i$\n$= u'(q_{L_i} \\cdot l_i' + q_{R_i} \\cdot r_i' + q_{O_i} \\cdot o_i' + q_{M_i} \\cdot l_i' \\cdot r_i' + u' \\cdot q_{C_i}) + e'_i + u'' \\cdot s^2(q_{L_i} \\cdot l_i'' + q_{R_i} \\cdot r_i'' + q_{O_i} \\cdot o_i'' + q_{M_i} \\cdot l_i'' \\cdot r_i'' + u'' \\cdot q_{C_i}) + s^2 e''_i$\n$ = C'_{Q,i}(\\mathsf{L}', \\mathsf{R}', \\mathsf{O}', u, \\mathsf{E}') + s^2 \\cdot C'_{Q,i}(\\mathsf{L}'', \\mathsf{R}'', \\mathsf{O}'', u, \\mathsf{E}'')$\nSo following the steps of the protocol above provides a folding that satisfies completeness.\nSoundness # The proof for soundness is rather involved, so we provide the intuition for it here, and the technical note for Sangria provides the proof in full. We rely on the fact that a binding commitment is used.\nFirst, we apply the forking lemma for folding (Nova paper lemma 1), to obtain three transcripts. We then show that, using all three transcripts, the extractor can interpolate the values of $\\mathsf{E}', r_e', \\mathsf{E}'', r_e''$. It can also interpolate $(W', r_l', r_r', r_o')$ and $(W'', r_l'', r_r'', r_o'')$ using any two of the transcripts. Finally, we show that the traces these values belong to satisfy the copy constraints and the equality for each gate.\nZero-Knowledge # The proof relies on the fact that the commitment used is hiding, then the only message sent by the prover is a hiding commitment, which means the proof is relatively short and straight forward. We define a simulator, $\\mathcal{S}$, which samples a random vector $\\mathsf{T}$ from $\\mathbb{F}^{n + s +1}$ and a random scalar $r_T$ from $\\mathbb{F}$. From these, it produces the commitment $\\overline T = \\mathsf{com}(\\mathsf{T}, r_T)$. It then generates a random challenge $r$, and uses this $r$ and $\\overline T$ to output the transcript. Since the commitment is hiding, this is computationally indistinguishable from a real transcript.\n"},{"id":9,"href":"/docs/gadgets/lookup1/","title":"Lookup1","section":"Gadgets","content":" Lookup (Type 1) # Recap of types # Type Description Recap This lookup1 $\\mathsf{Arr}[i]\\in \\{0,1\\}$ Each element of array $\\mathsf{Arr}$ is in $\\{0,1\\}$ (or another small set). ✅ lookup2 $\\mathsf{Arr}[i]\\in \\mathsf{Table}$ Each element of array $\\mathsf{Arr}$ is in a disclosed table of values $\\mathsf{Table}$. Relation # $ \\mathcal{R}_{\\mathtt{lookup1}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}], \\\\ \\mathsf{Poly}_\\mathsf{Arr}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}), \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds an array $\\mathsf{Arr}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that each element in $\\mathsf{Arr}$ is in $\\{0,1\\}$ (or another small set). The prover will encode $\\mathsf{Arr}$ into the polynomial $\\mathsf{Poly}_\\mathsf{Arr}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$). It will commit to the polynomial: $K_\\mathsf{Arr}$. The verifier ($\\mathcal{V}$) cannot check any of the $\\mathsf{Arr}$ values directly (they may contain secret information, and even if they do not, they are too long to check) so the verifier only sees $K_\\mathsf{Arr}$.\nIn order to check that each element of $\\mathsf{Arr}$ is either 0 or 1, consider the expression $\\mathsf{Arr}[i] \\cdot (\\mathsf{Arr}[i] - 1)$. If $\\mathsf{Arr}[i]$ is 0, then the first part of the product is zero, and if $\\mathsf{Arr}[i]$ is 1, then the second part of the product is zero. If $\\mathsf{Arr}[i]$ is not 0 or 1, then the expression will be non-zero. Thus, to check our condition, it suffices to check that $\\mathsf{Arr}[i] \\cdot (\\mathsf{Arr}[i] - 1) = 0$ for $i$ from 0 to $n-1$.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers ($a_i \\in \\mathbb{Z}_q$) Polynomial Level # We assume that $\\mathsf{Arr}$ is encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 0 or 1.\nRecall the constraint we want to prove:\n$\\mathsf{Arr}[i] \\cdot (\\mathsf{Arr}[i] - 1) = 0$ for $i$ from 0 to $n-1$ We write our constraint in polynomial form and label it:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Vanish}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(X) - 1) =0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(X)}{X^\\kappa - 1}$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$ Ultimately the lookup1 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X))$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish}=\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) - 1)$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}$ such that $\\mathsf{Arr}[i] \\in \\{0, 1\\} \\forall 0 \\leq i \\leq n$, can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$ = \\mathsf{Poly}_\\mathsf{Arr}(\\zeta) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) - 1) - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$ = \\mathsf{Poly}_\\mathsf{Arr}(\\zeta) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) - 1) - \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(\\zeta)}{\\zeta^\\kappa - 1}\\cdot (\\zeta^\\kappa - 1)$\n$ = \\mathsf{Poly}_\\mathsf{Arr}(\\zeta) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) - 1) - [\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(\\zeta) - 1)]$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\\kappa -1$. This is true if $\\mathsf{Poly_{Vanish}}(\\zeta)$ is vanishing on $\\mathcal{H}_\\kappa$, i.e. if $\\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot (\\mathsf{Poly}_\\mathsf{Arr}(X) - 1) = 0 \\space \\forall X \\in \\mathcal{H}_\\kappa$. This is true if $\\mathsf{Arr}[i] \\cdot (\\mathsf{Arr}[i] - 1) = 0 \\space \\forall i \\in [0, \\kappa -1]$, since $\\mathsf{Poly}(\\omega^i) = \\mathsf{Arr}[i] \\space \\forall i \\in [0, \\kappa - 1]$. But this is precisely the condition we assumed held for the prover (since the array gets padded with $1$\u0026rsquo;s or $0$\u0026rsquo;s if $n \\lt \\kappa$), so the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and the transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $Q(X)$.\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Arr}[i]\\neq 0$ and $\\mathsf{Arr}[i]\\neq 1$ for some $i \\in [0, n-1]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, there must be at least one entry is $\\mathsf{Arr}$ that is not 0 or 1. But then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes a commitment to $\\mathsf{Poly}_\\mathsf{Arr}(X)$. Both commitments $\\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)$, can only feasibliy be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1}}{(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses an arbitrary value for ${\\mathsf{Poly}_\\mathsf{Arr}(\\tau)}$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr}(\\tau)}$ to write as the commitment $ K_\\mathsf{Arr}$. $\\mathcal{S}$ then generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the value it chose for ${\\mathsf{Poly}_\\mathsf{Arr}(\\tau)}$. $\\mathcal{S}$ writes the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the second random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)}$, to an arbitrary value. This is done using the knowledge of $\\tau$, calculating the witness polynomial $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":10,"href":"/docs/gadgets/lookup2/","title":"Lookup2","section":"Gadgets","content":" Lookup (Type 2) # Recap of types # Type Description Recap This lookup1 $\\mathsf{Arr}[i]\\in \\{0,1\\}$ Each element of array $\\mathsf{Arr}$ is in $\\{0,1\\}$ (or another small set). lookup2 $\\mathsf{Arr}[i]\\in \\mathsf{Table}$ Each element of array $\\mathsf{Arr}$ is in a disclosed table of values $\\mathsf{Table}$. ✅ Relation # $ \\mathcal{R}_{\\mathtt{lookup2}} := \\left\\{ \\begin{array}{l} (\\mathsf{Arr},\\mathsf{T}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr}[i]\\in\\mathsf{T}, 0\\leq i \\leq n-1, \\\\ \\mathsf{Poly}_\\mathsf{Arr}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}), \\\\ \\mathsf{Poly}_\\mathsf{T}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{T}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}), \\\\ K_\\mathsf{T}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T}), \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds an array $\\mathsf{Arr}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that each value in $\\mathsf{Arr}$ is the element of a public table $\\mathsf{T}$. The prover will encode $\\mathsf{Arr}$ and $\\mathsf{T}$ into polynomials: $\\mathsf{Poly}_\\mathsf{Arr}$ and $\\mathsf{Poly}_\\mathsf{T}$. Assume $\\mathsf{Arr}$ is equal to $\\mathsf{T}$, then the prover can complete the proof by simply performing the product check or the permutation check between $\\mathsf{Arr}$ and $\\mathsf{T}$. However, if $\\mathsf{Arr}$ is not equal to $\\mathsf{T}$ (this is the case we want to solve), the prover needs to reveal the points where $\\mathsf{Arr}$ equals to $\\mathsf{T}$, which makes zero knowledge impossible. Thus, the prover needs to construct auxiliary polynomial(s) to prove the constraints between $\\mathsf{Arr}$ and $\\mathsf{T}$ are desired.\nThere are different approaches to achieving the lookup argument, e.g., halo2 and Plookup. We will discuss these two approaches as follows.\nhalo2 # The lookup argument in halo2 requires the prover to construct two auxiliary vectors, $\\mathsf{Arr}^\\prime$ and $\\mathsf{T}^\\prime$, where $\\mathsf{Arr}^\\prime$ is the permutation of $\\mathsf{Arr}$ and sorted (ascending or descending does not matter), $\\mathsf{T}^\\prime$ is the permutation of $\\mathsf{T}$ and sorted by $\\mathsf{Arr}$. For any two sets $A,B$ such that $A\\subset{B}$, we say $B$ is sorted by $A$ when the elements in $A$ have the same order as they do in $B$. Let us demonstrate the halo2 lookup argument with a concrete example, $\\mathsf{Arr}=\\{1,2,1,6,4,5,3,0\\},\\mathsf{T}=\\mathbb{Z}_8$. The prover constructs $\\mathsf{Arr}^\\prime$ and $\\mathsf{T}^\\prime$ such that $$ \\mathsf{Arr}^\\prime=\\{0,1,1,2,3,4,5,6\\} $$ $$ \\mathsf{T}^\\prime=\\{0,1,7,2,3,4,5,6\\} $$ We can observe that $\\mathsf{Arr}^\\prime[i]$ is equal to $\\mathsf{T}^\\prime[i]$ or $\\mathsf{Arr}^\\prime[i-1]$. Since $\\mathsf{Arr}^\\prime[i-1]$ does not exist when $i=0$, we have to enforce the other rule, $\\mathsf{Arr}^\\prime[0]=\\mathsf{T}^\\prime[0]$. With these two constraints and the proof that $\\mathsf{Arr}^\\prime$ is the permutation of $\\mathsf{Arr}$ and $\\mathsf{T}^\\prime$ is the permutation of $\\mathsf{T}$, the prover can prove each element in $\\mathsf{Arr}$ exists in $\\mathsf{T}$.\nPlookup # We start with an unoptimized version of Plookup that is conceptually simpler than the final version and is still fully succinct. The inputs are: an array containing the values of the lookup table $\\mathsf{T}$ of size $n_1$; and an array of length $n_2$ (typically longer than $n_1$ but not necessarily) that will be proven to contain only values from somewhere in $\\mathsf{T}$.\nThe prover will create 5 helper arrays ($\\mathsf{Acc_1}$ to $\\mathsf{Acc_5}$) to demonstrate this overall property ($\\mathsf{Arr}[i]\\in\\mathsf{T}$ for all $i$). The helper arrays will each be of size $n_1+n_2$ with the exception of $\\mathsf{Acc_4}$ which is $n_2$. They are as follows:\n$\\mathsf{Acc_1}=\\mathsf{Arr}||\\mathsf{T}$ $\\mathsf{Acc_2}=\\mathtt{Sort}(\\mathsf{Acc_1})$ $\\mathsf{Acc_3}[i]=\\mathsf{Acc_2}[i+1]-\\mathsf{Acc_2}[i]$ $\\mathsf{Acc_4}[i]=\\mathsf{T}[i+1]-\\mathsf{T}[i]$ $\\mathsf{Acc_5}=\\mathsf{Acc_4}||\\{0\\}^{n_2}$ where $n_1=|\\mathsf{Arr}|$ It is probably worth an example at this point.\n$\\mathsf{T}=[7,0,15,3]$ $\\mathsf{Arr}=[7,0,15,15,7,7,15,0,0,7,15,7]$ $\\mathsf{Acc_1}=[7,0,15,15,7,7,15,0,0,7,15,7,7,0,15,3]$ $\\mathsf{Acc_2}=[7,7,7,7,7,7,0,0,0,0,15,15,15,15,15,3]$ $\\mathsf{Acc_3}=[0,0,0,0,0,-7,0,0,0,15,0,0,0,0,-12,\\bot]$ $\\mathsf{Acc_4}=[-7,15,-12,\\bot]$ $\\mathsf{Acc_5}=[-7,15,-12,\\bot,0,0,0,0,0,0,0,0,0,0,0,0]$ The first array $\\mathsf{Acc_1}$ is the concatination for $\\mathsf{Arr}$ and $\\mathsf{T}$. The intuition for this is as follows. Every element of $\\mathsf{Arr}$ is in $\\mathsf{T}$ (what is being proven) but the converse is not true, not every element of $\\mathsf{T}$ is necessarily in $\\mathsf{Arr}$. By constructing $\\mathsf{Acc_1}$, the prover has an array where every element of $\\mathsf{T}$ appears at least once. This will be convenient later. Additionally, if the prover can show every element in $\\mathsf{Acc_1}$ is in $\\mathsf{T}$, it implies every element in the original $\\mathsf{Arr}$ is in $\\mathsf{T}$ so it can now move forward with $\\mathsf{Acc_1}$.\nHow does $\\mathsf{Acc_1}$ compare to $\\mathsf{T}$? They both have the same elements but $\\mathsf{Acc_1}$ has a bunch of extra duplicates of values. Also the appearance of elements in $\\mathsf{Acc_1}$ are in a different (arbitrary) order. Next the prover will sort the values of $\\mathsf{Acc_1}$, grouping all duplicates together, and having them appear in the same order as the original $\\mathsf{T}$ (which does not have to be sorted).\nNow how does $\\mathsf{Acc_2}$ compare to $\\mathsf{T}$? They have the same elements in the same order (including 3 which is not in the original $\\mathsf{Arr}$) however $\\mathsf{Acc_2}$ has a bunch of duplicates of some of the elements. Next we want to \u0026ldquo;flag\u0026rdquo; all the elements that are duplicates. The way we do this is to take the difference between each neighbouring elements. If the neighbouring elements are the same (duplicates), this is will place a 0 in that position. If they are not, a non-zero number will appear instead.\nThis is straight-forward until we hit the last element in $\\mathsf{Acc_2}$ and $\\mathsf{Acc_3}$ which has no \u0026ldquo;next\u0026rdquo; element in the array. We will leave it for now as an arbitrary integer $\\bot$.\nWe have marked the duplicates elements but have some other integers when neighbouring elements are not the same. The idea is do the same thing with $\\mathsf{T}$ and we create $\\mathsf{Acc_4}$, which we then pad with $n_2$ zeros.\n$\\mathsf{Acc_5}=[-7,15,-12,\\bot,0,0,0,0,0,0,0,0,0,0,0,0]$ If $\\mathsf{Acc_5}$ is a permutation of $\\mathsf{Acc_3}$ and everything else is correctly constructed, then all elements in $\\mathsf{Arr}$ are from $\\mathsf{T}$.\nThe prover will show that $\\mathsf{Acc_1}$ is constructed correctly with the $\\mathtt{concat}$ gadget. It will not prove that $\\mathsf{Acc_2}$ is sorted correctly (if it does not sort it correctly, the protocol will not work) but it will prove that $\\mathsf{Acc_2}$ is a permutation of $\\mathsf{Acc_1}$ using $\\mathtt{shuffle1}(\\mathsf{Acc_1},\\mathsf{Acc_2})$. It will prove $\\mathsf{Acc_3}$ is constructed correctly by $\\mathsf{add1}(\\mathsf{Acc_2}[i+1],-\\mathsf{Acc_2}[i])$ and $\\mathsf{Acc_3}$ is $\\mathsf{add1}(\\mathsf{T}[i+1],-\\mathsf{T}[i])$. Last, it will prove that $\\mathsf{Acc_5}$ is correctly formed with $\\mathtt{concat}$ and finally, that it is a permutation of $\\mathsf{Acc_3}$ with $\\mathtt{shuffle1}(\\mathsf{Acc_5},\\mathsf{Acc_3})$.\n$\\mathsf{T}$ to the end of $\\mathsf{Arr}$ does not change anything about the arguement\nIn fact, the only difference betweeen $\\mathsf{Acc_1}$ and $\\mathsf{T}$ itself is that there are serveral duplicates\nWith these arrays, the following constraints are demonstrated:\nUses $\\mathtt{concat}$ gadget Uses $\\mathtt{shuffle1}(\\mathsf{Acc_1},\\mathsf{Acc_2})$ Uses $\\mathsf{add1}(\\mathsf{Acc_2}[i+1],-\\mathsf{Acc_2}[i])$ Uses $\\mathsf{add1}(\\mathsf{T}[i+1],-\\mathsf{T}[i])$ Uses $\\mathtt{concat}$ and then $\\mathtt{shuffle1}(\\mathsf{Acc_5},\\mathsf{Acc_3})$ Unlike halo2, Plookup requires only one auxiliary vector, $\\mathsf{S}$, where $\\mathsf{S}$ is the union set of $\\mathsf{Arr}$ and $\\mathsf{T}$, and sorted by $\\mathsf{T}$. The prover encodes $\\mathsf{Arr}$, $\\mathsf{T}$, and $\\mathsf{S}$ into polynomials: $\\mathsf{Poly}_\\mathsf{Arr}$, $\\mathsf{Poly}_\\mathsf{T}$, and $\\mathsf{Poly}_\\mathsf{S}$, and computes $\\prod{\\mathsf{Poly}_\\mathsf{Arr}\\cdot\\prod\\mathsf{Poly}_\\mathsf{T}}$ and $\\prod{\\mathsf{Poly}_\\mathsf{S}}$ with some random challenges. The theorem tells us the two products are equal if and only if: $\\mathsf{Arr}\\subset\\mathsf{T}$, and $\\mathsf{S}=(\\mathsf{Arr},\\mathsf{T})$ and sorted by $\\mathsf{T}$.\nProtocol Details # halo2 # Array Level # $\\mathcal{P}$ and $\\mathcal{V}$ are given a public table $\\mathsf{T}$ $\\mathcal{P}$ holds an array $\\mathsf{Arr}=[a_0,a_1,a_2,\\dots,a_{n-1}]$ of $n$ integers ($a_i\\in\\mathbb{Z}_q$) $\\mathcal{P}$ computes an array $\\mathsf{Arr}^\\prime=[a_0^\\prime,a_1^\\prime,a_2^\\prime,\\dots,a_{n-1}^\\prime]$ of $n$ integers ($a_i^\\prime\\in\\mathbb{Z}_q$) such that: $\\mathsf{Arr}^\\prime$ is a permutation of $\\mathsf{Arr}$ and sorted in ascending or descending $\\mathcal{P}$ computes an array $\\mathsf{T}^\\prime$ such that: $\\mathsf{T}^\\prime$ is a permutation of $\\mathsf{T}$ and sorted by $\\mathsf{Arr}^\\prime$ $\\mathsf{Arr}^\\prime$ and $\\mathsf{T}^\\prime$ have the following relations: $\\mathsf{Arr}^\\prime[0]=\\mathsf{T}^\\prime[0]$ $\\mathsf{Arr}^\\prime[i]=\\mathsf{T}^\\prime[i]\\mid\\mathsf{Arr}^\\prime[i-1],i\\ne{0}$ Polynomial Level # We assume arrays $\\mathsf{Arr}$, $\\mathsf{Arr}^\\prime$, $\\mathsf{T}$, and $\\mathsf{T}^\\prime$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product).\nRecall the four constraints we want to prove:\n$\\mathsf{Arr}^\\prime$ is a permutation of $\\mathsf{Arr}$ $\\mathsf{T}^\\prime$ is a permutation of $\\mathsf{T}$ The first value in $\\mathsf{Arr}^\\prime$ equals to the first value in $\\mathsf{T}^\\prime$ The rest of the values in $\\mathsf{Arr}^\\prime$ are of the form $\\mathsf{Arr}^\\prime[i]=\\mathsf{T}^\\prime[i]\\mid\\mathsf{Arr}^\\prime[i-1],i\\ne{0}$ In polynomial form, the constraints are ($\\alpha,\\beta$ are challenges from $\\mathcal{V}$):\n$\\prod[\\alpha-\\mathsf{Poly}_{\\mathsf{Arr}}(X)]=\\prod[\\alpha-\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)]$ $\\prod[\\beta-\\mathsf{Poly}_{\\mathsf{T}}(X)]=\\prod[\\beta-\\mathsf{Poly}_{\\mathsf{T}^\\prime}(X)]$ For $X=\\omega^0$: $\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)=\\mathsf{Poly}_{\\mathsf{T}^\\prime}(X)$ For all $X\\in\\mathcal{H}_\\kappa\\setminus{\\omega^0}$: $[\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)-\\mathsf{Poly}_{\\mathsf{T}^\\prime}(X)]\\cdot[\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)-\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X\\cdot\\omega^{-1})]=0$ We take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=\\prod[\\alpha-\\mathsf{Poly}_{\\mathsf{Arr}}(X)]-\\prod[\\alpha-\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)]=0$ $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=\\prod[\\beta-\\mathsf{Poly}_{\\mathsf{T}}(X)]-\\prod[\\beta-\\mathsf{Poly}_{\\mathsf{T}^\\prime}(X)]=0$ $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=[\\mathsf{Poly}_{\\mathsf{Arr^\\prime}}(X)-\\mathsf{Poly}_{\\mathsf{T^\\prime}}(X)]\\cdot\\frac{X^\\kappa-1}{X-\\omega^0}=0$ $\\mathsf{Poly}_\\mathsf{Vanish4}(X)=[\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)-\\mathsf{Poly}_{\\mathsf{T}^\\prime}(X)]\\cdot[\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X)-\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(X\\cdot\\omega^{-1})]\\cdot(X-\\omega^0)=0$ Instead of proving $\\mathsf{Poly}_\\mathsf{Vanish1}$ and $\\mathsf{Poly}_\\mathsf{Vanish2}$ are vanishing through two permutation checks, we can construct an accumulator $\\mathsf{Poly}_\\mathsf{Z}$ to make it more efficient (the domain needs to be expanded to $2\\kappa$, denoted by $k$):\n$\\mathsf{Poly}_\\mathsf{Z}(\\omega^0)=\\mathsf{Poly}_\\mathsf{Z}(\\omega^{k-1})=1$ For all $X\\in\\mathcal{H}_\\kappa\\setminus{\\omega^{k-1}}$: $\\mathsf{Poly}_\\mathsf{Z}(X\\cdot\\omega)=\\mathsf{Poly}_\\mathsf{Z}(X)\\cdot\\frac{[\\mathsf{Poly}_\\mathsf{Arr}(X)+\\alpha]\\cdot[\\mathsf{Poly}_\\mathsf{T}(X)+\\beta]}{[\\mathsf{Poly}_\\mathsf{Arr^\\prime}(X)+\\alpha]\\cdot[\\mathsf{Poly}_\\mathsf{T^\\prime}(X)+\\beta]}$ Now we have the new $\\mathsf{Poly}_\\mathsf{Vanish1}$ and $\\mathsf{Poly}_\\mathsf{Vanish2}$:\n$\\mathsf{Poly}_\\mathsf{Vanish1}=[\\mathsf{Poly}_\\mathsf{Z}(X)-1]\\cdot\\frac{X^k-1}{(X-\\omega^0)\\cdot(X-\\omega^{k-1})}=0$ $\\mathsf{Poly}_\\mathsf{Vanish2}=\\{\\mathsf{Poly}_\\mathsf{Z}(X\\cdot\\omega)\\cdot[\\mathsf{Poly}_\\mathsf{Arr^\\prime}(X)+\\alpha]\\cdot[\\mathsf{Poly}_\\mathsf{T^\\prime}(X)+\\beta]-\\mathsf{Poly}_\\mathsf{Z}(X)\\cdot[\\mathsf{Poly}_\\mathsf{Arr}(X)+\\alpha]\\cdot[\\mathsf{Poly}_\\mathsf{T}(X)+\\beta]\\}\\cdot(X-\\omega^{k-1})=0$ These equations are true for every value of $X \\in \\mathcal{H}_k$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^k - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_k$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish3}(X)$, and $\\mathsf{Poly}_\\mathsf{Vanish4}(X)$ must be vanishing on $\\mathcal{H}_k$ too. Specifically, the prover computes,\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^k - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^k - 1}$ $Q_3(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^k - 1}$ $Q_4(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish4}(X)}{X^k - 1}$ Instead of proving the four polynomials are zero polynomials one by one, we can linearly combine the four polynomials with a random challenge $\\rho$ sent by $\\mathcal{V}$ to compute:\n$W(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}+\\rho^2\\cdot{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}+\\rho^3\\cdot{\\mathsf{Poly}_\\mathsf{Vanish4}(X)}=0$ When $\\mathsf{Poly}_\\mathsf{Vanish1}(X),\\mathsf{Poly}_\\mathsf{Vanish2}(X),\\mathsf{Poly}_\\mathsf{Vanish3}(X),\\mathsf{Poly}_\\mathsf{Vanish4}(X)$ are vanishing on the domain $\\mathcal{H}_k$, $W(X)$ is also vanishing with high probability. Again, if and only if $W(X)$ is vanishing over the field $\\mathcal{H}_k$, $Q(X)=W(X)/(X^k-1)$ exists.\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it): $$ \\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)+\\rho^2\\cdot\\mathsf{Poly}_\\mathsf{Vanish3}(X)+\\rho^3\\cdot\\mathsf{Poly}_\\mathsf{Vanish4}(X)-Q(X)\\cdot(X^n-1)=0 $$ Ultimately the halo2 lookup argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Z}(X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_\\mathsf{Arr^\\prime}(X)$, and $\\mathsf{Poly}_\\mathsf{T^\\prime}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is a zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) are too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Z}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Z}(X))$ $K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X))$ $K_\\mathsf{T}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T}(X))$ $K_\\mathsf{Arr^\\prime}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr^\\prime}(X))$ $K_\\mathsf{T^\\prime}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T^\\prime}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_k$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_k$. Call this point $\\zeta$. The prover will write the three points and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Z}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Z},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Z}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Z},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr^\\prime}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr^\\prime},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr^\\prime}(\\zeta\\omega^{-1})=\\mathsf{KZG.Open}(K_\\mathsf{Arr^\\prime},\\zeta\\omega^{-1})$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta)$ $\\mathsf{Poly}_\\mathsf{T^\\prime}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{T^\\prime},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}=[\\mathsf{Poly}_\\mathsf{Z}(\\zeta)-1]\\cdot\\frac{(\\zeta^k-1)}{(\\zeta-\\omega^0)\\cdot(\\zeta-\\omega^{k-1})}$ $Y_\\mathsf{Vanish2}=\\{\\mathsf{Poly}_\\mathsf{Z}(\\zeta\\omega)\\cdot[\\mathsf{Poly}_\\mathsf{Arr^\\prime}(\\zeta)+\\alpha]\\cdot[\\mathsf{Poly}_\\mathsf{T^\\prime}(\\zeta)+\\beta]-\\mathsf{Poly}_\\mathsf{Z}(\\zeta)\\cdot[\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\alpha]\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\beta]\\}\\cdot(\\zeta-\\omega^{k-1})$ $Y_\\mathsf{Vanish3}=[\\mathsf{Poly}_{\\mathsf{Arr^\\prime}}(\\zeta)-\\mathsf{Poly}_{\\mathsf{T^\\prime}}(\\zeta)]\\cdot\\frac{\\zeta^k-1}{\\zeta-\\omega^0}$ $Y_\\mathsf{Vanish4}=[\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(\\zeta)-\\mathsf{Poly}_{\\mathsf{T}^\\prime}(\\zeta)]\\cdot[\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(\\zeta)-\\mathsf{Poly}_{\\mathsf{Arr}^\\prime}(\\zeta\\omega^{-1})]\\cdot(\\zeta-\\omega^0)$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1}+\\rho\\cdot{Y_\\mathsf{Vanish2}}+\\rho^2\\cdot{Y_\\mathsf{Vanish3}}+\\rho^3\\cdot{Y_\\mathsf{Vanish4}}-Q(\\zeta)\\cdot(\\zeta^k - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Plookup # Array Level # $\\mathcal{P}$ and $\\mathcal{V}$ are given a public table $\\mathsf{T}=[t_0,t_1,t_2,\\dots,t_{d-1}]$ of $d$ integers ($t_i\\in\\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr}=[a_0,a_1,a_2,\\dots,a_{n-1}]$ of $n$ integers ($a_i\\in\\mathbb{Z}_q$) $\\mathcal{P}$ constructs an array $\\mathsf{S}=(\\mathsf{Arr},\\mathsf{T})=[s_0,s_1,s_2,\\dots,s_{n+d-1}]$ of $n+d$ integers ($s_i\\in\\mathbb{Z}_q$) such that: $\\mathsf{S}$ is a union set of $\\mathsf{Arr}$ and $\\mathsf{T}$ $\\mathsf{S}$ is sorted by $\\mathsf{T}$ $\\mathsf{Arr}$, $\\mathsf{T}$, and $\\mathsf{S}$ have the following relations: For each $i\\in[0,d-1)$, there exists a $j\\in[0,n+d-1)$ such that $(t_i,t_{i+1})=(s_j,s_{j+1})$ Let $I$ be the set of those $d-1$ indices, and let $I^\\prime:=[0,n+d-1)\\setminus{I}$. For each $i\\in{I^\\prime}$, there exists a $j\\in[0,n)$ such that $s_i=s_{i+1}=a_{j}$ Polynomial Level # We assume arrays $\\mathsf{Arr}$, $\\mathsf{T}$, and $\\mathsf{S}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product).\nRecall the two constraints we want to prove:\nFor each $i\\in[0,d-1)$, there exists a $j\\in[0,n+d-1)$ such that $(t_i,t_{i+1})=(s_j,s_{j+1})$ Let $I$ be the set of those $d-1$ indices, and let $I^\\prime:=[0,n+d-1)\\setminus{I}$. For each $i\\in{I^\\prime}$, there exists a $j\\in[0,n)$ such that $s_i=s_{i+1}=a_{j}$ In polynomial form, the constraints are ($\\alpha,\\beta$ are challenges from $\\mathcal{V}$):\n$(1+\\beta)^n\\prod_{i\u003c{n}}[\\alpha+\\mathsf{Poly}_{\\mathsf{Arr}}(\\omega^i)]\\cdot\\prod_{i\u003c{d-1}}[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(\\omega^{i+1})]=\\prod_{i\u003c{n+d-1}}[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{S}}(\\omega^{i+1})]$ To efficiently prove the above polynomial holds, we can use a similar trick in halo2 lookup by constructing an accumulator :\n$\\mathsf{Poly}_\\mathsf{Z}(\\omega^0)=\\mathsf{Poly}_\\mathsf{Z}(\\omega^{n+d-1})=1$ For $i\\in[0,n+d-1)$: $\\mathsf{Poly}_\\mathsf{Z}(X\\omega)=\\mathsf{Poly}_\\mathsf{Z}(X)\\cdot\\frac{(1+\\beta)[\\alpha+\\mathsf{Poly}_{\\mathsf{Arr}}(X)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(X\\omega)]}{\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{S}}(X\\omega)}$ However, the above accumulator does not exist because the degree of the denominator, $\\mathsf{Poly}_\\mathsf{S}$, is different from $\\mathsf{Poly}_\\mathsf{Arr}$ and $\\mathsf{Poly}_\\mathsf{T}$. Specifically, there are $n$ elements in $\\mathsf{Arr}$, $d$ elements in $\\mathsf{T}$, but $n+d$ elements in $\\mathsf{S}$. Thus we have to decompose the denominator to make it have the same iteration as $\\mathsf{Arr}$ and $\\mathsf{T}$ do. It is worth noting for the numerator, the left term contains $\\mathsf{Poly}_\\mathsf{Arr}(X)$ while the right term contains $\\mathsf{Poly}_\\mathsf{T}(X)$ and $\\mathsf{Poly}_\\mathsf{T}(X\\omega)$. Therefore, it will be convenient to assume $d=n+1$. The order of $\\mathsf{S}$ is $2n+1$. To traverse $\\mathsf{S}$ in $n$ steps, we can halve it to $\\mathsf{S}_\\mathsf{l}=[s_0,s_1,\\dots,s_{n-1},s_n]$ and $\\mathsf{S}_\\mathsf{h}=[s_{n},s_{n+1},\\dots,s_{2n-1},s_{2n}]$, and prove $\\mathsf{S}_\\mathsf{l}[n]=\\mathsf{S}_\\mathsf{h}[0]$. Then we can compute the accumulator such that:\n$\\mathsf{Poly}_\\mathsf{Z}(\\omega^0)=\\mathsf{Poly}_\\mathsf{Z}(\\omega^{\\kappa-1})=1$ For $X\\in\\mathcal{H}_n\\setminus{\\omega^{\\kappa-1}}$: $\\mathsf{Poly}_\\mathsf{Z}(X\\omega)=\\mathsf{Poly}_\\mathsf{Z}(X)\\cdot\\frac{(1+\\beta)[\\alpha+\\mathsf{Poly}_{\\mathsf{Arr}}(X)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(X\\omega)]}{[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X\\omega)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X\\omega)]}$ For $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X)=\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X\\omega)$ Similarly, we take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=[\\mathsf{Poly}_{\\mathsf{Z}}(X)-1]\\cdot\\frac{X^n-1}{(X-\\omega^0)(X-\\omega^{\\kappa-1})}=0$ $\\displaylines{\\mathsf{Poly}_\\mathsf{Vanish2}(X)=\\{\\mathsf{Poly}_\\mathsf{Z}(X\\omega)\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X\\omega)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X\\omega)]-\\\\\\mathsf{Poly}_\\mathsf{Z}(X)\\cdot(1+\\beta)[\\alpha+\\mathsf{Poly}_{\\mathsf{Arr}}(X)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(X)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(X\\omega)]\\}\\cdot(X-\\omega^{\\kappa-1})}=0$ $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=[\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X)-\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X\\omega^{n+1})]\\cdot\\frac{X^n-1}{X-\\omega^{\\kappa-1}}=0$ These equations are true for every value of $X\\in\\mathcal{H}_n$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^n-1$, which is a minimal vanishing polynomial for $\\mathcal{H}_n$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$, and $\\mathsf{Poly}_\\mathsf{Vanish3}(X)$ must be vanishing on $\\mathcal{H}_n$ too. Specifically, the prover computes,\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^n - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^n - 1}$ $Q_3(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^n - 1}$ Instead of proving the three polynomials are zero polynomials one by one, we can linearly combine the three polynomials with a random challenge $\\rho$ sent by $\\mathcal{V}$ to compute:\n$W(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}+\\rho^2\\cdot{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}=0$ When $\\mathsf{Poly}_\\mathsf{Vanish1}(X),\\mathsf{Poly}_\\mathsf{Vanish2}(X),\\mathsf{Poly}_\\mathsf{Vanish3}(X)$ are vanishing on the domain $\\mathcal{H}_n$, $W(X)$ is also vanishing with high probability. Again, if and only if $W(X)$ is vanishing over the field $\\mathcal{H}_n$, $Q(X)=W(X)/(X^n-1)$ exists.\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_n$ and outside of it): $$ \\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)+\\rho^2\\cdot\\mathsf{Poly}_\\mathsf{Vanish3}(X)-Q(X)\\cdot(X^n-1)=0 $$ Ultimately the Plookup will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Z}(X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X)$, and $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is a zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) are too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Z}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Z}(X))$ $K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X))$ $K_\\mathsf{T}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T}(X))$ $K_{\\mathsf{S}_\\mathsf{l}}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X))$ $K_{\\mathsf{S}_\\mathsf{h}}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_n$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_n$. Call this point $\\zeta$. The prover will write the three points and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Z}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Z},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Z}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Z},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta)$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta)$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta\\omega)$ $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta)=\\mathsf{KZG.Open}(K_{\\mathsf{S}_\\mathsf{l}},\\zeta)$ $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_{\\mathsf{S}_\\mathsf{l}},\\zeta\\omega)$ $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(\\zeta)=\\mathsf{KZG.Open}(K_{\\mathsf{S}_\\mathsf{h}},\\zeta)$ $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_{\\mathsf{S}_\\mathsf{h}},\\zeta\\omega)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}=[\\mathsf{Poly}_\\mathsf{Z}(\\zeta)-1]\\cdot\\frac{(\\zeta^n-1)}{(\\zeta-\\omega^0)\\cdot(\\zeta-\\omega^{\\kappa-1})}$ $\\displaylines{Y_\\mathsf{Vanish2}=\\{\\mathsf{Poly}_\\mathsf{Z}(\\zeta\\omega)\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta)+\\beta\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta\\omega)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(\\zeta)+\\beta\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(\\zeta\\omega)]-\\\\\\mathsf{Poly}_\\mathsf{Z}(\\zeta)\\cdot(1+\\beta)[\\alpha+\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)]\\cdot[\\alpha(1+\\beta)+\\mathsf{Poly}_\\mathsf{T}(\\zeta)+\\beta\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)]\\}\\cdot(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish3}=[\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta)-\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta\\omega^{n+1})]\\cdot\\frac{\\zeta^n-1}{\\zeta-\\omega^{\\kappa-1}}$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1}+\\rho\\cdot{Y_\\mathsf{Vanish2}}+\\rho^2\\cdot{Y_\\mathsf{Vanish3}}-Q(\\zeta)\\cdot(\\zeta^k - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Security Proof # halo2 # Completeness # Any honest prover can do the computations explained above and create an accepting proof.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g,g^\\tau,g^{\\tau^2},\\dots,g^{\\tau^{n-1}}]$, $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{Arr^\\prime}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_\\mathsf{T^\\prime}(X)$, $Q$ $\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{Arr^\\prime}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_\\mathsf{T^\\prime}(X)$, $Q$ $\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$ $\\mathcal{A}$ wins if $\\mathcal{V}$ accepts at the end of the protocol For some $i\\in[0,\\kappa-1]$, $\\mathsf{Arr}[i]\\notin\\mathsf{T}$ Our proof is as follows:\nTo make $Y_\\mathsf{Zero}$ a zero polynomial, $\\mathcal{A}$ has to prove the four vanishing polynomials are correct. For $\\mathsf{Poly}_\\mathsf{Vanish1}$ and $\\mathsf{Poly}_\\mathsf{Vanish2}$, the permutation check tells us the probability that $\\mathcal{V}$ accepts the proof is negligible if some elements in $\\mathsf{Arr}$ are not in $\\mathsf{T}$. By the Schwartz-Zippel lemma, we know the probability that $\\mathsf{Poly}_\\mathsf{Vanish3}$ is vanishing is negligible if $\\mathsf{Poly}_\\mathsf{Arr^\\prime}(\\omega^0)\\ne\\mathsf{Poly}_\\mathsf{T^\\prime}(\\omega^0)$. Therefore, to win the KS game, $\\mathcal{A}$ has to prove $\\mathsf{Poly}_\\mathsf{Vanish4}$ is correct with the winning condition (some elements in $\\mathsf{Arr}$ do not appear in $\\mathsf{T}$). Assume $\\mathsf{Arr}[i^\\prime]\\notin\\mathsf{T},i\u003e0$, to make such $\\mathsf{Poly}_\\mathsf{Vanish4}$ exist, $\\mathsf{Arr}[i^\\prime]$ has to equal to $\\mathsf{Arr}[i^\\prime-1]$. And because $\\mathsf{Arr}[i^\\prime-1]\\ne{\\mathsf{T}[i^\\prime-1]}$, $\\mathsf{Arr}[i^\\prime-1]$ has to equal to $\\mathsf{Arr}[i^\\prime-2]$. Thus, to make the winning condition hold, $\\mathsf{Arr}[i^\\prime]=\\mathsf{Arr}[0]$ must hold, which contradicts to the condition of $\\mathsf{Poly}_\\mathsf{Vanish3}$, $\\mathsf{Arr}[0]=\\mathsf{T}[0]$.\nZero-Knowledge # Before we prove the above protocol is zero-knowledge, it is worth noting the protocol is different from the lookup argument of halo2 in the real world. Specifically, the real halo2 lookup optimizes the two permutation checks into one and fills the table with some random numbers for the PLONK-based proof system. We refer to the official halo2 handbook to see the details. To prove the above protocol is zero-knowledge, we do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ generates an array $\\mathsf{Arr^*}$ by randomly filling it with elements from $\\mathsf{T}$, then follows the same steps a prover would prove the lookup argument. $\\mathcal{S}$ computes $\\mathsf{Arr^{*^\\prime}},\\mathsf{T^\\prime}$ and interpolates the four arrays into their respective polynomials, $\\mathsf{Poly}_\\mathsf{Arr^*}(X)$, $\\mathsf{Poly}_\\mathsf{Arr^{*^\\prime}}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, and $\\mathsf{Poly}_\\mathsf{T^\\prime}(X)$. It computes $Q^*(X)$ and finally outputs the commitments to each of these polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta^*$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_\\mathsf{Arr^*}(\\zeta^*),\\mathsf{Poly}_\\mathsf{Arr^{*^\\prime}}(\\zeta^*),Q^*(\\zeta^*)$, $\\mathsf{Poly}_\\mathsf{T}(\\zeta^*\\omega)$, and $\\mathsf{Poly}_\\mathsf{T^\\prime}(\\zeta^*\\omega)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nPlookup # Completeness # Any honest prover can do the computations explained above and create an accepting proof.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g,g^\\tau,g^{\\tau^2},\\dots,g^{\\tau^{n-1}}]$, $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_\\mathsf{S}(X)$, $Q$ $\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_\\mathsf{S}(X)$, $Q$ $\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$ $\\mathcal{A}$ wins if $\\mathcal{V}$ accepts at the end of the protocol For some $i\\in[0,\\kappa-1]$, $\\mathsf{Arr}[i]\\notin\\mathsf{T}$ Our proof is as follows:\nTo make $Y_\\mathsf{Zero}$ a zero polynomial, $\\mathcal{A}$ has to prove the three vanishing polynomials are correct. It is easy to observe that $\\mathsf{Poly}_\\mathsf{Vanish1}$ and $\\mathsf{Poly}_\\mathsf{Vanish3}$ can be constructed even if some elements in $\\mathsf{Arr}$ do not appear in $\\mathsf{T}$, so we focus on the $\\mathsf{Poly}_\\mathsf{Vanish2}$. By the soundness of the product check, we know $\\mathsf{S}$ must be the union set of $\\mathsf{Arr}$ and $\\mathsf{T}$ if we want to the product of $\\mathsf{S}[i]$ equals to the product of $\\mathsf{Arr}[i]$ and $\\mathsf{T}[i]$. Recall the equation $\\mathcal{A}$ needs to prove: $$ (1+\\beta)^n\\prod_{i\u003c{n}}[\\alpha+\\mathsf{Poly}_{\\mathsf{Arr}}(\\omega^i)]\\cdot\\prod_{i\u003c{d-1}}[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(\\omega^{i+1})]=\\prod_{i\u003c{n+d-1}}[\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{S}}(\\omega^{i+1})] $$ Thus, for each $i\\in[0,d-1]$, there exists a factor in the right-hand side of the equation equal to $\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(\\omega^{i+1})$, which means $\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{T}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{T}}(\\omega^{i+1})=\\alpha(1+\\beta)+\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)+\\beta\\mathsf{Poly}_{\\mathsf{S}}(\\omega^{i+1})$. We can get $\\mathsf{Poly}_{\\mathsf{T}}(\\omega^i)=\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)$ and $\\mathsf{Poly}_{\\mathsf{T}}(\\omega^{i+1})=\\mathsf{Poly}_{\\mathsf{S}}(\\omega^{i+1})$ for $i\\in[0,d-1]$. Similarly, we can get $\\mathsf{Poly}_{\\mathsf{Arr}}(\\omega^i)=\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)=\\mathsf{Poly}_{\\mathsf{S}}(\\omega^{i+1})$ for $i\\in[0,n]$. Since $n$ should be equal to or less than $d$, when $\\mathsf{Poly}_{\\mathsf{Arr}}(\\omega^i)=\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)$, $\\mathsf{Poly}_{\\mathsf{T}}(\\omega^i)=\\mathsf{Poly}_{\\mathsf{S}}(\\omega^i)$ must hold at the same time, which contradicts to the winning assumption. Therefore, the protocol is sound.\nZero-Knowledge # To prove the above protocol is zero-knowledge, we do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ generates an array $\\mathsf{Arr^*}$ by randomly filling it with elements from $\\mathsf{T}$, then follows the same steps a prover would prove the lookup argument. $\\mathcal{S}$ computes $\\mathsf{S}_\\mathsf{l}$, $\\mathsf{S}_\\mathsf{h}$, and $\\mathsf{Z}$ and interpolates the five arrays into their respective polynomials, $\\mathsf{Poly}_\\mathsf{Arr^*}(X)$, $\\mathsf{Poly}_\\mathsf{T}(X)$, $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(X)$, $\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(X)$, and $\\mathsf{Poly}_{\\mathsf{Z}}(X)$. It computes $Q^*(X)$ and finally outputs the commitments to each of these polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta^*$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_\\mathsf{Arr^*}(\\zeta^*),\\mathsf{Poly}_\\mathsf{T}(\\zeta^*),\\mathsf{Poly}_\\mathsf{T}(\\zeta^*\\omega),\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta^*),\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{l}}(\\zeta^*\\omega),\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(\\zeta^*),\\mathsf{Poly}_{\\mathsf{S}_\\mathsf{h}}(\\zeta^*\\omega),Q^*(\\zeta^*),\\mathsf{Poly}_\\mathsf{Z}(\\zeta^*)$, and $\\mathsf{Poly}_\\mathsf{Z}(\\zeta^*\\omega)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":11,"href":"/docs/gadgets/mult1/","title":"Mult1","section":"Gadgets","content":" Multiplication (Type 1) # Recap of types # Type Description Recap This mult1 $\\mathsf{Arr}_3=\\mathsf{Arr}_1 \\cdot \\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the element-wise multiplication of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. ✅ mult2 $\\mathsf{Prod}_\\mathsf{Arr}=\\prod_{i = 0}^{n-1} \\mathsf{Arr}[i]$ $\\mathsf{Prod}_\\mathsf{Arr}$ is the disclosed product of all the elements in $\\mathsf{Arr}$. mult3 $\\prod_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\prod_{i = 0}^{n-1} \\mathsf{Arr}_2[i]$ $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ have the same undisclosed product. Relation # $ \\mathcal{R}_{\\mathtt{mult1}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr_2},K_\\mathsf{Arr_3}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]\\cdot\\mathsf{Arr_2}[i], 0\\leq i \\leq n-1, \\\\ \\mathsf{Poly}_\\mathsf{Arr_j}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_j}), 1\\leq j \\leq 3, \\\\ K_\\mathsf{Arr_j}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_j}), 1\\leq j \\leq 3, \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds two arrays $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that $\\mathsf{Arr_3}$ is the element-wise product of all the elements in the array: $\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]\\cdot\\mathsf{Arr_2}[i]$. The prover will encode the three arrays into three polynomials: $\\mathsf{Poly}_\\mathsf{Arr_1}$, $\\mathsf{Poly}_\\mathsf{Arr_2}$, and $\\mathsf{Poly}_\\mathsf{Arr_3}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$). It will commit to each polynomial: $K_\\mathsf{Arr_1}$, $K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$. The verifier ($\\mathcal{V}$) cannot check any of the $\\mathsf{Arr_i}$ or $\\mathsf{Poly}_\\mathsf{Arr_i}$ values directly (they may contain secret information, and even if they do not, they are too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$,$K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$.\nIn order to prove$K_\\mathsf{Arr_1}$,$K_\\mathsf{Arr_2}$, and $K_\\mathsf{Arr_3}$ are consistent, the prover will compute the difference between $(\\mathsf{Poly}_\\mathsf{Arr_1}\\cdot\\mathsf{Poly}_\\mathsf{Arr_2})$ and $(\\mathsf{Poly}_\\mathsf{Arr_3})$ using add1. Next, it will show it is 0 for each evaluation point in the domain $\\mathcal{H}_\\kappa$. Showing a polynomial is zero on the domain is a common sub-protocol used by many gadgets.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ computes or holds an array $\\mathsf{Arr_3} = [a_{(3,0)}, a_{(3,1)}, a_{(3,2)}, \\dots, a_{(3,n-1)}]$ of $n$ integers ($a_{(3,i)} \\in \\mathbb{Z}_q$) such that: $\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]\\cdot\\mathsf{Arr_2}[i]$ for $i$ from 0 to $n-1$ Polynomial Level # We assume the three arrays $\\mathsf{Arr_1}$, $\\mathsf{Arr_2}$ and $\\mathsf{Arr_3}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded.\nRecall the constraint we want to prove:\n$\\mathsf{Arr_3}[i]=\\mathsf{Arr_1}[i]\\cdot\\mathsf{Arr_2}[i]$ for $i$ from 0 to $n-1$ In polynomial form, the constraint is:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_3}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)\\cdot\\mathsf{Poly}_\\mathsf{Arr_2}(X)$ We adjust the constraints to show an equality with 0:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Vanish}(X)=\\mathsf{Poly}_\\mathsf{Arr_3}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X)\\cdot\\mathsf{Poly}_\\mathsf{Arr_2}(X)=0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(X)}{X^\\kappa - 1}$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$ Ultimately the mult1 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_3}(X)$. Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$\n$K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$\n$K_\\mathsf{Arr_3}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_3}(X))$\n$K_Q=\\mathsf{KZG.Commit}(Q(X))$\nThe prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$\n$\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$\n$\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$\n$\\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_3},\\zeta)$\n$Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$\nTo check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish}=\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta)$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Rust Mathematica (Toy Example) Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr_1}, \\mathsf{Arr_2}$ and $\\mathsf{Arr_3}$ such that $\\mathsf{Arr_1}[i] \\cdot \\mathsf{Arr_2}[i] - \\mathsf{Arr_3}[i] = 0 \\space \\forall i \\in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$ = Y_\\mathsf{Vanish} - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$ = \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta) - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta) - \\frac{\\mathsf{Poly_{Vanish}}(\\zeta)}{\\zeta^\\kappa - 1}\\cdot(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}( \\zeta) - (\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)+\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_3}(\\zeta))$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish}}(X)$ is vanishing on $\\mathcal{H_\\kappa}$, i.e. if $\\mathsf{Poly}_\\mathsf{Arr_1}(X) \\cdot \\mathsf{Poly}_\\mathsf{Arr_2}(X) - \\mathsf{Poly}_\\mathsf{Arr_3}(X) =0 \\space \\forall X \\in \\mathcal{H}_\\kappa$. This is true if if $\\mathsf{Arr_1}[i] \\cdot \\mathsf{Arr_2}[i] - \\mathsf{Arr_3}[i] = 0 \\space \\forall i \\in [0, \\kappa - 1]$, since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$. But $\\mathsf{Arr_1}[i] \\cdot \\mathsf{Arr_2}[i] - \\mathsf{Arr_3}[i] = 0 \\space \\forall i \\in [0, \\kappa - 1]$ is precisely the relation tnat we assumed held for our prover (if $\\kappa \\gt n$ then the arrays get padded such that this relation still holds), thus the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr3}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr3}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Arr}_3\\neq \\mathsf{Arr}_1 \\cdot \\mathsf{Arr}_2$\nOur proof is as follows:\nFor the second win condition to be fulfilled, the constraint must not hold for at least one index of the arrays. But then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and sends $K_Q = g^{Q(\\tau)}$. It also sends commitments to $\\mathsf{Poly}_\\mathsf{Arr1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr2}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr3}(X)$. Each commitment $\\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr2}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\zeta)$ can only feasibliy be opened to one value each. For $\\mathcal{A}$ to have the verifier accept, they must send a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1}}{(\\zeta^\\kappa - 1)}$. This means being able to send $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ choose arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr2}(\\tau)}$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\tau)$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Arr2}(\\tau)}$ , and $g^{\\mathsf{Poly}_\\mathsf{Arr3}(\\tau)}$ to output as the commitments $K_\\mathsf{Arr1}$, $ K_\\mathsf{Arr2}$, and $ K_\\mathsf{Arr3}$. $\\mathcal{S}$ then generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the values they chose for ${\\mathsf{Poly}_\\mathsf{Arr1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr2}(\\tau)}$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\tau)$. $\\mathcal{S}$ outputs the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the second random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Arr2}(\\zeta)}$, and $\\mathsf{Poly}_\\mathsf{Arr3}(\\zeta)$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nFor mult2, the proof is written with a simulator that doesn\u0026rsquo;t know the trapdoor; however, with small alterations the proof for mult2 should apply here and vice versa "},{"id":12,"href":"/docs/gadgets/mult2/","title":"Mult2","section":"Gadgets","content":" Multiplication (Type 2) # Recap of types # Type Description Recap This mult1 $\\mathsf{Arr}_3=\\mathsf{Arr}_1 \\cdot \\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the element-wise multiplication of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. mult2 $\\mathsf{Prod}_\\mathsf{Arr}=\\prod_{i = 0}^{n-1} \\mathsf{Arr}[i]$ $\\mathsf{Prod}_\\mathsf{Arr}$ is the disclosed product of all the elements in $\\mathsf{Arr}$. ✅ mult3 $\\prod_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\prod_{i = 0}^{n-1} \\mathsf{Arr}_2[i]$ $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ have the same undisclosed product. Relation # $ \\mathcal{R}_{\\mathtt{mult2}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr},\\mathsf{Prod}_\\mathsf{Arr}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}], \\\\ \\mathsf{Prod}_\\mathsf{Arr} = \\prod_{i = 0}^{n-1} a_i, \\\\ \\mathsf{Poly}_\\mathsf{Arr}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}) \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds an array $\\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers (from $\\mathbb{Z}_q$) and a disclosed integer $\\mathsf{Prod}_\\mathsf{Arr}$. It will produce a succinct (independent of $n$) proof that $\\mathsf{Prod}_\\mathsf{Arr}$ is the product of all the elements in the array. The prover will encode the array into a polynomial $\\mathsf{Poly}_\\mathsf{Arr}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to the polynomial $K_\\mathsf{Arr}$. The verifier ($\\mathcal{V}$) cannot check $\\textsf{Arr}$ or $\\mathsf{Poly}_\\mathsf{Arr}$ directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr}$ and the asserted value $\\mathsf{Prod_\\mathsf{Arr}}$.\nIn order to prove $K_\\mathsf{Arr}$ and $\\mathsf{Prod}_\\mathsf{Arr}$ are consistent, the prover will build a helper array $\\mathsf{Acc}_\\mathsf{Arr}$ called an accumulator (or accumulating array or incremental array). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\\mathsf{Arr}$, the prover will also encode $\\mathsf{Acc}$ as a polynomial and provide a commitment of it to the verifier. The idea is that the prover will prove a relation between $\\mathsf{Arr}$ and $\\mathsf{Acc}$; and a relation between $\\mathsf{Acc}$ and $\\mathsf{Prod_\\mathsf{Arr}}$. Put together, it will imply the correct relation between $\\mathsf{Arr}$ and $\\mathsf{Prod_\\mathsf{Arr}}$.\nConsider a small numeric example in $\\mathbb{Z}_{97}$ where $\\mathsf{Arr}= [84,67,11,92,36,67]$ and $\\mathsf{Prod}_\\mathsf{Arr}=72$. The first idea is to get $\\mathsf{Prod}_\\mathsf{Arr}$ into an array. Say, we just append it: $\\mathsf{Arr}''= [84,67,11,92,36,67,72] $. How does the prover show $\\mathsf{Arr}''$ is correct? The last value of the array depends on every single element that precedes it, which will be a complex constraint to prove.\nAn alternative idea is to create a new array that starts the same as $\\mathsf{Arr}$ and ends up at $\\mathsf{Prod}_\\mathsf{Arr}$ by folding in the integers from $\\mathsf{Arr}$ one-by-one with multiplication. Then each value in the new array will depend on only two values, as below.\nThe first value in $\\mathsf{Acc}$ will be a copy of the first value from $\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$\\mathsf{Acc}= [84, \\bot,\\bot,\\bot,\\bot,\\bot] $\nThe next value will be the multiplication (mod 97) of: 67 (the value at the same index in $\\mathsf{Arr}$) and 84 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$ \\mathsf{Acc} = [84, (67\\cdot84),\\bot,\\bot,\\bot,\\bot] = [84, 2,\\bot,\\bot,\\bot,\\bot]$\nThe next value will be the multiplication of: 11 (the value at the same index in $\\mathsf{Arr}$) and 2 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [84, 2,(11\\cdot2),\\bot,\\bot,\\bot] = [84,2,22,\\bot,\\bot,\\bot]$ $ \\mathsf{Acc} = [84, 2,22,(92\\cdot22),\\bot,\\bot] = [84,2,22,84,\\bot,\\bot]$ $ \\mathsf{Acc} = [84, 2,22,84,(36\\cdot84),\\bot] = [84,2,22,84,17,\\bot]$ $ \\mathsf{Acc} = [84,2,22,84,17,(67\\cdot17)] = [84, 2, 22, 84, 17, 72]$ $\\mathsf{Prod}_\\mathsf{Arr}=72$ Notice the last value in $\\mathsf{Acc}$ is $\\mathsf{Prod_\\mathsf{Arr}}$. The prover wants to show three constraints:\nThe first value in $\\mathsf{Acc}$ matches the first value in $\\mathsf{Arr}$, The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i]\\cdot\\mathsf{Acc}[i-1]$, The last value in $\\mathsf{Acc}$ matches $\\mathsf{Prod}_\\mathsf{Arr}$. If all three constraints are true, then $\\mathsf{Prod}_\\mathsf{Arr}$ is the product of the elements of $\\mathsf{Arr}$.\nLast, while it is not necessary to do, it is often convenient to hold the the value $\\mathsf{Prod}_\\mathsf{Arr}$ at the start of the array $\\mathsf{Acc}$ instead of the end. For this reason, the mathematical explaination below will construct $\\mathsf{Acc}$ \u0026ldquo;backwards\u0026rdquo; (or right-to-left) from the above example, where the last value of $\\mathsf{Acc}$ matches the last value of $\\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\\mathsf{Acc}$ is $\\mathsf{Prod}_\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, \\bot, 67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, 84, 67]$ $\\ldots$ $ \\mathsf{Acc} = [72, 84, 36, 65, 84, 67]$ $\\mathsf{Prod}_\\mathsf{Arr}=72$ Protocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers ($a_i \\in \\mathbb{Z}_q$) $\\mathcal{P}$ computes array $\\mathsf{Acc}$ as follows: $\\mathsf{Acc}[n-1]\\leftarrow\\mathsf{Arr}[n-1]$ $\\mathsf{Acc}[i]\\leftarrow\\mathsf{Arr}[i]\\cdot\\mathsf{Acc}[i+1]$ for $i$ from $n-2$ to 0 $\\mathcal{P}$ computes $\\mathsf{Prod}_\\mathsf{Arr}\\leftarrow\\mathsf{Acc}[0]$ Polynomial Level # We assume arrays $\\mathsf{Arr}$ and $\\mathsf{Acc}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product).\nRecall the three constraints we want to prove (now adjusted to fit with an $\\mathsf{Acc}$ that is constructed \u0026ldquo;backwards,\u0026rdquo; as noted above):\nThe last value in $\\mathsf{Acc}$ matches the last value in $\\mathsf{Arr}$, The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i]\\cdot\\mathsf{Acc}[i-1]$, The first value in $\\mathsf{Acc}$ matches $\\mathsf{Prod}_\\mathsf{Arr}$. In polynomial form, the constraints are:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Prod}_\\mathsf{Arr}$ In constraint 2, $\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ can also be conceptualized as rotate applied to $\\mathsf{Poly}_\\mathsf{Acc}(X)$ by one element (rightward in the array view). Also note that constraint 2 does not hold at $X=\\omega^{\\kappa-1}$ because this value is defined by constraint 1 (for the last value of $X$, the \u0026ldquo;next\u0026rdquo; value, $\\omega X$, wraps back to the first element of the array which is a boundary condition).\nWe adjust each of these constraints to show an equality with 0:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)=0$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)=0$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Prod}_\\mathsf{Arr}=0$ Next we take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X))\\cdot(X-\\omega^{\\kappa-1})=0$ $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Prod}_\\mathsf{Arr})\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These equations are true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$, and $\\mathsf{Poly}_\\mathsf{Vanish3}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes,\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ $Q_3(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$, $Q_2(X)$, and $Q_3(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all three $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all three are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2}{X^\\kappa - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(X) + \\rho^2 \\mathsf{Poly}_\\mathsf{Vanish3}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the mult2 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Acc}(X)$, $\\mathsf{Poly}_\\mathsf{Acc}(\\omega X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, and $\\mathsf{Prod}_\\mathsf{Arr}$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X))$ $K_\\mathsf{Acc}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Acc}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Acc},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}=(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish2}=(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Vanish3}=(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Prod}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)}$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Rust Mathematica (Toy Example) Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}$ such that $\\mathsf{Prod}_\\mathsf{Arr}=\\prod_{i = 0}^{n-1} \\mathsf{Arr}[i] \\space \\forall i \\in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)} \\newline - \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(\\zeta)\\rho^2}{\\zeta^\\kappa - 1} \\cdot(\\zeta^\\kappa - 1)$\n$= (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)} \\newline - ((\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}) + \\rho(\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)+\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot \\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1}) \\newline + \\rho^2 (\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)-\\mathsf{Sum}_\\mathsf{Arr})\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)})$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta) + \\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(\\zeta)\\rho^2$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish_1}}(X), \\mathsf{Poly_{Vanish_2}}(X)$ and $\\mathsf{Poly_{Vanish_3}}(X),$ are all vanishing on $\\mathcal{H_\\kappa}$, i.e. if all three of the following conditions hold for all $X \\in \\mathcal{H}_\\kappa$:\n$(\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$ $ (\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot \\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X))\\cdot(X-\\omega^{\\kappa-1})=0$ $ (\\mathsf{Poly}_\\mathsf{Acc}(X)-\\mathsf{Prod}_\\mathsf{Arr})\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These conditions, in turn, hold if:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot \\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc}(X)=\\mathsf{Prod}_\\mathsf{Arr}$ Where we get the \u0026ldquo;For $X$\u0026rdquo; due to zeroing parts of the polynomials (see zero1). Since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$, the above conditions are true if:\nThe last value in $\\mathsf{Acc}$ matches the last value in $\\mathsf{Arr}$ The rest of the values in $\\mathsf{Acc}$ are of the form $\\mathsf{Acc}[i]=\\mathsf{Arr}[i] \\cdot \\mathsf{Acc}[i-1]$ The first value in $\\mathsf{Acc}$ matches $\\mathsf{Prod}_\\mathsf{Arr}$ Which are precisely the conditions the Intuitions sections explains will hold if the prover contructs their Accumulator by following the protocol and using $\\mathsf{Arr}$ such that $\\mathsf{Prod}_\\mathsf{Arr}=\\prod_{i = 0}^{n-1} \\mathsf{Arr}[i] \\space \\forall i \\in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Acc}(X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Acc}(X)$, $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Prod}_\\mathsf{Arr}\\neq\\prod_{i = 0}^{n-1} \\mathsf{Arr}[i]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, one of the three constraints must be false. But then the $\\mathsf{Poly}_\\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcrip. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Acc}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr}(X)$. Each commitment $\\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta \\cdot \\omega)$ can only feasibliy be opened to one value each. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2Y_\\mathsf{Vanish3}}{\\zeta^\\kappa - 1}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2Y_\\mathsf{Vanish3}}{\\zeta^\\kappa - 1}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ generates an array $\\mathsf{Arr'}$ whose product is equal to the disclosed value $\\mathsf{Prod}_\\mathsf{Arr}$ (this array could just have $\\mathsf{Prod}_\\mathsf{Arr}$ in one entry, and $1$\u0026rsquo;s elsewhere), then follows the same steps a prover would to prove the product of this array. So, $\\mathcal{S}$ computes the accumulator $\\mathsf{Acc'}$ and interpolates the two arrays into their respective polynomials, $\\mathsf{Poly}_\\mathsf{Acc'}(X)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(X)$. It computes $Q(X)'$ using $\\mathsf{Poly}_\\mathsf{Acc'}(X)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(X)$ and the random challenge point $\\rho'$ (by strong Fiat-Shamir). $\\mathcal{S}$ commits to each of these three polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta'$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta'), \\space \\mathsf{Poly}_\\mathsf{Arr}(\\zeta'), \\space Q(\\zeta')$, and $\\mathsf{Poly}_\\mathsf{Acc}(\\zeta' \\cdot \\omega)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nThis proof could also be done by defining a simulator that knows the trapdoor $\\tau$ and cant thus create a passing witness for any commitment. The proof for mult1 is done in this style, but with small alterations would work here as well (and vice versa for this style of proof working for mult1) "},{"id":13,"href":"/docs/gadgets/mult3/","title":"Mult3","section":"Gadgets","content":" Multiplication (Type 3) # Recap of types # Type Description Recap This mult1 $\\mathsf{Arr}_3=\\mathsf{Arr}_1 \\cdot \\mathsf{Arr}_2$ $\\mathsf{Arr}_3$ is the element-wise multiplication of $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$. mult2 $\\mathsf{Prod}_\\mathsf{Arr}=\\prod_{i = 0}^{n-1} \\mathsf{Arr}[i]$ $\\mathsf{Prod}_\\mathsf{Arr}$ is the disclosed product of all the elements in $\\mathsf{Arr}$. mult3 $\\prod_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\prod_{i = 0}^{n-1} \\mathsf{Arr}_2[i]$ $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ have the same undisclosed product. ✅ Relation # $ \\mathcal{R}_{\\mathtt{mult3}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr2}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}],\\\\ \\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}], \\\\ \\mathsf{Poly}_\\mathsf{Arr_1}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_1}), \\\\ \\mathsf{Poly}_\\mathsf{Arr_2}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_2}), \\\\ K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}),\\\\ K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}), \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds two arrays $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that they have the same undisclosed product. The prover will encode the two arrays into polynomials, $\\mathsf{Poly}_\\mathsf{Arr_1}$ and $\\mathsf{Poly}_\\mathsf{Arr_2}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to them as $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$. The verifier ($\\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$.\nIn order to prove $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$ are consistent, the prover will build two helper arrays $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$ called accumulators (or accumulating arrays or incremental arrays). This should not be confused with accumulators from cryptography, which are a concept related to succinct proofs but are distinct. As with $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$, the prover will also encode $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$ as a polynomials and provide a commitment to the verifier of each one. The idea is that the prover will prove a relation between each $\\mathsf{Arr}$ and its $\\mathsf{Acc}$; and a relation between $\\mathsf{Acc_1}$ and $\\mathsf{Acc_2}$. Put together, it will imply the correct relation between $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$.\nWe will illustrate a small numerical example in $\\mathbb{Z}_{97}$ of constructing an accumulator $\\mathsf{Acc}$ for the array $\\mathsf{Arr}= [84,67,11,92,36,67]$. The idea is to create a new array, $\\mathsf{Acc}$, that starts the same as $\\mathsf{Arr}$ and ends with the product of all entries of $\\mathsf{Arr}$, by folding in the integers from $\\mathsf{Arr}$ one-by-one with multiplication. Then each value in the new array will depend on only two values, as below.\nThe first value in $\\mathsf{Acc}$ will be a copy of the first value from $\\mathsf{Arr}$:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$\\mathsf{Acc}= [84, \\bot,\\bot,\\bot,\\bot,\\bot] $\nThe next value will be the multiplication (mod 97) of: 67 (the value at the same index in $\\mathsf{Arr}$) and 84 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$\n$ \\mathsf{Acc} = [84, (67\\cdot84),\\bot,\\bot,\\bot,\\bot] = [84, 2,\\bot,\\bot,\\bot,\\bot]$\nThe next value will be the multiplication of: 11 (the value at the same index in $\\mathsf{Arr}$) and 2 (the previous value in $\\mathsf{Acc}$):\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [84, 2,(11\\cdot2),\\bot,\\bot,\\bot] = [84,2,22,\\bot,\\bot,\\bot]$ $ \\mathsf{Acc} = [84, 2,22,(92\\cdot22),\\bot,\\bot] = [84,2,22,84,\\bot,\\bot]$ $ \\mathsf{Acc} = [84, 2,22,84,(36\\cdot84),\\bot] = [84,2,22,84,17,\\bot]$ $ \\mathsf{Acc} = [84,2,22,84,17,(67\\cdot17)] = [84, 2, 22, 84, 17, 72]$ Notice the last value in $\\mathsf{Acc}$ is the product of all the entries in $\\mathsf{Arr}$. The prover wants to show five constraints:\nThe first value in $\\mathsf{Acc_1}$ matches the first value in $\\mathsf{Arr_1}$ The first value in $\\mathsf{Acc_2}$ matches the first value in $\\mathsf{Arr_2}$ The rest of the values in $\\mathsf{Acc}_1$ are of the form $\\mathsf{Acc_1}[i]=\\mathsf{Arr_1}[i]\\cdot\\mathsf{Acc_1}[i-1]$ The rest of the values in $\\mathsf{Acc}_2$ are of the form $\\mathsf{Acc_2}[i]=\\mathsf{Arr_2}[i]\\cdot\\mathsf{Acc_2}[i-1]$ The last value in $\\mathsf{Acc_1}$ matches the last value in $\\mathsf{Acc_2}$ If all five constraints are true, then entries of $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ have the same product.\nLast, while it is not necessary to do, it is often convenient to hold the the value of the product at the start of the array $\\mathsf{Acc}$ instead of the end. For this reason, the mathematical explaination below will construct $\\mathsf{Acc}$ \u0026ldquo;backwards\u0026rdquo; (or right-to-left) from the above example, where the last value of $\\mathsf{Acc}$ matches the last value of $\\mathsf{Arr}$, the values are folded in from right to left, and the first (leftmost) value of $\\mathsf{Acc}$ is the product of all entries:\n$\\mathsf{Arr}= [84,67,11,92,36,67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, \\bot, 67]$ $ \\mathsf{Acc} = [\\bot, \\bot, \\bot, \\bot, 84, 67]$ $\\ldots$ $ \\mathsf{Acc} = [72, 84, 36, 65, 84, 67]$ and the product of all entries in $\\mathsf{Arr}$ is 72 Protocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ computes array $\\mathsf{Acc_j}$ as follows for $j \\in [1,2]$: $\\mathsf{Acc_j}[n-1]\\leftarrow\\mathsf{Arr_j}[n-1]$ $\\mathsf{Acc_j}[i]\\leftarrow\\mathsf{Arr_j}[i]\\cdot\\mathsf{Acc_j}[i+1]$ for $i$ from $n-2$ to 0 Polynomial Level # We assume arrays $\\mathsf{Arr_1}$, $\\mathsf{Arr_2}$, $\\mathsf{Acc_1}$, and $\\mathsf{Acc_2}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 1 (which will not change the product).\nRecall the five constraints we want to prove (now adjusted to fit with an $\\mathsf{Acc}$ that is constructed \u0026ldquo;backwards,\u0026rdquo; as noted above):\nThe last value in $\\mathsf{Acc_1}$ matches the last value in $\\mathsf{Arr_1}$ The last value in $\\mathsf{Acc_2}$ matches the last value in $\\mathsf{Arr_2}$ The rest of the values in $\\mathsf{Acc}_1$ are of the form $\\mathsf{Acc_1}[i]=\\mathsf{Arr_1}[i]\\cdot\\mathsf{Acc_1}[i-1]$ The rest of the values in $\\mathsf{Acc}_2$ are of the form $\\mathsf{Acc_2}[i]=\\mathsf{Arr_2}[i]\\cdot\\mathsf{Acc_2}[i-1]$ The first value in $\\mathsf{Acc_1}$ matches the first value in $\\mathsf{Acc_2}$ In polynomial form, the constraints are:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, For $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Acc_2}(X)$ In constraints 2 and 3, $\\mathsf{Poly}_\\mathsf{Acc}(\\omega\\cdot X)$ can also be conceptualized as rotate applied to $\\mathsf{Poly}_\\mathsf{Acc}(X)$ by one element (rightward in the array view). Also note thats constraint 2 and 3 do not hold at $X=\\omega^{\\kappa-1}$ because this value is defined by constraint 1 (for the last value of $X$, the \u0026ldquo;next\u0026rdquo; value, $\\omega X$, wraps back to the first element of the array which is a boundary condition).\nWe adjust each of these constraints to show an equality with 0:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X)=0$, For $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X)=0$, For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)=0$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)=0$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Acc_2}(X)=0$ Next we take care of the \u0026ldquo;for $X$\u0026rdquo; conditions by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=(\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$, $\\mathsf{Poly}_\\mathsf{Vanish3}(X)=(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X))\\cdot(X-\\omega^{\\kappa-1})=0$ $\\mathsf{Poly}_\\mathsf{Vanish4}(X)=(\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X)\\cdot\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X))\\cdot(X-\\omega^{\\kappa-1})=0$ $\\mathsf{Poly}_\\mathsf{Vanish5}(X)=(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Acc_2}(X)\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These equations are true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish3}(X)$, $\\mathsf{Poly}_\\mathsf{Vanish4}(X)$, and $\\mathsf{Poly}_\\mathsf{Vanish5}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prove computes,\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ $Q_3(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish3}(X)}{X^\\kappa - 1}$ $Q_4(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish4}(X)}{X^\\kappa - 1}$ $Q_5(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish5}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$, $Q_2(X)$, $Q_3(X)$, $Q_4(X)$, and $Q_5(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all five $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all five are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4}{X^\\kappa - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2} (X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X) \\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4 - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the mult3 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$ $K_\\mathsf{Acc_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Acc_1}(X))$ $K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$ $K_\\mathsf{Acc_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Acc_2}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Acc_1},\\zeta\\omega)$ $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{Acc_2},\\zeta\\omega)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}= (\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish2}= (\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^{\\kappa-1})}$ $Y_\\mathsf{Vanish3}=(\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Vanish4}= (\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)-\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)\\cdot\\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\zeta))\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Vanish5}= (\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)-\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)\\cdot\\frac{(\\zeta^\\kappa-1)}{(\\zeta-\\omega^0)}$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5}- Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ such that $\\prod_{i = 0}^{n-1} \\mathsf{Arr}_1[i]=\\prod_{i = 0}^{n-1} \\mathsf{Arr}_2[i] \\space \\forall i \\in [0, n - 1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$ = Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5}- Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5} - (\\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4}{X^\\kappa - 1})(\\zeta^\\kappa - 1)$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4 Y_\\mathsf{Vanish5} - {\\mathsf{Poly}_\\mathsf{Vanish1}(X) - \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho - \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 - \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 - \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4}$\n$= 0$\nWhere the finally equality holds becaue $Y_{\\mathsf{Vanish_j}}=\\mathsf{Poly_{Vanish_j}}(\\zeta)$.\nNote also that the second equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho + \\mathsf{Poly}_\\mathsf{Vanish3}(X)\\rho^2 + \\mathsf{Poly}_\\mathsf{Vanish4}(X)\\rho^3 + \\mathsf{Poly}_\\mathsf{Vanish5}(X)\\rho^4$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish_1}}(X), \\mathsf{Poly_{Vanish_2}}(X)$, $\\mathsf{Poly_{Vanish_3}}(X),$ $\\mathsf{Poly_{Vanish_4}}(X)$, and $\\mathsf{Poly_{Vanish_5}}(X),$ are all vanishing on $\\mathcal{H_\\kappa}$, i.e. if all three of the following conditions hold for all $X \\in \\mathcal{H}_\\kappa$:\n$ (\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Arr_1}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$ $ (\\mathsf{Poly}_\\mathsf{Acc_2}(X)-\\mathsf{Poly}_\\mathsf{Arr_2}(X))\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}=0$ $(\\mathsf{Poly}_\\mathsf{Acc_1}(X)-(\\mathsf{Poly}_\\mathsf{Arr_1}(X) \\cdot \\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)))\\cdot(X-\\omega^{\\kappa-1})=0$ $ (\\mathsf{Poly}_\\mathsf{Acc_2}(X)-(\\mathsf{Poly}_\\mathsf{Arr_2}(X) \\cdot \\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)))\\cdot(X-\\omega^{\\kappa-1})=0$ $ (\\mathsf{Poly}_\\mathsf{Acc_1}(X)-\\mathsf{Poly}_\\mathsf{Acc_2}(X)\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}=0$ These conditions, in turn, hold if:\nFor $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X)$ For $X=w^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Arr_1}(X) \\cdot \\mathsf{Poly}_\\mathsf{Acc_1}(\\omega\\cdot X)$ For all $X$ except $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Acc_2}(X)=\\mathsf{Poly}_\\mathsf{Arr_2}(X) \\cdot \\mathsf{Poly}_\\mathsf{Acc_2}(\\omega\\cdot X)$ For $X=w^0$: $\\mathsf{Poly}_\\mathsf{Acc_1}(X)=\\mathsf{Poly}_\\mathsf{Acc_2}(X)$ Where we get the \u0026ldquo;For $X$\u0026rdquo; due to zeroing parts of the polynomials (see zero1). Since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$, the above conditions are true if:\nThe last value in $\\mathsf{Acc_1}$ matches the last value in $\\mathsf{Arr_1}$ The last value in $\\mathsf{Acc_2}$ matches the last value in $\\mathsf{Arr_2}$ The rest of the values in $\\mathsf{Acc}_1$ are of the form $\\mathsf{Acc_1}[i]=\\mathsf{Arr_1}[i] \\cdot \\mathsf{Acc_1}[i-1]$ The rest of the values in $\\mathsf{Acc}_2$ are of the form $\\mathsf{Acc_2}[i]=\\mathsf{Arr_2}[i] \\cdot \\mathsf{Acc_2}[i-1]$ The first value in $\\mathsf{Acc_1}$ matches the first value in $\\mathsf{Acc_2}$ Which are precisely the conditions the Intuitions sections explains will hold if the prover contructs their Accumulators by following the protocol and using $\\mathsf{Arr}_1$ and $\\mathsf{Arr_2}$ such that $\\prod_{i = 0}^{n-1} \\mathsf{Arr}_1[i] =\\prod_{i = 0}^{n-1} \\mathsf{Arr}_2[i] \\space \\forall i \\in [0, n - 1]$. This is what we assumed true about the prover, thus the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_{2}}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_{2}}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_{2}}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_{2}}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}A$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\prod_{i = 0}^{n-1} \\mathsf{Arr_1}[i]\\neq\\prod_{i = 0}^{n-1} \\mathsf{Arr_2}[i]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, one of the five constraints must be false. But then the $\\mathsf{Poly}_\\mathsf{Vanish}$ corresponding to that constraint is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, also writes commitments to $\\mathsf{Poly}_\\mathsf{Acc_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$. Each commitment $\\mathcal{A}$ has written is a linear combination of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta\\omega)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta\\omega)$ can each only feasibliy be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4Y_\\mathsf{Vanish5}}{(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4Y_\\mathsf{Vanish5}}{(\\zeta^]kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Acc_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$ and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\tau)$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Acc_1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, and $g^{\\mathsf{Poly}_\\mathsf{Acc_2}(\\tau)}$ to write as the commitments $K_\\mathsf{Arr_1}$, $ K_\\mathsf{Acc_1}$, $K_\\mathsf{Arr_2}$, and $ K_\\mathsf{Acc_2}$. $\\mathcal{S}$ then generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Acc_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$ and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\tau)$. $\\mathcal{S}$ writes the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the second random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_1}(\\zeta\\omega)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Acc_2}(\\zeta\\omega)$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} + \\rho^2 Y_\\mathsf{Vanish3} + \\rho^3 Y_\\mathsf{Vanish4} + \\rho^4Y_\\mathsf{Vanish5}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\nFor mult2, the proof is written with a simulator that doesn\u0026rsquo;t know the trapdoor; however, with small alterations the proof for mult2 should apply here and vice versa "},{"id":14,"href":"/docs/gadgets/range/","title":"Range","section":"Gadgets","content":" Range # Recap of types # Type Description Recap This range $\\mathsf{Arr}[i]\\in[0,r]$ Each element of array $\\mathsf{Arr}$ is in the range $[0,r]$ ✅ Relation # $\\mathcal{R}_{\\mathtt{add1}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr}) \\end{array} \\middle | \\begin{array}{l} 0\\le{\\mathsf{Arr}[i]}\\le{r}, i\\in[0,n), \\\\ \\mathsf{Poly}_\\mathsf{Arr}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}), \\end{array} \\right\\}$\nIntuition # To prove each element of array $\\mathsf{Arr}$ is in the range $[0,r]$, one of the most intuitive ways is we create a vector containing the numbers from $0$ to $r$ and run the lookup argument for $\\mathsf{Arr}$. Another approach is we prove each element is in $[0,r]$. Specifically, we decompose the target number to digits in some base $x$ and prove (i) the digits are valid and (ii) the number can be recovered from the digits and the base. The prover ($\\mathcal{P}$) holds a number $\\eta$ and a vector $\\mathsf{T}$ of $k=\\lceil\\log_x{\\eta}\\rceil$ integers from $\\mathbb{Z}_q$: $[a_0,a_1,a_2,\\dots,a_{k-1}]$. Then $r=x^k$ and the prover shows $\\eta \\in [0, r]$. It will produce a succinct (logarithm base $x$ of $\\eta$; for simplicity, we will use base $2$) proof that the vector $\\mathsf{T}$ satisfies the following conditions: (i) the first value of $\\mathsf{T}$ equals to $\\eta$ (ii) the last value of $\\mathsf{T}$ equals to one or zero (iii) any value minus two times the next value is equal to one or zero in $\\mathsf{T}$. The prover will encode $\\mathsf{Arr}$ and $\\mathsf{T}$ into two polynomials: $\\mathsf{Poly}_\\mathsf{Arr}$ and $\\mathsf{Poly}_\\mathsf{T}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$). It will commit to each polynomial: $K_\\mathsf{Arr}$ and $K_\\mathsf{T}$. The verifier ($\\mathcal{V}$) cannot check any of the $\\mathsf{Arr}$, $\\mathsf{T}$ or $\\mathsf{Poly}_\\mathsf{Arr}$, $\\mathsf{Poly}_\\mathsf{T}$ values directly. Instead the verifier only sees $K_\\mathsf{Arr}$, and $K_\\mathsf{T}$.\nConsider a small numerical example where $\\eta = 14$, working with $x=2$. Since $k=\\lceil\\log_2{\\eta}\\rceil = 4$, we will demonstrate that $\\eta \\in [0,r=2^k]$ by constructing $\\mathsf{Arr}$ consisting of $k$ integers. First, we know $\\mathsf{T}[0] = \\eta = 14$:\n$\\mathsf{T} = [14, \\bot, \\bot, \\bot]$ Now, for $\\mathsf{T}[1]$ we want an integer $a_1$ such that $14 - 2\\cdot a_1$ equals 1 or 0. Since 14 is even, we are looking for $a_1$ such that $14 - 2\\cdot a_1=0$, thus $a_1=7$:\n$\\mathsf{T} = [14, 7, \\bot, \\bot]$ Now we find $a_2$ such that $7-2\\cdot a_2$ equals 1 or 0. Since 7 is odd, we are looking for $a_2$ such that $7-2\\cdot a_2=1$, thus $a_2 = 3$:\n$\\mathsf{T} = [14, 7, 3, \\bot]$ Finally, we find $a_3$ such that $3 - 2\\cdot a_3$ equals 1 or 0. Again, since 3 is odd, we are looking for $a_3$ such that $3-2\\cdot a_3=1$, thus $a_3= 1$:\n$\\mathsf{T} = [14, 7, 3, 1]$ Now, $\\mathsf{Arr}$ is $k$ elements long, and the last element of $\\mathsf{T}$ is one or zero, so we have constructed the desired vector $\\mathsf{T}$. Note that the last element of $\\mathsf{T}$ will only be zero if $\\eta \\leq x^{k-1}$.\nIn order to prove $K_\\mathsf{Arr}$ and $K_\\mathsf{T}$ satisfy the above three conditions, one of the most straightforward methods is to use the additive homomorphic property of the KZG commitment scheme, i.e., prove $K_\\mathsf{Arr}$ and $K_\\mathsf{T}$ satisfy the conditions through the group addition. This method works if the target condition only involves additive operations. However, there are multiplications in the above conditions, so it is infeasible to calculate the product of two KZG commitments unless the t-SDH can be solved. Even if the verifier is given the powers of the KZG commitments, it is inefficient to perform scalar multiplications for two commitments (imagine the time complexity of multiplying two $d$-degree polynomials is $O(d^2)$), which implies this method is hard to be succinct.\nThe second method is more general and widely used. The basic idea is instead of proving the commitments satisfy the conditions, the prover reveals the evaluations of the polynomials at a random point sent by the verifier to prove the evaluations satisfy the conditions; at the same time, the prover proves the evaluations are valid through the binding property of KZG commitment. This method works because of the Schwartz-Zippel lemma, which tells us if the equation (of the polynomials) holds at a random evaluation point on the domain $\\mathcal{H}_\\kappa$, then it holds at any point on $\\mathcal{H}_\\kappa$ with high probability. The probability is $d/|\\mathbb{F}|$, where $d$ is the number of roots of the equation and $\\mathbb{F}$ is the field of the random evaluation point. This means as long as the field is big enough, the probability of failure is negligible. By rearranging the polynomials, the verifier can challenge any point on the group field rather than $\\mathcal{H}_\\kappa$, which makes the probability of failure tend to $0$.\nProtocol Details # Array Level # $\\mathcal{P}$ holds a number $\\eta\\in\\mathbb{Z}$ $\\mathcal{P}$ computes or holds an array $\\mathsf{T}=[t_0,t_1,t_2,\\dots,t_{k-1}]$ of $k$ (recall $k=\\lceil\\log_2{\\eta}\\rceil$) integers ($t_i\\in\\mathbb{Z}$) such that: $\\mathsf{T}[0]=\\eta$ $\\mathsf{T}[k-1]\\in\\{0,1\\}$ $\\mathsf{T}[i]-2\\cdot\\mathsf{T}[i+1]\\in\\{0,1\\}$ Polynomial Level # We assume the array $\\mathsf{T}$ is encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the array, the array can be padded with elements of value 0 (which will not change the sum).\nRecall the constraints we want to prove:\n$\\mathsf{T}[0]=\\eta$ $\\mathsf{T}[k-1]\\in\\{0,1\\}$ $\\mathsf{T}[i]-2\\cdot\\mathsf{T}[i+1]\\in\\{0,1\\}$ In polynomial form, the constraints are:\nFor $X=\\omega^0$: $\\mathsf{Poly}_\\mathsf{T}(X)=\\eta$ For $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{T}(X)\\in\\{0,1\\}$ For all $X=\\mathcal{H}_\\kappa\\setminus{\\omega^{\\kappa-1}}$: $\\mathsf{Poly}_\\mathsf{T}(X)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega)\\in\\{0,1\\}$ Note because the value of $\\eta$ is a secret, $\\mathcal{P}$ will not reveal $\\eta$ to let $\\mathcal{V}$ verify $\\eta$ is the evaluation of $\\mathsf{Poly}_\\mathsf{T}(\\omega^0)$. $\\mathcal{P}$ will leverage the hiding property of KZG (Pedersen) commitment to prove the committed $\\eta$ is the correct evaluation. Specifically, $\\mathcal{P}$ claims the committed $\\eta$ is the correct one and opens $\\mathsf{Poly}_\\mathsf{T}$ at $\\omega^0$. If the committed $\\eta$ satisfy the KZG verification, $\\mathcal{V}$ can believe the first constraint is satisfied.\nWe take care of the \u0026ldquo;for $X$\u0026rdquo; conditions of constraints 2 and 3 by zeroing out the rest of the polynomial that is not zero. See the gadget zero1 for more on why this works.\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)=\\mathsf{Poly}_\\mathsf{T}(X)\\cdot[\\mathsf{Poly}_\\mathsf{T}(X)-1]\\cdot\\frac{X^\\kappa-1}{X-\\omega^{\\kappa-1}}=0$ $\\mathsf{Poly}_\\mathsf{Vanish2}(X)=[\\mathsf{Poly}_\\mathsf{T}(X)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(X)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega)-1]\\cdot(X-\\omega^{\\kappa-1})=0$ The two equations are vanishing for every value of $X\\in\\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa-1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish1}(X)$ and $\\mathsf{Poly}_\\mathsf{Vanish2}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$, and $Q_2(X)$ with a single polynomial $Q(X)$. We can do this because all three constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with all three $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if all three are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)-Q(X)\\cdot(X^{\\kappa-1}-1)=0$\nUltimately the range gadget will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{T}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) are too large to examine and maintain a succinct proof system. Instead, the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{T}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{T}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a second random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta)$ $\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)=\\mathsf{KZG.Open}(K_\\mathsf{T},\\zeta\\omega)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}=\\mathsf{Poly}_\\mathsf{T}(\\zeta)\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-1]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^{\\kappa-1}}$ $Y_\\mathsf{Vanish2}=[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)-1]\\cdot(\\zeta-\\omega^{\\kappa-1})$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1}+\\rho\\cdot{Y_\\mathsf{Vanish2}}-Q(\\zeta)\\cdot(\\zeta^\\kappa-1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\rho$ and $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who runs the protocol with $\\eta$ such that $\\eta \\in [0,r]$, can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish1}+\\rho\\cdot{Y_\\mathsf{Vanish2}}-Q(\\zeta)\\cdot(\\zeta^\\kappa-1)$\n$= \\mathsf{Poly}_\\mathsf{T}(\\zeta)\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-1]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^{\\kappa-1}} +[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)-1]\\cdot(\\zeta-\\omega^{\\kappa-1}) -Q(\\zeta)\\cdot(\\zeta^\\kappa-1)$\n$= \\mathsf{Poly}_\\mathsf{T}(\\zeta)\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-1]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^{\\kappa-1}} +[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)-1]\\cdot(\\zeta-\\omega^{\\kappa-1}) \\newline -\\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta)}{\\zeta^n - 1}\\cdot(\\zeta^\\kappa-1)$\n$= \\mathsf{Poly}_\\mathsf{T}(\\zeta)\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-1]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^{\\kappa-1}} +[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)-1]\\cdot(\\zeta-\\omega^{\\kappa-1}) \\newline - [\\mathsf{Poly}_\\mathsf{T}(\\zeta)\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-1]\\cdot\\frac{\\zeta^\\kappa-1}{\\zeta-\\omega^{\\kappa-1}} +[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(\\zeta)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(\\zeta\\omega)-1]\\cdot(\\zeta-\\omega^{\\kappa-1})]$\n$=0$\nWhere the third equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(X)+\\rho\\cdot\\mathsf{Poly}_\\mathsf{Vanish2}(X)$ is divisible by $X^\\kappa -1$. This is true if $\\mathsf{Poly_{Vanish1}}(\\zeta)$ and $\\mathsf{Poly_{Vanish2}}(\\zeta)$ are vanishing on $\\mathcal{H}_\\kappa$, i.e. if both of the following conditions hold:\n$ \\mathsf{Poly}_\\mathsf{T}(X)\\cdot[\\mathsf{Poly}_\\mathsf{T}(X)-1]\\cdot\\frac{X^\\kappa-1}{X-\\omega^{\\kappa-1}}=0$ $ [\\mathsf{Poly}_\\mathsf{T}(X)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega)]\\cdot[\\mathsf{Poly}_\\mathsf{T}(X)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega)-1]\\cdot(X-\\omega^{\\kappa-1})=0$ These conditions, in turn, hold if:\nFor $X=\\omega^0$: $\\mathsf{Poly}_\\mathsf{T}(X)=\\eta$ For $X=\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{T}(X)\\in\\{0,1\\}$ For all $X=\\mathcal{H}_\\kappa\\setminus{\\omega^{\\kappa-1}}$: $\\mathsf{Poly}_\\mathsf{T}(X)-2\\cdot\\mathsf{Poly}_\\mathsf{T}(X\\omega)\\in\\{0,1\\}$ Where we get the \u0026ldquo;For $X$\u0026rdquo; due to zeroing parts of the polynomials (see zero1). Since $\\mathsf{Poly_T}(\\omega^i) = \\mathsf{Arr_T}[i] \\space \\forall i \\in [0, \\kappa - 1]$, the above conditions are true if:\n$\\mathsf{T}[0]=\\eta$ $\\mathsf{T}[k-1]\\in\\{0,1\\}$ $\\mathsf{T}[i]-2\\cdot\\mathsf{T}[i+1]\\in\\{0,1\\}$ Which are precisely the conditions we described in the intuition section that a honest prover will obey when encoding $\\eta$. Thus, the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and its transcipt will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g,g^\\tau,g^{\\tau^2},\\dots,g^{\\tau^{n-1}}]$, $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{T}(X)$ and $Q$ $\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{T}(X)$ and $Q$ $\\mathcal{A}$ plays the part of the prover in showing that $Y_\\mathsf{Zero}$ is zero at a random challenge $\\zeta$ $\\mathcal{A}$ wins if $\\mathcal{V}$ accepts at the end of the protocol $\\eta\\notin[0,r]$ Our proof is as follows:\nFirst, we prove $\\eta\\ge{0}$. To make $\\mathsf{Poly}_\\mathsf{Vanish1}$ exist, the last value of $\\mathsf{T}$ must be zero or one. From $\\mathsf{Poly}_\\mathsf{Vanish2}$, it can be observed that $\\mathsf{T}[i]\\ge\\mathsf{T}[i+1]$ for all $i\\in[0,\\kappa-2]$. Thus, $\\mathsf{T}[0]$ is equal to or greater than $\\mathsf{T}[\\kappa-1]$, i.e., $\\eta\\ge{0}$.\nSecond, we prove $\\eta\\le{r}$. For simplicity, we assume $r$ is the power of two (recall $\\kappa=\\log_2{r}$). From $\\mathsf{Poly}_\\mathsf{Vanish2}$, we know $\\mathsf{T}[0]$ is less than or equal to $2^\\kappa$. Therefore, $\\eta\\le{r}$.\nZero-Knowledge # To prove the above protocol is zero-knowledge, we do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ randomly generates an $\\eta^*$, then follows the same steps a prover would prove the lookup argument. $\\mathcal{S}$ computes $\\mathsf{T^*}$ and interpolates $\\mathsf{Poly}_\\mathsf{T^*}$ from $\\mathsf{T^*}$. It computes $Q^*(X)$ and finally outputs the commitments to each of these polynomials (and writes the commitments to the transcript). Then, it generates the random challenge $\\zeta^*$ (once again this is by strong Fiat-Shamir). It creates opening proofs for $\\mathsf{Poly}_\\mathsf{T^*}(\\zeta^*),\\mathsf{Poly}_\\mathsf{T^*}(\\zeta^*\\omega)$, and $Q^*(\\zeta^*)$, and writes these to the transcript as well. Since $\\mathcal{S}$ knows each of the above polynomials, it can honestly compute this step and the proof will be accepted by $\\mathcal{V}$. The transcript it generates this way will be indistinguishable from a transcript generated from a real execution since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":15,"href":"/docs/gadgets/rotate/","title":"Rotate","section":"Gadgets","content":" Rotate # Recap of types # $ \\mathcal{R}_{\\mathtt{rotate}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr}, K_\\mathsf{Arr'}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}],\\\\ \\mathsf{Arr'}[i] = \\mathsf{Arr}[i +\\alpha], \\\\ \\mathsf{Poly}_\\mathsf{Arr}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}),\\\\ \\mathsf{Poly}_\\mathsf{Arr'}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr'}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}),\\\\ K_\\mathsf{Arr'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr'}),\\\\ \\end{array} \\right\\} $\nIntuition # Assume $\\mathsf{Arr}$ is an array of data of size $n$. It is encoded as the y-coordinates into univariant polynomials where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. We call our polynomial $\\mathsf{Poly}_\\mathsf{Arr}(X)$. The goal is to construct an output polynomial $\\mathsf{Poly_\\mathsf{Arr'}}$ where all the elements in $\\mathsf{Arr}$ have been rotated by $\\alpha$ positions; i.e. $\\mathsf{Arr'}[i] \\leftarrow \\mathsf{Arr}[i + \\alpha]$. Here, the index is defined mod $n$.\nWritten in terms the polynomials, the goal is that $\\mathsf{Poly_\\mathsf{Arr'}}(\\omega^i) = \\mathsf{Poly_\\mathsf{Arr}}(\\omega^i\\cdot\\omega^\\alpha)$ for all $i \\in [0, n-1]$. To this end, we define $\\mathsf{Poly_\\mathsf{Arr}}(X) = \\mathsf{Poly_\\mathsf{Arr}}(X)\\cdot\\omega^\\alpha$ and demonstrate below why this satisfies the requirements of the output polynomials.\nConsider $\\mathsf{Poly_\\mathsf{Arr}}(X) = c_{n-1}X^{n-1} + \\dots + c_2X^2 + c_1X + c_0$. Then:\n$\\mathsf{Poly_\\mathsf{Arr'}}(X)$\n$= \\mathsf{Poly_Arr}(X) \\cdot \\omega^\\alpha$\n$= (c_{n-1}X^{n-1} + \\dots + c_2X^2 + c_1X + c_0)(\\omega^\\alpha) $\n$= c_{n-1}X^{n-1}\\cdot\\omega^\\alpha + \\dots + c_2X^2\\cdot\\omega^\\alpha + c_1X\\cdot\\omega^\\alpha + c_0\\cdot\\omega^\\alpha$\n$= \\mathsf{Poly_\\mathsf{Arr}}(X\\cdot\\omega^\\alpha)$\nIn particular, $\\mathsf{Poly_{Arr'}}(\\omega^i) = \\mathsf{Poly_\\mathsf{Arr}}(\\omega^i\\cdot\\omega^\\alpha)$ for $i \\in [0, n-1]$. We also note that $\\omega^n = \\omega^0$, since $\\omega$ is of order $\\kappa$. Thus the exponent of $\\omega$ is defined mod $n$, like the indexing of $\\mathsf{Arr}$. This means that $\\omega^i\\cdot\\omega^\\alpha$ wraps around to have the rotation defined as it should be for $i + \\alpha \\gt n-1$.\nTo prove the relation between $\\mathsf{Arr}$ and $\\mathsf{Arr'}$, the prover must commit to the two polynomials, $\\mathsf{Poly_{Arr}}$ and $\\mathsf{Poly_{Arr'}}$ as $K_{\\mathsf{Arr}}$ and $K_\\mathsf{Arr'}$. The verifier ($\\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$. The relation will be proven by showing $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$ and consistent; this mean verifying that $\\mathsf{Arr'}[i] \\leftarrow \\mathsf{Arr}[i + \\alpha]$.\nProtocol Details # Array Level # * $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers ($a_{i} \\in \\mathbb{Z}_q$)\n* $\\mathcal{P}$ holds or computes $\\mathsf{Arr}'$ such that:\n* $\\mathsf{Arr}'[i]= \\mathsf{Arr}[i+\\alpha]$ for $i \\in [0, n-1]$\nPolynomial Level # We assume that $\\mathsf{Arr}$ and $\\mathsf{Arr'}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the arrays, then $\\mathsf{Arr}$ can be padded with any value (say, all 1s) as long as this is done before the rotation to create $\\mathsf{Arr'}$ is computed.\nRecall the constrant we want to prove:\n$\\mathsf{Arr}'[i]= \\mathsf{Arr}[i+\\alpha]$ for $i \\in [0, n-1]$ We write the constraint in polynomial form:\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr'}(X) = \\mathsf{Poly}_\\mathsf{Arr}(X)\\cdot\\omega^\\alpha$ We adjust the constraint to show an equality with 0 and label it:\n$\\mathsf{Poly}_\\mathsf{Vanish}(X)= \\mathsf{Poly}_\\mathsf{Arr'}(X) - \\mathsf{Poly}_\\mathsf{Arr}(X)\\cdot\\omega^\\alpha = 0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide the polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotient is polynomial (and not a rational function), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish}(X)}{X^\\kappa - 1}$ By rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the rotate argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr}(X)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial Commitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}(X))$\n$K_\\mathsf{Arr'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr'}(X))$\n$K_Q=\\mathsf{KZG.Commit}(Q(X))$\nThe prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$\n$\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr},\\zeta)$\n$$\\mathsf{Poly}\\mathsf{Arr\u0026rsquo;}(\\zeta)=\\mathsf{KZG.Open}(K\\mathsf{Arr\u0026rsquo;},\\zeta)$\n$Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$\nTo check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish}= \\mathsf{Poly}_\\mathsf{Arr'}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr}(\\zeta)\\cdot\\omega^\\alpha$\n$Y_\\mathsf{Zero}=Y_\\mathsf{Vanish} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\nFinally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Security Proof # Completeness # If $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr'}$ and $\\mathsf{Arr}$ such that $\\mathsf{Arr'}[i] = \\mathsf{Arr}[i +\\alpha] \\space \\forall i \\in [0, n-1]$ can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$ = Y_\\mathsf{Vanish} - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$ = \\mathsf{Poly_{Arr'}}(\\zeta) - \\mathsf{Poly_{Arr}}(\\zeta)\\cdot \\omega^\\alpha - Q(\\zeta)(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly_{Arr'}}(\\zeta) - \\mathsf{Poly_{Arr}}(\\zeta)\\cdot \\omega^\\alpha - \\frac{\\mathsf{Poly_{Vanish}}(\\zeta)}{\\zeta^\\kappa - 1}\\cdot(\\zeta^\\kappa - 1)$\n$= \\mathsf{Poly_{Arr'}}(\\zeta) - \\mathsf{Poly_{Arr}}(\\zeta)\\cdot \\omega^\\alpha - \\mathsf{Poly_{Arr'}}(\\zeta) + \\mathsf{Poly_{Arr}}(\\zeta)\\cdot \\omega^\\alpha$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly_{Vanish}}(X)$ is divisible by $X^\\kappa - 1$. This is true if $\\mathsf{Poly_{Vanish}}(X)$ is vanishing on $\\mathcal{H_\\kappa}$, i.e. if $\\mathsf{Poly}_\\mathsf{Arr'}(X) - \\mathsf{Poly}_\\mathsf{Arr}(X)\\cdot\\omega^\\alpha = 0 \\space \\forall X \\in \\mathcal{H_\\kappa}$. This is true if $\\mathsf{Poly}_\\mathsf{Arr'}(X) - \\mathsf{Poly}_\\mathsf{Arr}(X\\cdot\\omega^\\alpha) = 0 \\space \\forall X \\in \\mathcal{H_\\kappa}$, which is in turn true if $\\mathsf{Arr'}[i] - \\mathsf{Arr}[i + \\alpha] = 0 \\space \\forall i \\in [0, \\kappa -1]$, since $\\mathsf{Poly_Arr}(\\omega^i)=\\mathsf{Arr}[i] \\space \\forall i \\in [0, \\kappa -1]$. But $\\mathsf{Arr'}[i] - \\mathsf{Arr}[i + \\alpha] = 0 \\space \\forall i \\in [0, n-1]$ is precisely the relation between $\\mathsf{Arr'}$ and $\\mathsf{Arr}$ that we assumed held for our prover (if $\\kappa \\gt n$ then the arrays get padded such that this relation still holds), thus the $Y_\\mathsf{Zero}(X)$ it creates by following the protocol is the zero polynomial, and its transcipt will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$, the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{Arr'}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr}(X)$, $\\mathsf{Poly}_\\mathsf{Arr'}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Arr'}[i] \\neq \\mathsf{Arr}[i + \\alpha]$ for some $i \\in [0, n-1]$\nOur proof is as follows:\nFor the second win condition to be fulfilled, there must be some $i \\in [0, n-1]$ such that $\\mathsf{Arr'}[i] \\neq \\mathsf{Arr}[i + \\alpha]$. But then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Arr}(X)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(X)$. All commitments $\\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)$ and $\\mathsf{Poly}_\\mathsf{Arr'}(\\zeta)$ can each only feasibliy be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}} {(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr}(\\tau)}$ and ${\\mathsf{Poly}_\\mathsf{Arr'}(\\tau)}$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr}(\\tau)}$ and $g^{\\mathsf{Poly}_\\mathsf{Arr'}(\\tau)}$ to write as the commitments $ K_\\mathsf{Arr}$ and $K_\\mathsf{Arr'}$. $\\mathcal{S}$ computes $Q(\\tau)$ using the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr}(\\tau)}$ and ${\\mathsf{Poly}_\\mathsf{Arr'}(\\tau)}$. $\\mathcal{S}$ writes the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr}(\\zeta)}$ and ${\\mathsf{Poly}_\\mathsf{Arr'}(\\zeta)}$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":16,"href":"/docs/gadgets/shuffle1/","title":"Shuffle1","section":"Gadgets","content":" Shuffle (Type 1) # Recap of types # Type Description Recap This shuffle1 $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1)$ Array $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ for some undisclosed permutation $\\pi$. ✅ shuffle2 $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1 ,\\pi)$ Array $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ under a disclosed permutation $\\pi$. Relation # $ \\mathcal{R}_{\\mathtt{shuffle1}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr2}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}],\\\\ \\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}], \\\\ \\mathsf{Poly}_\\mathsf{Arr_1}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_1}), \\\\ \\mathsf{Poly}_\\mathsf{Arr_2}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_2}), \\\\ K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}),\\\\ K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}), \\end{array} \\right\\} $\nIntuition # The prover ($\\mathcal{P}$) holds 2 arrays, $\\mathsf{Arr_1 }$ and $\\mathsf{Arr_2}$, of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It will produce a succinct (independent of $n$) proof that $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ for some undisclosed permutation $\\pi$. The prover will encode the two arrays into polynomials, $\\mathsf{Poly}_\\mathsf{Arr_1}$ and $\\mathsf{Poly}_\\mathsf{Arr_2}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to them as $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$. The verifier ($\\mathcal{V}$) cannot check either array directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_2}$.\nOne idea to check that $\\mathsf{Arr_2}$ is a permutation of $\\mathsf{Arr_1}$ might be to perform a product check on the two arrays. If the permutation relation holds, then the products will be equal; however, many arrays can have their entries multiply to the same number, without necessarily containing the same elements.\nInstead, the prover constructs two new arrays, $\\mathsf{Arr_1}'$ and $\\mathsf{Arr_2}'$, where $\\mathsf{Arr_j}'$ contains the points $ \\{r - \\mathsf{Arr_j}[i] \\}_{i \\in [0, n-1]}$ for $r$ a random field element. Then, a product check is run on these two arrays. One way to understand why this works is to think of it as creating two auxilary polynomials, ${\\mathsf{Poly}}_\\mathsf{Arr_1'}$ and ${\\mathsf{Poly}}_\\mathsf{Arr_2'}$, where $\\mathsf{Poly}_\\mathsf{Arr_j'}(X) = \\prod^{n-1}_{i = 1}(X - \\mathsf{Arr_j}[i])$. If ${\\mathsf{Poly}}_\\mathsf{Arr_1'}$ = $\\mathsf{Poly}_\\mathsf{Arr_2'}$, then they have the same factorization. This means that $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ must contain the same elements (in possibly different orders); in other words, $\\mathsf{Arr}_2$ is a permutation of $\\mathsf{Arr}_1$. To check this equality, a random challenge point $r$ is generated and the products are checked at that point. If they are equal at that point then (with overwhelming probabiltiy) the polynomials are equal.\nIn addition to demontrasting the equality of the product of $\\mathsf{Arr_1}'$ and $\\mathsf{Arr_2}'$, it must also be shown that these two arrays are defined correctly in terms of the original arrays. In other words, it must be shown that $\\mathsf{Arr_j}'[i]= r - \\mathsf{Arr_j}[i]$ for $i \\in [0, n-1]$. Once this, in addition to the product check, has been done, we have shown that $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ for some undisclosed permutation $\\pi$.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ generates the random challenge $r$ and computes $\\mathsf{Arr_j}'$ as follows for $j \\in [1,2]$: $\\mathsf{Arr_j}'[i]= r - \\mathsf{Arr_j}[i]$ Polynomial Level # We assume that $\\mathsf{Arr_1}$, $\\mathsf{Arr_2}$, $\\mathsf{Arr_1'}$, and $\\mathsf{Arr_2'}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the arrays, the arrays can be padded with elements all of value 1 (or any other value, as long as it is the same for both arrays).\nRecall the two steps we want to prove:\n$\\prod^{n-1}_{i=0}\\{r - \\mathsf{Arr_1[i]}\\} = \\prod^{n-1}_{i=0}\\{r - \\mathsf{Arr_2[i]}\\}$ $\\mathsf{Arr_j}'[i]= r - \\mathsf{Arr_j}[i]$ for $j \\in [1,2]$, $0 \\leq 1 \\leq n-1$ The first step is done as a mult3 product check, and we write the second step as two constraints in polynomial form. From this point on we focus on the polynomial details of the second step.\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_1'}(X) = (r - \\mathsf{Poly}_\\mathsf{Arr_1}(X))$ For all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_2'}(X) = (r - \\mathsf{Poly}_\\mathsf{Arr_2}(X))$ We adjust each of these constraints to show an equality with 0 and label them:\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)= \\mathsf{Poly}_\\mathsf{Arr_1'}(X) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(X)) = 0$ $\\mathsf{Poly}_\\mathsf{Vanish2}(X)= \\mathsf{Poly}_\\mathsf{Arr_2'}(X) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(X)) = 0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$ and $Q_2(X)$ with a single polynomial $Q(X)$. We can do this because both constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with both $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if both are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho}{X^\\kappa - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(X) - Q(X)\\cdot (X^\\kappa - 1)=0$\nUltimately the shuffle1 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial In addition, it will show that $\\prod^{n-1}_{i=0}(r - \\mathsf{Arr_1}[i]) = \\prod^{n-1}_{i=0}(r - \\mathsf{Arr_2}[i])$ using a mult3 product check.\nCommitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will create a transcript for the product check, as decribed in mult3. Below, we give details specific to the second step, showing that $\\mathsf{Arr_j}'[i]= r - \\mathsf{Arr_j}[i]$ for $j \\in [1,2]$, $0 \\leq 1 \\leq n-1$.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$ $K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call this point $r$. It will use this point to define the sets $ \\{r - \\mathsf{Poly}_\\mathsf{Arr_j}(a) \\}_{a \\in \\mathcal{H}_\\kappa}$ and run the product check. It will write the product check into the transcript. However, here we focus only on what is relevant to the second step, the point $r$ and the following polynomials, which it also writes to the transcript:\n$r$ $K_\\mathsf{Arr_1'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1'}(X))$ $K_\\mathsf{Arr_2'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2'}(X))$​ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1'},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2'},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}= \\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))$ $Y_\\mathsf{Vanish2}= \\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Security Proof # Completeness # We assume completeness of the product check (it is proven in mult3) and conduct a proof of completeness for the rest of the protocol.\nIf $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ such that $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1)$, can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))] + \\rho [\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))] - Q(\\zeta) \\cdot (\\zeta^\\kappa - 1)$\n$= [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))] + \\rho [\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))] - \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta)}{X^\\kappa - 1} \\cdot (\\zeta^\\kappa - 1)$\n$= [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))] + \\rho [\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))] - [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)) + \\rho[\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))]]$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(X)$ is divisible by $X^\\kappa -1$. This is true if $\\mathsf{Poly_{Vanish1}}(\\zeta)$ and $\\mathsf{Poly_{Vanish2}}(\\zeta)$ are vanishing on $\\mathcal{H}_\\kappa$, i.e. if $\\mathsf{Poly}_\\mathsf{Arr_1'}(X) - (r - \\mathsf{Poly}_\\mathsf{Arr_1}(X)) = 0$ and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X) - (r - \\mathsf{Poly}_\\mathsf{Arr_2}(X)) = 0$, $X \\in \\mathcal{H}_\\kappa$. This is true if $\\mathsf{Arr}_1'[i] - (r - \\mathsf{Arr}_1[i]) = 0$ and $\\mathsf{Arr}_2'[i] - (r - \\mathsf{Arr}_1[i]) = 0$, $\\forall 0 \\leq i\\leq \\kappa$, since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$ and $\\mathsf{Poly_j}'(\\omega^i) = \\mathsf{Arr_j}'[i] \\space \\forall i \\in [0, \\kappa - 1]$. But this is precisely how the honest prover defines $\\mathsf{Arr}_1'$ and $\\mathsf{Arr}_2'$, so the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and the transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). We assume soundness of the product check (it is proven in mult3) and conduct a proof of soundness for the rest of the protocol. To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$, the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Arr}_2 \\neq \\mathsf{Permute}(\\mathsf{Arr}_1)$\nOur proof is as follows:\nFor the second win condition to be fulfilled, there must be some $a \\in \\mathsf{Arr_2}, a \\notin \\mathsf{Arr_1}$, or vice versa. Since $\\mathsf{Arr_1}$ and $\\mathsf{Arr_2}$ have different entries, $\\prod^{n-1}_{i = 1}(X - \\mathsf{Arr_1}[i])$ and $\\prod^{n-1}_{i = 1}(X - \\mathsf{Arr_2}[i])$ have different factorizations and are thus different polynomials. By the Schwartz-Zippel lemma, there is negligible probability that they are equal at $r$ (thus the product check will fail). Any strategy to increase this probability to greater than negligible means $\\mathcal{A}$ must pass in $\\mathsf{Arr_j'}$ such that $\\mathsf{Arr_j'}[i] \\neq r - \\mathsf{Arr_j}[i]$ for some index $i$ and $j \\in [1, 2]$. But then $\\mathsf{Poly}_\\mathsf{Vanishj}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$. All commitments $\\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta)$ can each only feasibliy be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2}}{(\\zeta^\\kappa - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2}}{(\\zeta^\\kappa - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We assume the product check is zero-knowledge (it is proven in mult3), and conduct a proof for the rest of the protocol. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$ and ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$ and $g^{\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$ to write as the commitments $ K_\\mathsf{Arr_1}$ and $K_\\mathsf{Arr_1}$. $\\mathcal{S}$ then generates the random challenge $r$ (by strong Fiat-Shamir). It chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1'}(\\tau)}$ and ${\\mathsf{Poly}_\\mathsf{Arr_2'}(\\tau)}$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1'}(\\tau)}$ and $g^{\\mathsf{Poly}_\\mathsf{Arr_2'}(\\tau)}$ to write as the commitments $ K_\\mathsf{Arr_1'}$ and $K_\\mathsf{Arr_1'}$. It creates a view of the product check as described in the zero-knowledge proof for mult3.\n$\\mathcal{S}$ generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_1'}(\\tau)}$, and ${\\mathsf{Poly}_\\mathsf{Arr_2'}(\\tau)}$. $\\mathcal{S}$ outputs the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the random challenge point $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta)}$, and ${\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta)}$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2}}{(\\zeta^\\kappa - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":17,"href":"/docs/gadgets/shuffle2/","title":"Shuffle2","section":"Gadgets","content":" Shuffle (Type 2) # Recap of types # Type Description Recap This shuffle1 $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1)$ Array $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ for some undisclosed permutation $\\pi$. shuffle2 $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1 ,\\pi)$ Array $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ under a disclosed permutation $\\pi$. ✅ Relation # $\\mathcal{R}_{\\mathtt{shuffle2}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr_1},K_\\mathsf{Arr2}, K_\\pi) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}],\\\\ \\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}], \\\\ \\mathsf{Arr_\\pi} = [\\pi(\\omega^0), \\pi(\\omega^1), \\pi(\\omega^2), \\dots, \\pi(\\omega^{n-1})], \\\\ \\mathsf{Poly}_\\mathsf{Arr_1}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_1}), \\\\ \\mathsf{Poly}_\\mathsf{Arr_2}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr_2}), \\\\ \\mathsf{Poly_\\pi} = \\mathsf{FFT.Interp}(\\omega, \\mathsf{Arr_\\pi}), \\\\ K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}),\\\\ K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}),\\\\K_\\pi = \\mathsf{KZG.Commit(Poly_{\\pi})} \\end{array} \\right\\}$\nIntuition # The prover ($\\mathcal{P}$) holds 2 arrays, $\\mathsf{Arr_1 }$ and $\\mathsf{Arr_2}$, of $n$ integers from $\\mathbb{Z}_q$: $[a_0, a_1, a_2, \\dots, a_{n-1}]$. It also holds an array $\\mathsf{Arr_\\pi}$, which represents the disclosed permutation $\\pi$. It will produce a succinct (independent of $n$) proof that $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ under the disclosed permutation $\\pi$. The prover will encode the three arrays into polynomials, $\\mathsf{Poly}_\\mathsf{Arr_1}$, $\\mathsf{Poly}_\\mathsf{Arr_2}$, and $\\mathsf{Poly_\\pi}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to them as $K_\\mathsf{Arr_1}$, $K_\\mathsf{Arr_2}$, and $K_\\pi$. The verifier ($\\mathcal{V}$) cannot check any array directly ($\\mathsf{Arr_1 }$ and $\\mathsf{Arr_2}$ may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr_1}$, $K_\\mathsf{Arr_2}$ and $K_\\pi$.\nThe idea behind this check is that if $(\\mathsf{Arr_\\pi}[i], \\mathsf{Arr_2}[i]) = (i, \\mathsf{Arr_1}[i])$ for all $0 \\leq i \\leq n-1$, then $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1 ,\\pi)$. To gain some intuition on why this is true, pair up tuples from the left and right hand sides of the equation by matching the first entries. Then, if each pair is equal, it means that $\\mathsf{Arr_2}[i] = \\mathsf{Arr_1}[\\mathsf{Arr_\\pi}[i]]$ for $0 \\leq i \\leq n-1$. In other words, $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1 ,\\pi)$.\nTo check that $(\\mathsf{Arr_\\pi}[i], \\mathsf{Arr_2}[i]) = (i, \\mathsf{Arr_1}[i])$ for all $0 \\leq j \\leq n-1$, we use a similar trick to shuffle1. The prover constructs two arrays: $\\mathsf{Arr_1'} = \\{ r - s\\cdot i - \\mathsf{Arr_1}[i]\\}_{i \\in [0, n-1]}$ and $\\mathsf{Arr_2'} = \\{ r - s\\cdot\\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i]\\}_{i \\in [0, n-1]}$ for random field elements $r, s$. Then, a product check is conducted on the two arrays. One way to understand why this works is to think of it as creating two auxilary polynomials, ${\\mathsf{Poly}}_\\mathsf{Arr_1'}$ and ${\\mathsf{Poly}}_\\mathsf{Arr_2'}$. Here, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X) = \\prod^{n-1}_{i = 1}(X - Y\\cdot i - \\mathsf{Arr_1}[i])$ and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X) = \\prod^{n-1}_{i = 1}(X - Y\\cdot \\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i])$. If ${\\mathsf{Poly}}_\\mathsf{Arr_1'}$ = $\\mathsf{Poly}_\\mathsf{Arr_2'}$, then they have the same factorization. This means that $\\mathsf{Arr}_1'$ and $\\mathsf{Arr}_2'$ must contain the same elements (in possibly different orders). By the same intuition of matching first entries as above (in this case, we are pairing up factors where $i$ in $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$ equals $\\mathsf{Arr_\\pi}[i]$ in $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$) this shows that $\\mathsf{Arr}_2$ is a permutation of $\\mathsf{Arr}_1$ under $\\pi$. To check the equality of the two auxilary polynomials, random challenge values $r$ and $s$ are generated and the products are checked at that point. If they are equal at that point then (with overwhelming probabiltiy) the polynomials are equal.\nIn addition to demontrasting the equality of the product of $\\mathsf{Arr_1}'$ and $\\mathsf{Arr_2}'$, it must also be shown that these two arrays are defined correctly in terms of the original arrays. In other words, it must be shown that $\\mathsf{Arr_1}'[i]= (i, \\mathsf{Arr_1}[i])$ and $\\mathsf{Arr_2}'[i]= (\\mathsf{Arr_\\pi}[i], \\mathsf{Arr_2}[i])$. Once this, in addition to the product check, has been done, it has been shown that $\\mathsf{Arr}_2$ is a shuffle of $\\mathsf{Arr}_1$ under the disclosed permutation $\\pi$.\nProtocol Details # Array Level # $\\mathcal{P}$ holds an array $\\mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \\dots, a_{(1,n-1)}]$ of $n$ integers ($a_{(1,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ holds an array $\\mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \\dots, a_{(2,n-1)}]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$​) $\\mathcal{P}$ holds an array $\\mathsf{Arr_\\pi} = [\\pi(\\omega^0), \\pi(\\omega^1), \\pi(\\omega^2), \\dots, \\pi(\\omega^{n-1})]$ of $n$ integers ($a_{(2,i)} \\in \\mathbb{Z}_q$) $\\mathcal{P}$ generates the random challenge $r, s$ and computes $\\mathsf{Arr_1}'$ as follows: $\\mathsf{Arr_1}'[i]= r - s\\cdot i - \\mathsf{Arr_1}[i]$ $\\mathcal{P}$ computes $\\mathsf{Arr_2}'$ as follows: $\\mathsf{Arr_2}'[i]= r - s\\cdot \\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i]$ Polynomial Level # We assume that $\\mathsf{Arr_1}$, $\\mathsf{Arr_2}$, $\\mathsf{Arr_\\pi}[i]$, $\\mathsf{Arr_1'}$, and $\\mathsf{Arr_2'}$ are encoded as the y-coordinates into a univariant polynomial where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. If $\\kappa$ is larger than the length of the arrays, the arrays can be padded with elements all of value 1 (or any other value, as long as it is the same for both arrays).\nRecall the two components we want to prove. First, the product check:\n$\\prod^{n-1}_{i = 1}(r - s\\cdot i - \\mathsf{Arr_1}[i]) = \\prod^{n-1}_{i = 1}(r - s\\cdot \\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i])$\nAs well as the two constraints:\n$\\mathsf{Arr_1}'[i]= r - s\\cdot i - \\mathsf{Arr_1}[i]$ $\\mathsf{Arr_2}'[i]= r - s\\cdot \\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i]$ The first component is done as a mult3 product check, and we write the second component in polynomial form. From this point on we focus on the polynomial details of the second component.\nFor all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_1'}(X) = r - s\\cdot X - \\mathsf{Poly}_\\mathsf{Arr_1}(X)$ For all $X$ from $\\omega^0$ to $\\omega^{\\kappa-1}$: $\\mathsf{Poly}_\\mathsf{Arr_2'}(X) = r - s\\cdot \\mathsf{Poly_\\pi}(X) - \\mathsf{Poly}_\\mathsf{Arr_2}(X)$ We adjust each of these constraints to show an equality with 0 and label them:\n$\\mathsf{Poly}_\\mathsf{Vanish1}(X)= \\mathsf{Poly}_\\mathsf{Arr_1'}(X) - (r - s\\cdot X - \\mathsf{Poly}_\\mathsf{Arr_1}(X)) = 0$ $\\mathsf{Poly}_\\mathsf{Vanish2}(X)= \\mathsf{Poly}_\\mathsf{Arr_2'}(X) - (r - s\\cdot \\mathsf{Poly_\\pi}(X) - \\mathsf{Poly}_\\mathsf{Arr_2}(X)) = 0$ This equation is true for every value of $X \\in \\mathcal{H}_\\kappa$ (but not necessarily true outside of these values). To show this, we divide each polynomial by $X^\\kappa - 1$, which is a minimal vanishing polynomial for $\\mathcal{H}_\\kappa$ that does not require interpolation to create. If the quotients are polynomials (and not rational functions), then $\\mathsf{Poly}_\\mathsf{Vanish}(X)$ must be vanishing on $\\mathcal{H}_\\kappa$ too. Specifically, the prover computes:\n$Q_1(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X)}{X^\\kappa - 1}$ $Q_2(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish2}(X)}{X^\\kappa - 1}$ We can replace polynomials $Q_1(X)$ and $Q_2(X)$ with a single polynomial $Q(X)$. We can do this because both constraints have the same format: $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)=0$. The batching technique is to create a new polynomial with both $\\mathsf{Poly}_\\mathsf{Vanish_i}(X)$ values as coefficients. If and (overwhelmingly) only if both are vanishing, then so will the new polynomial. This polynomial will be evaluated at a random challenge point $\\rho$ selected after the commitments to the earlier polynomials are fixed.\n$Q(X) = \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\mathsf{Poly}_\\mathsf{Vanish2}(X) \\rho}{X^n - 1}$\nBy rearranging, we can get $\\mathsf{Poly}_\\mathsf{Zero}(X)$ as a true zero polynomial (zero at every value both in $\\mathcal{H}_\\kappa$ and outside of it):\n$\\mathsf{Poly}_\\mathsf{Zero}(X)=\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(X) - Q(X)\\cdot (X^n - 1)=0$\nUltimately the shuffle1 argument will satisfy the following constraints at the Commitment Level:\nShow $Q(X)$ exists (as a polynomial that evenly divides the divisor) Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is correctly constructed from $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly_\\pi(X)}$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$ Show $\\mathsf{Poly}_\\mathsf{Zero}(X)$ is the zero polynomial In addition, it will show that $\\prod^{n-1}_{i = 1}(X - Y\\cdot i - \\mathsf{Arr_1}[i]) = \\prod^{n-1}_{i = 1}(X - Y\\cdot \\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i])$ using a mult3 product check.\nCommitment Level # The verifier will never see the arrays or polynomials themselves. They are undisclosed because they either (i) contain private data or (ii) they are too large to examine and maintain a succinct proof system. Instead the prover will use commitments.\nThe prover will create a transcript for the product check, as decribed in mult3. Below, we give details specific to the second component, verifing the two constraints.\nThe prover will write the following commitments to the transcript:\n$K_\\mathsf{Arr_1}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1}(X))$ $K_\\mathsf{Arr_2}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2}(X))$​ $K_\\pi = \\mathsf{KZG.Commit(Poly_\\pi}(X))$ The prover will generate two random challenge evaluation points (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call these points $r$ and $s$. It will use these points to define the arrays $\\mathsf{Arr_1'} = \\{ r - s\\cdot i - \\mathsf{Arr_1}[i]\\}_{i \\in [0, n-1]}$ and $\\mathsf{Arr_2'} = \\{ r - s\\cdot\\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i]\\}_{i \\in [0, n-1]}$ and run the product check. It will write the product check into the transcript. However, here we focus only on what is relevant to the second component, the points $r$ and $s$ and the following polynomials, which are also written to the transcript:\n$r$ $K_\\mathsf{Arr_1'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_1'}(X))$ $K_\\mathsf{Arr_2'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr_2'}(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomial that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\rho$. It will be used by the prover to create polynomial $Q(X)$ (see above) and the prover will write to the transcript:\n$\\rho$ $K_Q=\\mathsf{KZG.Commit}(Q(X))$ The prover will generate a random challenge evaluation point (using strong Fiat-Shamir) on the polynomials that is outside of $\\mathcal{H}_\\kappa$. Call this point $\\zeta$. The prover will write the point and opening proofs to the transcript:\n$\\zeta$ $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2},\\zeta)$​ $\\mathsf{Poly_\\pi}(\\zeta) = \\mathsf{KZG.Open}(K_\\pi, \\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_1'},\\zeta)$ $\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta)=\\mathsf{KZG.Open}(K_\\mathsf{Arr_2'},\\zeta)$ $Q(\\zeta)=\\mathsf{KZG.Open}(K_Q,\\zeta)$ To check the proof, the verifier uses the transcript to construct the value $Y_\\mathsf{Zero}$ as follows:\n$Y_\\mathsf{Vanish1}= \\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - s\\cdot \\zeta - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))$ $Y_\\mathsf{Vanish2}= \\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - s\\cdot \\mathsf{Poly_\\pi}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))$ $Y_\\mathsf{Zero}=Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} - Q(\\zeta)\\cdot (\\zeta^n - 1)$ Finally, if the constraint system is true, the following constraint will be true (and will be false otherwise with overwhelming probability, due to the Schwartz-Zippel lemma on $\\zeta$) :\n$Y_\\mathsf{Zero}\\overset{?}{=}0$ Implementations # Security Proof # Completeness # We assume completeness of the product check (it is proven in mult3) and conduct a proof of completeness for the rest of the protocol.\nIf $Y_\\mathsf{Zero}$ is zero, then $\\mathcal{V}$ will accept. Therefore, to show completeness, we show that any prover who holds $\\mathsf{Arr}_1$ and $\\mathsf{Arr}_2$ such that $\\mathsf{Arr}_2=\\mathsf{Permute}(\\mathsf{Arr}_1)$, can follow the steps outlined in the above protocol and the resulting $Y_\\mathsf{Zero}$ will be equal to zero. To see this, observed that $Y_\\mathsf{Zero}$\n$= Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2} - Q(\\zeta)\\cdot (\\zeta^\\kappa - 1)$\n$= [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - s \\cdot \\zeta - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))] + \\rho [\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - s\\cdot\\mathsf{Poly_{\\pi}(\\zeta)} - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))] - Q(\\zeta) \\cdot (\\zeta^\\kappa - 1)$\n$= [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - s\\cdot\\zeta - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))] + \\rho [\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - s\\cdot \\mathsf{Poly_\\pi}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))] - \\frac{\\mathsf{Poly}_\\mathsf{Vanish1}(\\zeta) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(\\zeta)}{X^\\kappa - 1} \\cdot (\\zeta^\\kappa - 1)$\n$= [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - s\\cdot\\zeta - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta))] + \\rho [\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - s\\cdot \\mathsf{Poly_\\pi}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))] \\newline - [\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta) - (r - s\\cdot\\zeta - \\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)) + \\rho[\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta) - (r - s\\cdot\\mathsf{Poly_\\pi}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta))]]$\n$= 0$\nWhere the third equality relies on the fact that $\\mathsf{Poly}_\\mathsf{Vanish1}(X) + \\rho \\mathsf{Poly}_\\mathsf{Vanish2}(X)$ is divisible by $X^\\kappa -1$. This is true if $\\mathsf{Poly_{Vanish1}}(\\zeta)$ and $\\mathsf{Poly_{Vanish2}}(\\zeta)$ are vanishing on $\\mathcal{H}_\\kappa$, i.e. if $\\mathsf{Poly}_\\mathsf{Arr_1'}(X) - (r - s\\cdot\\zeta - \\mathsf{Poly}_\\mathsf{Arr_1}(X)) = 0$ and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X) - (r - s\\cdot \\mathsf{Poly_\\pi}(\\zeta) - \\mathsf{Poly}_\\mathsf{Arr_2}(X)) = 0$, $X \\in \\mathcal{H}_\\kappa$. This is true if $\\mathsf{Arr}_1'[i] - (r - s\\cdot i - \\mathsf{Arr}_1[i]) = 0$ and $\\mathsf{Arr}_2'[i] - (r - s \\cdot \\mathsf{Arr}_\\pi(i) - \\mathsf{Arr}_1[i]) = 0$, $\\forall 0 \\leq i\\leq \\kappa$, since $\\mathsf{Poly_j}(\\omega^i) = \\mathsf{Arr_j}[i] \\space \\forall i \\in [0, \\kappa - 1]$, $\\mathsf{Poly_j}'(\\omega^i) = \\mathsf{Arr_j}'[i] \\space \\forall i \\in [0, \\kappa - 1]$, and since $\\mathsf{Poly_\\pi}(\\omega^i) = \\mathsf{Arr_\\pi}[i] \\space \\forall i \\in [0, \\kappa - 1]$ . But this is precisely how the honest prover defines $\\mathsf{Arr}_1'$ and $\\mathsf{Arr}_2'$, so the $Y_\\mathsf{Zero}$ it creates by following the protocol is zero, and the transcript will be accepted.\nSoundness # We prove knowledge soundness in the Algebraic Group Model (AGM). We assume soundness of the product check (it is proven in mult3) and conduct a proof of soundness for the rest of the protocol. To do so, we must prove that there exists an efficient extractor $\\mathcal{E}$ such that for any algebraic adversary $\\mathcal{A}$ the probability of $\\mathcal{A}$ winning the following game is $\\mathsf{negl}(\\lambda)$.\nGiven $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$ $\\mathcal{A}$ outputs commitments to $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly_\\pi}$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$, $Q(X)$\n$\\mathcal{E}$, given access to $\\mathcal{A}$\u0026rsquo;s outputs from the previous step, outputs $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly_\\pi}$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$, $Q(X)$\n$\\mathcal{A}$ plays the part of the prover in showing that $Y_{\\mathsf{Zero}}$ is zero at a random challenge $\\zeta$\n$\\mathcal{A}$ wins if:\ni) $\\mathcal{V}$ accepts at the end of the protocol\nii) $\\mathsf{Arr}_2 \\neq \\mathsf{Permute}(\\mathsf{Arr}_1 ,\\pi)$\nOur proof is as follows:\nFor the second win condition to be fulfilled, it must be that $(\\mathsf{Arr_\\pi}[i], \\mathsf{Arr_2}[i]) \\neq (i, \\mathsf{Arr_1}[i])$ for some $i \\in [0, n-1]$. But then, $\\mathsf{Arr_1'}$ and $\\mathsf{Arr_2'}$ contain differing element. This means that $\\mathsf{Poly}_\\mathsf{Arr_1'}(X) = \\prod^{n-1}_{i = 1}(X - Y\\cdot i - \\mathsf{Arr_1}[i])$ and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X) = \\prod^{n-1}_{i = 1}(X - Y\\cdot \\mathsf{Arr_\\pi}[i] - \\mathsf{Arr_2}[i])$ and different polynomials, and thus by the Schwartz-Zippel lemma, there is negligible probability that they are equal at $X=r$ and $Y=2$ for the random challenge $r, s$ (thus the product check will fail). Any strategy to increase this probability to greater than negligible means $\\mathcal{A}$ must pass in $\\mathsf{Arr_j'}$ for $j = 1$ or $j = 2$ that is not defined according to the its corresponding constraint. But then $\\mathsf{Poly}_\\mathsf{Vanishj}(X)$ is not vanishing on $\\mathcal{H}_\\kappa$, so $Q(X)$ is not a polynomial (it is a rational function). This means that $\\mathcal{A}$ cannot calcuated the correct commitment value $g^{Q(\\tau)}$ without solving the t-SDH. Thus, $\\mathcal{A}$ chooses an arbitrary value for $Q(\\tau)$ and writes $K_Q = g^{Q(\\tau)}$ to the transcript. Before this, it also writes commitments to $\\mathsf{Poly}_\\mathsf{Arr_1}(X)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(X)$, $\\mathsf{Poly_\\pi}$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(X)$, and $\\mathsf{Poly}_\\mathsf{Arr_2'}(X)$. All commitments $\\mathcal{A}$ has written are linear combinations of the elements in $[g, g^\\tau, g^{\\tau^2}, \\dots,g^{\\tau^{n-1}}]$. $\\mathcal{E}$ is given these coefficients (since $\\mathcal{A}$ is an algebraic adversary) so $\\mathcal{E}$ can output the original polynomials.\n$\\mathcal{A}$ then obtains the random challenge $\\zeta$ (using strong Fiat-Shamir). By the binding property of KZG commitments, $\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)$, $\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)$, $\\mathsf{Poly_\\pi(\\zeta)}$, $\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta)$, and $\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta)$ can only feasibliy be opened to one value. For $\\mathcal{A}$ to have the verifier accept, it must produce a proof that $Q(\\zeta)$ opens to $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2}}{(\\zeta^n - 1)}$. This means being able to produce $g^{q(\\tau)}$ where $q(\\tau) = \\frac{Q(\\tau) - Q(\\zeta)}{\\tau - \\zeta}$ and $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2}}{(\\zeta^n - 1)}$. Since $Q(\\tau)$ and $Q(\\zeta)$ are known, this implies knowing $g^{\\frac{1}{\\tau - \\zeta}}$. Thus $\\mathcal{A}$ would have found $\\langle\\zeta,g^{\\frac{1}{\\tau - \\zeta}}\\rangle$, which is the t-SDH problem. We have shown that creating an accepting proof reduces to the t-SDH, so $\\mathcal{A}$\u0026rsquo;s probability of success is negligible.\nZero-Knowledge # We prove that the above protocol is zero-knowledge when $\\mathsf{PolyCommit}_\\mathsf{Ped}$ (from the KZG paper) is used for the polynomial commitments. We assume the product check is zero-knowledge (it is proven in mult3), and conduct a proof for the rest of the protocol. We do so by constructing a probabilistic polynomial time simulator $\\mathcal{S}$ that knows the trapdoor $\\tau$, which, for every (possibly malicious) verifier $\\mathcal{V}$, can output a view of the execution of the protocol that is indistinguishable from the view produced by the real execution of the program.\nThe simulator $\\mathcal{S}$ chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, and $\\mathsf{Poly_\\pi}(\\tau)$, then computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, $g^{\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, $g^{\\mathsf{Poly_\\pi}(\\tau)}$ to write as the commitments $ K_\\mathsf{Arr_1}$, $K_\\mathsf{Arr_1}$, $K_\\pi$. $\\mathcal{S}$ then generates $r$ and $s$ as values for the ranom challenge (by strong Fiat-Shamir). It then chooses arbitrary values for ${\\mathsf{Poly}_\\mathsf{Arr_1'}(\\tau)}$ and ${\\mathsf{Poly}_\\mathsf{Arr_2'}(\\tau)}$, computes $g^{\\mathsf{Poly}_\\mathsf{Arr_1'}(\\tau)}$ and $g^{\\mathsf{Poly}_\\mathsf{Arr_2'}(\\tau)}$ to write as the commitments $ K_\\mathsf{Arr_1'}$ and $K_\\mathsf{Arr_1'}$. It creates a view of the product check as described in the zero-knowledge proof for mult3.\n$\\mathcal{S}$ generates the challenge evaluation point $\\rho$ (by strong Fiat-Shamir) and computes $Q(\\tau)$ using $\\rho$ and the values it chose for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\tau)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\tau)}$, $\\mathsf{Poly_\\pi}(\\tau)$, ${\\mathsf{Poly}_\\mathsf{Arr_1'}(\\tau)}$, and ${\\mathsf{Poly}_\\mathsf{Arr_2'}(\\tau)}$. $\\mathcal{S}$ outputs the commitment $K_Q = g^{Q(\\tau)}$.\nNow, $\\mathcal{S}$ generates the second random challenge, $\\zeta$ (which we assume is not in $\\mathcal{H}_\\kappa$; if it is in $\\mathcal{H}_\\kappa$, $\\mathcal{S}$ simply restarts and runs from the beginning). This is once again by strong Fiat-Shamir. $\\mathcal{S}$ then create fake opening proofs for ${\\mathsf{Poly}_\\mathsf{Arr_1}(\\zeta)}$, ${\\mathsf{Poly}_\\mathsf{Arr_2}(\\zeta)}$, $\\mathsf{Poly_\\pi}(\\zeta)$, ${\\mathsf{Poly}_\\mathsf{Arr_1'}(\\zeta)}$, and ${\\mathsf{Poly}_\\mathsf{Arr_2'}(\\zeta)}$, to arbitrary values. This is done using the knowledge of $\\tau$, calculating the respective witness $q(\\tau) = \\frac{{f(\\tau) - f(\\zeta)}}{\\tau - \\zeta}$ for each of the polynomials.\nFinally, $\\mathcal{S}$ creates a fake opening proof for $Q(\\zeta) = \\frac{Y_\\mathsf{Vanish1} + \\rho Y_\\mathsf{Vanish2}}{(\\zeta^n - 1)}$. This is done using knowledge of $\\tau$ to calculate an accepting witness $q(\\tau)$, as above. This means that $Y_\\mathsf{Zero}$ will be zero, and the transcript will be accepted by the verifier. It is indistinguishable from a transcript generates from a real execution, since $\\mathsf{PolyCommit}_\\mathsf{Ped}$ has the property of Indistinguishability of Commitments due to the randomization by $h^{\\hat{\\phi}(x)}$.\n"},{"id":18,"href":"/docs/gadgets/zero1/","title":"Zero1","section":"Gadgets","content":" Zero (Type 1) # Recap of types # Type Description Recap This zero1 $\\mathsf{Arr}[i]\\leftarrow0$ Zero-out elements of an array $\\mathsf{Arr}$ such as: all, first, last, all-but-first, all-but-last. ✅ zero2 $\\mathsf{Arr}[i]\\leftarrow0$ iff $\\mathsf{Sel}[i]=0$ Zero-out elements of an array $\\mathsf{Arr}$ according to a binary array $\\mathsf{Sel}$. Subtypes of $\\texttt{zero1}$ # Operation Output Array Zero all $\\langle 0,0,0,0,0 \\rangle$ Zero first $\\langle 0,\\bot,\\bot,\\bot,\\bot \\rangle$ Zero last $\\langle \\bot,\\bot,\\bot,\\bot,0 \\rangle$ Zero all but first $\\langle \\bot,0,0,0,0 \\rangle$ Zero all but last $\\langle 0,0,0,0,\\bot \\rangle$ Relation # Shown for \u0026ldquo;zero last\u0026rdquo; but can be adapted to the other sub-types of $\\texttt{zero1}$:\n$ \\mathcal{R}_{\\mathtt{mult2}} := \\left\\{ \\begin{array}{l} (K_\\mathsf{Arr},K_\\mathsf{Arr'}) \\end{array} \\middle | \\begin{array}{l} \\mathsf{Arr} = [a_0, a_1, \\dots, a_{n-2}, a_{n-1}], \\\\ \\mathsf{Arr'} = [a'_0, a'_1, \\dots, a'_{n-2}, 0], \\\\ \\mathsf{Poly}_\\mathsf{Arr}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr}), \\\\ \\mathsf{Poly}_\\mathsf{Arr'}=\\mathsf{FFT.Interp}(\\omega,\\mathsf{Arr'}), \\\\ K_\\mathsf{Arr}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr}) \\\\ K_\\mathsf{Arr'}=\\mathsf{KZG.Commit}(\\mathsf{Poly}_\\mathsf{Arr'}) \\end{array} \\right\\} $\nIntuition # This gadget is a helper gadget that is not very useful as a stand-alone gadget, but is used in nearly all other gadgets to handle things like boundary conditions (see Red Tape). The semantics of the gadget might seem weird but eventually you will see it in use (e.g., $\\texttt{add2}$). The prover ($\\mathcal{P}$) holds an array $\\mathsf{Arr} = [a_0, a_1, a_2, \\dots, a_{n-1}]$ of $n$ integers (from $\\mathbb{Z}_q$). It will produce a succinct (independent of $n$) proof that $\\mathsf{Arr'}$ contains a 0 at a selected element (such as the last element). At the other elements, the operation is zero-preserving, meaning it will not replace a 0 in $\\mathsf{Arr}$. If an element in $\\mathsf{Arr}$ is non-zero and the\nit contains $\\bot$ which is an arbitrary integer\nthe same at every element\n$\\mathsf{Prod}_\\mathsf{Arr}$ is the product of all the elements in the array. The prover will encode the array into a polynomial $\\mathsf{Poly}_\\mathsf{Arr}$ (using evaluation points on the domain $\\mathcal{H}_\\kappa$) and commit to the polynomial $K_\\mathsf{Arr}$. The verifier ($\\mathcal{V}$) cannot check $\\textsf{Arr}$ or $\\mathsf{Poly}_\\mathsf{Arr}$ directly (they may contain secret information, and even if they do not, it is too long to check) so the verifier only sees $K_\\mathsf{Arr}$ and the asserted value $\\mathsf{Prod_\\mathsf{Arr}}$.Zeroing Parts of an Array\nAssuming an input array of size $n$: $\\langle \\mathsf{data}_0,\\mathsf{data}_1,\\ldots,\\mathsf{data}_{n-1}\\rangle$ and input array encoded into the polynomial. This uses \u0026ldquo;Encoding 2\u0026rdquo; from above (evaluation points) and uses \u0026ldquo;Roots of Unity + FFT\u0026rdquo; from above where $\\omega\\in\\mathbb{G}_\\kappa$ is a generator for the x-coordinates of the points.\n$\\bot$ is an arbitrary non-zero integer.\nOperation Input Array Input Polynomial Output Array Output Polynomial Zero all $\\langle 3,1,3,3,7 \\rangle$ $P(X)$ $\\langle 0,0,0,0,0 \\rangle$ $P(X)\\cdot(X^\\kappa-1)$ Zero first $\\langle 3,1,3,3,7 \\rangle$ $P(X)$ $\\langle 0,\\bot,\\bot,\\bot,\\bot \\rangle$ $P(X)\\cdot(X-\\omega^0)$ Zero last $\\langle 3,1,3,3,7 \\rangle$ $P(X)$ $\\langle \\bot,\\bot,\\bot,\\bot,0 \\rangle$ $P(X)\\cdot(X-\\omega^{\\kappa-1})$ Zero all but first $\\langle 3,1,3,3,7 \\rangle$ $P(X)$ $\\langle \\bot,0,0,0,0 \\rangle$ $P(X)\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^0)}$ Zero all but last $\\langle 3,1,3,3,7 \\rangle$ $P(X)$ $\\langle 0,0,0,0,\\bot \\rangle$ $P(X)\\cdot\\frac{(X^\\kappa-1)}{(X-\\omega^{\\kappa-1})}$ "},{"id":19,"href":"/docs/gadgets/zero2/","title":"Zero2","section":"Gadgets","content":" Zero (Type 2) # Recap of types # Type Description Recap This zero1 $\\mathsf{Arr}[i]\\leftarrow0$ Zero-out elements of an array $\\mathsf{Arr}$ such as: all, first, last, all-but-first, all-but-last. zero2 $\\mathsf{Arr}[i]\\leftarrow0$ iff $\\mathsf{Sel}[i]=0$ Zero-out elements of an array $\\mathsf{Arr}$ according to a binary array $\\mathsf{Sel}$. ✅ Zeroing Parts of an Array (2) # Assume both $\\mathsf{Arr}$ (an array of data) and $\\mathsf{Sel}$ (a binary array) are of size $n$. They are encoded as the y-coordinates into univariant polynomials where the x-coordinates (called the domain $\\mathcal{H}_\\kappa$) are chosen as the multiplicative group of order $\\kappa$ with generator $\\omega\\in\\mathbb{G}_\\kappa$ (see Background for more). In short, $\\omega^0$ is the first element and $\\omega^{\\kappa-1}$ is the last element of $\\mathcal{H}_\\kappa$. We call our polynomials $\\mathsf{Poly}_\\mathsf{Arr}(X)$ and $\\mathsf{Poly}_\\mathsf{Sel}(X)$. The goal is to construct an output polynomial where all the elements in $\\mathsf{Arr}$ that share an index with a zero in $\\mathsf{Sel}$ are zeroed (and non-zero elements in $\\mathsf{Arr}$ that share an index with a one in $\\mathsf{Sel}$ are kept non-zero).\nNote that $\\mathsf{Poly}_\\mathsf{Sel}(X)$ has a root at every point in $\\mathcal{H}_\\kappa$ that corresponds to a zero entry in $\\mathsf{Sel}$, since it has a $y$ value of zero at each of these values of $x$. Denote this set of roots $R = [r_0, r_1, \\dots, r_{m-1}]$, where $m$ is the number of zero entries in $\\mathsf{Sel}$. Denote also $S = [s_0, s_1, \\dots, s_{l-1}]$ the (possibly empty) set of remaining roots of $\\mathsf{Poly}_\\mathsf{Sel}(X)$, for some $l \\in \\mathbb{N}$. Then written in factored form we have $\\mathsf{Poly}_\\mathsf{Sel}(X) = \\prod^{i \\lt m}_{i = 0} (X - r_i) \\cdot \\prod^{i \\lt l}_{i=0}(X-s_i) \\cdot R(X)$ for some $R(X) = \\frac{\\mathsf{Poly}_\\mathsf{Sel}(X)}{\\prod^{i \\lt m}_{i = 0} (X - r_i) \\cdot \\prod^{i \\lt l}_{i=0}(X-s_i)}$. Note that $R(X)$ is indeed a polynomials, and that it has no roots over the field.\nNow, consider $\\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot \\mathsf{Poly}_\\mathsf{Sel}(X) = \\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot \\prod^{i \\lt m}_{i = 0} (X - r_i) \\cdot \\prod^{i \\lt l}_{i=0}(X-s_i) \\cdot R(X)$. First, note it has roots at each $r \\in R$, thus this new polynomial has zeroed out all the elements of $\\mathsf{Arr}$ corresponding to a zero entries in $\\mathsf{Sel}$. Further, the only other roots it has are from $S$, or are roots that were already part of $\\mathsf{Poly}_\\mathsf{Arr}(X)$. Since no value $s \\in S$ is also in $\\mathcal{H}_\\kappa$, all non-zero entries in $\\mathsf{Arr}$ are left non-zero.Thus, $\\mathsf{Poly}_\\mathsf{Arr}(X) \\cdot \\mathsf{Poly}_\\mathsf{Sel}(X)$ is our desired output polynomial.\n"},{"id":20,"href":"/docs/background/overview/","title":"Overview","section":"Background","content":" Overview # Preliminaries # While we may add more background in future iterations, for now we punt on explaining the following concepts and assume you are already familiar with them:\nElliptic curve cryptography Hardness of the discrete logarithm problem and related problems Pairing-based cryptography at a \u0026ldquo;black-box\u0026rdquo; level (what it does, not necessarily how it works) Resources: Lecture (Boneh) Commitment schemes Properties: hiding and binding Construction: Pedersen Commitments Resources: Lecture (Boneh) Zero knowledge proofs (high level idea) Properities: completeness, soundness, zero-knowledge Resources: Lecture (Goldwasser) zk-SNARKs # Plonk is a zk-SNARK proof system. In such a system, one entity (the prover) executes a function $f$ on a set of inputs (say $x,y$) and produces output $z=f(x,y)$. It then issues a proof $\\pi$ that $z$ is correct. It can show $\\pi$ to anyone and it will convince them (the verifier) that $z$ is correct.\nWhat are the assumptions about the function, inputs, and outputs?\nFunction:\n$f$ can be nearly any function. $f$ must be deterministic, meaning that running $f$ on the same inputs always produces the same output. Randomness can be used but it needs to be an input to the function. $f$ is disclosed to the verifier, meaning that to check $\\pi$ is correct requires a copy of $f$ itself. It is possible to make a private $f$ with a hack, see below (under inputs). In Plonk specifically, $f$ takes the form of a circuit with two kinds of gates: addition (takes two inputs and outputs their sum) and multiplication (takes two inputs and outputs their product). It is technically modular addition and multiplication, where the modulus is a large (for example, 256 bit) prime number. It has been proven that using only these two gates is sufficient to emulate any $f$ that can be implemented in any other kind of circuit (it just might result in a larger circuit to capture the same functionality). To use Plonk in practice, you do not need to program circuits. You can use a special-purpose programming language to write $f$ and compilation tools will convert $f$ into the circuit format that Plonk expects. $f$ has a (quite large) upper-bound on its \u0026ldquo;size\u0026rdquo; (for example, less than 1 trillion gates for efficiency in standard cryptographic settings). Inputs:\n$f$ can have any number of inputs which are typically integers (modulus the large prime). Inputs can be disclosed to the verifier (public inputs), meaning that to check $\\pi$ is correct, the verifier also checks that these were the inputs that were used to produce $z$. Inputs can also be undisclosed (private inputs), meaning the verifier does not see them and does need them to check that $\\pi$ is correct. But what does it mean to check $z$ is correct if the inputs are not disclosed? It proves that the verifier knows some input $x$ such that, given function $f$, public input $y$ and public output $z$ that $z=f(x,y)$. This called a \u0026ldquo;proof of knowledge.\u0026rdquo; The $\\pi$ reveals zero information (or \u0026ldquo;zero knowledge\u0026rdquo;) about $x$ (beyond what you can learn by knowing it is a legal input to $f$ that produces $y$). As inferable from the above example, inputs can be a mix of public and private. Ouputs:\nThe output $z$ is disclosed to the verifier, meaning that to check $\\pi$ is correct requires a copy of $z$. $z$ does need to be a single integer, it can be a data structure. Proof Output:\nThe output proof $\\pi$ is succinct, meaning that (for Plonk) it is always the same size regardless of how many gates $f$ has. Checking $\\pi$ is correct is (for Plonk) constant-time, meaning it is always the same amount of time regardless of how many gates $f$ has. So why do we need zk-SNARKs? In the case that some of the inputs are undisclosed/private, it is clear zk-SNARKs let us do something \u0026ldquo;magic,\u0026rdquo; prove things about inputs that we are not disclosing. In the case that all inputs are disclosed/public (we call this a SNARK rather than zk-SNARK), note that the verifier knows all values $x,y,f,z$ in $z=f(x,y)$. If the verifier wants to know if $z$ is correct, it does not need a proof $\\pi$, it can just execute $f$ for itself on $x,y$ and see that the output is $z$.\nAt first glance, SNARKs (rather than zk-SNARKs) seem useless but remember that proof outputs are succinct and constant-time. For this reason, it might be cheaper (in terms of time and memory) for the verifier to check $\\pi$ than to re-execute $f$. Whether it is cheaper or not basically comes down to how complex $f$ is. If $f$ is simple, re-executing it will be fastest. But once $f$ becomes sufficiently complex, it will be cheaper to verify $\\pi$. What is sufficiently complex? Roughly any $f$ that would take, say, a millisecond or more to run on a normal device.\nLast, it is important to recognize we are not getting something for \u0026ldquo;free\u0026rdquo; here. In order for the verifier to enjoy fast verification of $f$, someone else (the prover) had to execute $f$ and generate a proof $\\pi$ for $f$ which is substantially more work than just running $f$. So the prover does extra work to save the verifier work. What are some models where this kind of trade-off makes sense for SNARKs (rather than zk-SNARKs)? There are probably many more, but the two big ones are:\nCase 1: there is a powerful (but not trusted) computer like a cloud service and a smaller constrained device (like a phone with battery life). Additionally, the economics need to make sense for the cloud to execute on behalf of the smartphone (fees, subscription, service offered by phone manufacturer, \u0026hellip;). Case 2: there are many verifiers that want to verifier the same thing so the system scales better if one party executes and issues a proof $\\pi$ and the verifiers all check the proof rather than re-executing the function. Plonk \u0026amp; its gadgets # There are numerous ways to implement a zk-SNARK system. Plonk uses a templated called a polynomial interactive oracle proof (or poly-IOP). The next background article will go into more detail about it. Roughly, the prover stores inputs, outputs, gates, and intermediate values in one-dimensional arrays (or vectors). It will also perform a set of operations on the arrays to prove the circuit is executed correctly. Generally proving that array operations are done correctly will require proofs that are proportional (in size and time) to the length of the array.\nThe trick to avoiding this is two-fold: first, the array will be encoded into a polynomial (univariate meaning a single variable) and every operation that is done on the array can be \u0026ldquo;mirrored\u0026rdquo; on the polynomial representation of the array. Second, the verifier will not receive the polynomials themselves but rather a short commitment to them. Again, every operation being done on the arrays and polynomials need to be mirrored on the commitments to the polynomials so the verifier can follow along.\nIn order to work, Plonk establishes a set of Poly-IOP building blocks (or gadgets) and combines them into a somewhat involved protocol that proves a circuit is executed correctly. Once this is done, anyone can write any function into a circuit and have Plonk\u0026rsquo;s circuit gadget prove it is executed correctly.\nflowchart LR Succinctness --\u003e Poly-IOP Poly-IOP --\u003e Univariate Univariate --\u003e Gadgets subgraph Gadgets zero-.-\u003eadd rotate-.-\u003eadd zero-.-\u003emult rotate-.-\u003emult mult-.-\u003eshuffle encode-.-\u003ecircuit shuffle-.-\u003ecircuit add-.-\u003elookup shuffle-.-\u003elookup lookup-.-\u003ecircuit mult-.-\u003erange circuit end Gadgets --Special Purpose--- Protocol1(Function) circuit --General Purpose--- Protocol2(Function) classDef color fill:#9f6; class Protocol1 color class Protocol2 color This gadget book is not for writing Plonk circuits. Writing Plonk circuits is one method for proving a function is correctly executed and is a general purpose method that works for any function. The second method is to realize that the building blocks of Plonk can be used directly, if they are verbose enough to capture what you want $f$ to do. It is a special purpose method, meaning it will not work for all $f$ but if it does work, it should be intuitive that this will be considerably faster for the prover. It is also possible to do a hybrid approach where certain parts of a general purpose circuit are replaced with gadgets and then glued back to the circuit.\n"},{"id":21,"href":"/docs/background/kzg/","title":"PCS","section":"Background","content":" Polynomial Commitment Schemes (PCS) # Comparing Polynomials # Say that Carol sends a polynomial to Alice and the same polynomial to Bob. Later Alice and Bob are sitting together and want to make sure their polynomials, which they got from Carol, are actually the same. How do you compare polynomials? There are many sufficient comparisons, but here are two ways to get started:\nEnsure the degree $d$ is the same and each coefficient is the same, Ensure the degree $d$ is the same and check at $d+1$ unique points. Say Alice and Bob go with the second method for their polynomials from Carol, which are both degree 1000. They start checking points and after checking 500 points, the polynomials are the same so far. How confident are they that they have the same polynomial? They are not 100% confident until they check all $d+1$ points but should they be more than 0% confident?\nImagine Carol is trying to trick them with different polynomials. If Carol knows Alice and Bob will check $P(0),P(1),P(2),\\ldots,P(d+1)$, she can make sure the polynomials are the same at the first set of points, hoping they give up early. So Alice and Bob should be 0% confident after checking 500 points if they know Carol is malicious.\nHowever if Alice and Bob choose random points to compare at, then Carol has to get \u0026ldquo;lucky\u0026rdquo; and hope the polynomials happen to be the same at each of the random points. The nice thing is we can quantify what \u0026ldquo;lucky\u0026rdquo; means for Carol. Two polynomials of degree $d$ can only match at $d$ points (even if the polynomials are very similar to each, say differing only by one coefficient). Every time Alice and Bob check a random point, the probability that Carol gets lucky and does not get caught presenting different polynomials is $\\frac{d}{q}$ where $q$ is the number of points on the polynomial (all values in $\\mathbb{Z}_q$). In a cryptographic setting, $q$ will be a large prime. If $q$ is 256-bits and the polynomial is degree 1000, then the probability Carol can get away with cheating after the first check is $\\frac{1000}{2^{256}}$, which is already negligibly small. So after checking just one random point, Alice and Bob are pretty confident the polynomials are the same if the point matches. Specifically, probability $1-\\frac{1000}{2^{256}}$ which is close enough to 1 for practical purposes:\n$0.99999999999999999999999999999999999999999999999999999999999999999999999999136383\\ldots$\nSo we can add a third probabilistic method for Alice and Bob to use in checking their polynomials:\nEnsure the degree $d$ is the same and check at $1$ random point. Compared to Method 2, it is materially less work for Alice and Bob. In mathematics, this result is commonly known as the Schwartz–Zippel1 lemma. We will use this idea in building a commitment scheme for polynomials.\nA Wishlist for Polynomial Commitments # Recall the Pedersen2 commitment scheme, which for message $m$ and randomness $r$ produces commitment value $K_m=\\mathsf{Commit}(m,r)=g^mh^r$. The commitment scheme is hiding which means that examining $K_m$ does not reveal the message $m$ or any information about what $m$ might be. It is also binding which means the person who creates and circulates $K_m$ can later show how $m$ was used to construct $K_m$ but cannot show that for a different value $m'\\neq m$. This comes under the important caveat that $g$ and $h$ are random group elements and the committer does not know the discrete logarithm between them.\nA second property that Pedersen commitments exhibit is an additive homomorphism, where $K_{m_1}\\cdot K_{m_2}=\\mathsf{Commit}(m_1+m_2,r_1+r_2)$. This is sometimes useful for protocols requiring addition.\nA final property to be considered with commitments is how many $m$ values can be committed to and how many $K_m$ values can be produced. Specifically, are they exactly equal, which would make the commitment function one-to-one. Alternatively, it might be one-to-many or many-to-one. Consider a few variants of Pedersen commitments:\nFeldman commitment: $\\mathsf{Commit}(m)=g^m$ is one-to-one (but not hiding as you can check if your guess at $m$ is right or not). $m\\in\\mathbb{Z}_q$ restricted to exponent group. Hashed Pedersen commitment: $\\mathsf{Commit}(m,r)=g^{\\mathcal{H}(m)}h^r$ is many-to-one for collision-resistant hash function $\\mathcal{H}$. $m\\in\\{0,1\\}^*$ can be any bit-string of any length. Pedersen multi-commitment: $\\mathsf{Commit}(m_1,m_2,m_3,r)=g_1^{m_1}g_2^{m_2}g_3^{m_3}h^r$ is many-to-one. $m_i\\in\\mathbb{Z}_q$ restricted to exponent group. Elgamal: $\\mathsf{Commit}(m,r)=\\{g^r,g^{m}h^r\\}$ is one-to-many. $m\\in\\mathbb{Z}_q$ restricted to exponent group. Next, let us consider committing to polynomials. We can use any of the above schemes to commit to a complete description of a polynomial, where a complete description might be its coefficients, all of its roots, or a sufficient set of points on the polynomial. However we can also consider making a special purpose commitment function for polynomials that might allow us some useful things for dealing with polynomials. A wishlist for a polynomial scheme might look as follows:\nBinding: necessary for commitments. (Optionally) hiding: necessary for using the commitment for zk-SNARKs but not necessary for just SNARKs. Useful homomorphisms: Polynomial addition Polynomial multiplication Selective opening: demonstrating a single chosen point on a polynomial without revealing the rest of the polynomial. Many-to-one (succinct): having $K_{P(X)}$ be constant-size regardless of how \u0026ldquo;big\u0026rdquo; (the degree) polynomial $P(X)$ is. The Kate-Zaverucha-Goldberg (KZG) polynomial commitment scheme gives us most of the above properties. Polynomial multiplication has a little red tape around it but the rest of the properties follow directly from KZG. KZG is only for univariant polynomials (which is all we will use in Plonkbook) however many research papers have shown how to adapt it to multivariant polynomials.\nKZG Commitments # Starting Point # KZG commitments will commit to a univariate polynomial assuming it is in coefficient form. That is: $$ P(\\square)=c_0+c_1\\cdot\\square+c_2\\cdot\\square^2+c_3\\cdot\\square^3+c_4\\cdot\\square^4=\\sum_{i=0}^d c_i\\cdot\\square^i $$ The rough idea is that a commitment will be $K_{P(\\square)}=\\mathsf{Commit}(P(\\square), r)=g^{P(\\square)}h^r$. For simplicity, we will describe the simpler version that is not hiding: $K_{P(\\square)}=\\mathsf{Commit}(P(\\square))=g^{P(\\square)}$.\nWhat does it mean to commit to $P(\\square)$ without specifying what $\\square$ is? Recall that $\\square$ can take on any value (in $\\mathbb{Z}_q$). Probably the most intuitive idea is to use the multi-commitment (above) to commit to the coefficients: $\\mathsf{Commit}(c_0,c_1,c_2,c_3)=g_0^{c_0}g_1^{c_1}g_2^{c_2}g_3^{c_3}$. This hits a few items on our wish list: it is binding, could be hiding (with $h^r$), is additively homomorphic (sum of polynomials is the sum of their coefficients), and is succinct.\nWhat about selective opening? The committer (prover) knows that $y_\\alpha=P(\\alpha)$ for some value $\\alpha$ and wants to prove it. To work toward computing $P(\\alpha)=c_0+c_1\\cdot\\alpha+c_2\\cdot\\alpha^2+c_3\\cdot\\alpha^3$, the prover can create $\\langle \\alpha, \\alpha^2, \\alpha^3\\rangle$ but can the prover get them into the \u0026ldquo;right spot\u0026rdquo; in the commitment: $g_0^{c_0}g_1^{c_1\\cdot\\alpha}g_2^{c_2\\alpha^2}g_3^{c_3\\alpha^3}$? It cannot do it with exponentiation as operations like $(g_0^{c_0}g_1^{c_1}g_2^{c_2}g_3^{c_3})^\\alpha$ will distribute $\\alpha$ to each term: $g_0^{c_0\\cdot\\alpha}g_1^{c_1\\cdot\\alpha}g_2^{c_2\\cdot\\alpha}g_3^{c_3\\cdot\\alpha}$. Even if it got them into the right spot, the prover would have to prove they used the right values. Finally, the prover cannot \u0026ldquo;add\u0026rdquo; the terms up: $g_0^{c_0}g_1^{c_1\\cdot\\alpha}g_2^{c_2\\alpha^2}g_3^{c_3\\alpha^3}\\rightarrow g_0^{c_0+c_1\\cdot\\alpha+c_2\\alpha^2+c_3\\alpha^3}$ without knowing the discrete logarithm between $g_0, g_1, g_2, g_3$ (if it did, it would break the binding property) plus it would have to get rid of the discrete logarithm terms. Anyways, there are three or four roadblocks to adding selective opening to such a commitment.\nKZG takes a different approach. To commit to a polynomial, the idea is to commit to its evaluation at a set of points rather than committing to the coefficients. How many points do we need to commit to? Recall the story about Alice and Bob comparing the polynomials they received from Carol. We concluded that statistically it is sufficient for Alice and Bob to check at $1$ random point.\nThe idea of KZG is to commit to the evaluation of the polynomial at one random point $\\tau$ and have this commitment represent a commitment to the entire polynomial. The important caveat is that no one knows what $\\tau$ is (it is a secret). How do we pull this off? How can the prover figure out the evaluation of their polynomial at $\\tau$ without knowing what $\\tau$ is? And finally, if they can figure out what $P(\\tau)$ is, can they not just reverse engineer what $\\tau$ is (for example, by committing to $y=P(\\tau)=\\tau$)?\nKZG uses a trusted setup to generate a commitment to $\\tau$. It then uses homomorphic operations to let a prover compute a commimtent to $P(\\tau)$ using the commiment to $\\tau$ without learning what $\\tau$ is or even what $P(\\tau)$ is. Committing to $P(\\tau)$ is considered as good as committing to the entire polynomial! We will see these details next.\nSetup # Someone trusted chooses a random value (from $\\mathbb{Z}_q$) to use as $\\tau$. They will also generate $d$ powers of $\\tau$ which will be needed to commit to polynomials up to degree $d$. They will commit to each power of $\\tau$ as follows. The output is called a structured random string (SRS) and will be available for the prover to use and the verifier to use:\n$$ \\langle g^{(\\tau^0)}, g^{(\\tau^1)}, g^{(\\tau^2)}, g^{(\\tau^3)}, \\ldots, g^{(\\tau^d)} \\rangle \\equiv SRS $$ What if the person generating the powers of $\\tau$ is not trustworthy? What goes wrong? There are two ways the trusted party can cheat: (1) tell everyone the secret value $\\tau$ (or use it for itself), and (2) generate the SRS with the wrong structure (the values are not successive powers of $\\tau$). We can address both of these issues. To address (1), we can let many parties generate an SRS and combine them into a single SRS. As long as one party deletes $\\tau$ without looking at it, the entire SRS is secure. Many blockchain projects have done this already with thousands of contributors. We can also address (2) through special purpose zero knowledge proofs that demonstrate each contributor\u0026rsquo;s SRS has the correct format without revealing $\\tau$. We will not cover these details but you can learn more from this article (a16z crypto research).\nCommitment # Using the coefficients of the polynomial, the prover can use the SRS to create a commitment to the polynomial evaluated at $\\tau$ as follows: $$ \\begin{align} K_{P(\\tau)}\u0026=\\mathsf{Commit}(P(\\tau))\\\\ \u0026= (g)^{c_0} (g^{\\tau})^{c_1} (g^{\\tau^2})^{c_2} (g^{\\tau^3})^{c_3} \\ldots \\\\ \u0026= g^{c_0 + c_1\\tau + c_2\\tau^2 + c_3\\tau^3 + \\ldots}\\\\ \u0026= g^{P(\\tau)} \\end{align} $$ At the end of the commitment operation, the prover does not know either $\\tau$ nor $P(\\tau)$ and would have to solve a discrete logarithm to learn them. The degree of the polynomial $P(\\square)$ has no impact on the size of $K_{P(\\tau)}$ so it is succinct. However the SRS has to be long enough to have $\\tau^d$ for committing to degree $d$ polynomials.\nCommitment Operations # Open # To completely open the polynomial, the prover will just send the coefficients to the verifier $\\langle c_0,c_1,c_2,c_3,\\ldots \\rangle$ and the verifier will recompute $(g)^{c_0} (g^{\\tau})^{c_1} (g^{\\tau^2})^{c_2} (g^{\\tau^3})^{c_3} \\ldots$ and check it matches $K_{P(\\tau)}$. However this is not very interesting by itself as the prover could have done something simpler like hashing the coefficients. This is why KZG offers additional features tailored to working with polynomials.\nAddition # KZG commitments are homomorphic with respect to the polynomial addition: $K_{P_1(\\tau)}\\cdot K_{P_2(\\tau)}=\\mathsf{Commit}(P_1(\\tau)+P_2(\\tau))$. As is usually the case, scalar multiplication (multiplication by a disclosed integer) can also be performed.\nMultiplication # KZG commitments are not exactly homomorphic with respect to polynomial multiplication but we can get something close. The subtle difference is as follows. For addition, anyone who sees $K_{P_1(\\tau)}$ and $K_{P_2(\\tau)}$ can compute $K_{P_1(\\tau)+P_2(\\tau)}$ directly without involving anyone else. This is not possible with multiplication. However the prover can assert the value for $K_{P_1(\\tau)\\cdot P_2(\\tau)}$ and can convince the verifier it is correct, given $K_{P_1(\\tau)}$ and $K_{P_2(\\tau)}$. The rough idea is to use the bilinear pairing to show: $$ \\begin{align} e(K_{P_1(\\tau)},K_{P_2(\\tau)})\u0026\\stackrel{?}{=}e(K_{P_1(\\tau)+P_2(\\tau)},g)\\\\ e(g^{P_1(\\tau)},g^{P_2(\\tau)})\u0026=e(g^{P_1(\\tau)\\cdot P_2(\\tau)},g) \\\\\u0026=e(g,g)^{P_1(\\tau)\\cdot P_2(\\tau)} \\end{align} $$ There is some red tape with this as the pairing might not be symmetric ($g$ and $h$ are in different groups for $e(g,h)$) and other subtle details. We will show a different approach to multiplications with our $\\texttt{mult}$ gadget.\nSelective Open: Root # The most useful property of KZG (and any polynomial commitment scheme) is being able to open the committed polynomial to certain points. We start with a simple case, the prover wants to show the polynomial is zero at a certain value $P(r)=0$. Recall that $r$ is called a root of the polynomial. Also recall that a set of roots $r_0, r_1, r_2 \\ldots$ can be turned into coefficient form using multiplication: $$ P(\\square)=(\\square-r_0)(\\square-r_1)(\\square-r_2)(\\square-r_3)\\ldots $$ If the prover is correct that $r$ is a root of the polynomial, then it is the case that the term $(\\square-r)$ will evenly divide the polynomial without any remainder. It is also the case that if $r$ is not a root of the polynomial, $P(\\square)/(\\square-r)$ will not be an even division and will result in some remainder. The prover will use this fact to prove $r$ is a root.\nThe prover will compute the quotient polynomial $Q(\\square)=P(\\square)/(\\square-r)$ and provide a commitment to it $K_{Q(\\tau)}$ with KZG and give the commitment to the verifier. Knowing the value $r$, if the verifier can check if $P(\\square)=Q(\\square)(\\square -r)$, it will be convinced that $(r-\\square)$ evenly divides $P(\\square)$ (since $Q$ is a single polynomial) and thus $r$ is a root.\nThe verifier has $r$ and $K_{P(\\tau)}$ and $K_{Q(\\tau)}$. The verifier can compute a commitment to $(\\square-r)$ at $\\tau$ by just treating it as the polynomial $V(\\square)=(\\square-r)=-r+1\\cdot\\square$ and using KZG to produce $K_{V(\\tau)}$. The verifier can then check: $$ \\begin{align} e(K_{P(\\tau)},g)\u0026\\stackrel{?}{=}e(K_{Q(\\tau)},K_{V(\\tau)})\\\\ e(g^{P(\\tau)},g)\u0026=e(g^{Q(\\tau)},g^{V(\\tau)}) \\\\e(g,g)^{P(\\tau)}\u0026=e(g,g)^{Q(\\tau)\\cdot V(\\tau)} \\end{align} $$ Notice that the degree of the polynomial $P(\\square)$ (and thus $Q(\\square)$) has no impact on the size of the proof given to the verifier or the work that the verifier has to do. Even if the degree of $P(\\square)$ is billions, the proof is the same size and time for the verifier. In a sense, this is our first special purpose SNARK and one we will leverage into making SNARKs for all the gadgets in Plonkbook.\nSelective Open: Multiple Roots # If the prover wants to open at multiple roots, it runs the exact same protocol but has the verifier set $V(\\square)=(\\square-r_0)\\cdot(\\square-r_1)\\cdot(\\square-r_2)\\ldots$ for all the roots it wants to prove. Importantly, this does not add any complexity for the verifier once $K_{V(\\tau)}$ has been created.\nSelective Open: Arbitrary Point # Most of the time, the prover wants to prove the polynomial passes through an arbitrary point $\\{x,y\\}=\\{x,P(x)\\}$ where $y$ is some integer that is not zero (and thus $x$ is not a root). Again, this is very easy to prove once we have a protocol for proving roots. The intution is as follows: if and only if $P(\\square)$ has value $y$ at point $x$, then subtracting $y$ from $P(\\square)$ will create a new polynomial $\\tilde{P}(\\square)=P(\\square)-y$ that is zero at point $x$, making $x$ a root. (Visually you can imagine a polynomial with height $y$ at a point $x$, and subtracting $y$ shifts the whole polynomial down $y$ units, moving that point down to the x-axis.) The verifier can construct $K_{\\tilde{P}(\\tau)}$ from $K_{P(\\tau)}$ using the additive homomorphic property: $K_{\\tilde{P}(\\tau)}=K_{P(tau)\\cdot} g^{-y}$. Then the prover shows $K_{\\tilde{P}(\\tau)}$ has a root at point $x$ using the protocol above for proving roots.\nSelective Open: Batch of Points # If the cost of opening a set of points is roughly the same as the cost of opening a single point, it is called a batch opening. Several variants might be desired:\nBatch open multiple points on the same polynomial: direct from KZG, shown below. Batch open the same point on multiple polynomials: direct from KZG, not shown. Batch open multiple points on multiple polynomials: not directly possible with KZG but possible with variants. To batch open multiple points on the same polynomial $P(\\square)$, the prover asserts the full set of points to the verifier. The verifier will interpolate a polynomial through these points $R(\\square)$ and compute its commitment $K_{R(\\tau)}$. Recall that when proving a single point $\\{x,y\\}$, it would compute $\\tilde{P}(\\square)=P(\\square)-y$. This does not work for multiple points because the amount to \u0026ldquo;slide down\u0026rdquo; the polynomial differs. However $R(\\square)$ has the right amount at every value of $x$ being opened. So the verifier computes $K_{\\tilde{P}(\\tau)}=K_{P(\\tau)} \\cdot (K_{R(\\tau)})^{-1}$ where $\\tilde{P}(\\square)=P(\\square)-R(\\square)$ using the additively homomorphic property, and now all the points are roots, so the prover uses the \u0026ldquo;selective open: multiple roots\u0026rdquo; protocol above on $\\tilde{P}(\\square)$.\nFootnotes # The result was actually pointed out earlier by DeMillo and Lipton, and thus is occasionally referred to as the DeMillo–Lipton–Schwartz–Zippel lemma\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nThe commitment was popularized by Pedersen but Pedersen attributes it to Bos and Chaum in his paper. It appeared even earlier as a bit commitment scheme in a paper by Chaum, Damgard, and van de Graaf.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n"},{"id":22,"href":"/docs/background/poly-iop/","title":"Polynomials","section":"Background","content":" Polynomials # All the gadgets in Plonkbook follow the same high level model, called a polynomial interactive proof (Poly-IOP). Each gadget is defined as an operation on one or more arrays of data. The arrays are encoded into a univariate polynomial (see below) and the polynomial is committed to (next background section) and passed to the verifier. The verifier works with commitments and sees that operations on commitments are mirroring a set of operations being done on the polynomials themselves. And the operations on the polynomials are mirroring operations on the data encoded into them as an array.\nEach gadget description will begin with the array and show the operation being done on the array. It will then show how to manipulate a polynomial holding the array so that the operation is performed on the underlying array. It will then show how the verifier can use only commitments to the polynomials, rather than the full polynomials, to follow along and check every step.\nEncoding Arrays of Data into Polynomials # In the Poly-IOP model, data starts as an array (or vector) of integers and gadgets are defined in terms of operations on arrays. In the proof stage, the arrays are encoded into a polynomial. Array slots contain integers between 0 and $q-1$, where $q$ is a large (generally 256 bit) prime number. Recall that we call this set of integers $\\mathbb{Z}_q$.\n$\\mathsf{data}_0$ $\\mathsf{data}_1$ $\\mathsf{data}_2$ $\\mathsf{data}_3$ $\\mathsf{data}_4$ It is common to denote a polynomial like $P(X)$ where $X$ is the variable of the polynomial. We are going denote the variable with an empty box $\\square$ which can be interpreted as a place where you can put any integer in $\\mathbb{Z}_q$ you want evaluated (or equivalent, where you place an x-coordinate to learn what the y-coordinate is).\nA polynomial in this notation looks like:\n$P(\\square)=c_0+c_1\\cdot\\square+c_2\\cdot\\square^2+c_3\\cdot\\square^3+c_4\\cdot\\square^4=\\sum_{i=0}^d c_i\\cdot\\square^i$ The values $c_i$ are called coefficients. Different arrays of data will (depending on how data is encoded, next) result in different coefficients and thus different polynomials. The degree of the polynomial is the largest exponent. So the polynomial above has degree 4 and thus will have 5 coefficients and 5 terms of the form $c_i\\cdot\\square^i$ (including $i=0$). Sometimes the coefficient will be zero: the term is thus not written down but in a list of coefficients, it will be included as a 0.\nThe main question to tackle is how to \u0026ldquo;encode\u0026rdquo; an array of integers into a polynomial. This is generally done one of three ways:\nCoefficients Evaluation Points Roots Each has its advantages and disadvantages, which we discuss next.\nFast forwarding a bit, once the polynomial is created, it is not shared directly with anyone. Instead, a commitment to it is shared. The commitment does two things: (1) it makes it succinct: e.g., constant size regardless of how long the array is; and (2) it can hide the data in the array as necessary. We will discuss one specific polynomial commitment scheme called KZG. KZG needs the polynomial in the format of a list of its coefficients. If we have the polynomial in a different form, we will have to convert it to coefficients. Thus this needs to be considered when weighing the pros/cons of the three encoding methods.\nEncoding 1: Coefficients # Create polynomial as: $P_1(\\square)=\\mathsf{data}_0+\\square+\\mathsf{data}_2\\cdot\\square^2+\\mathsf{data}_3\\cdot\\square^3+\\mathsf{data}_4\\cdot\\square^4=\\sum_{i=0}^d \\mathsf{data}_i\\cdot\\square^i$\nProperties:\nFast 👍: fastest path to commitment as the output is already in coefficient form. Addition 👍: two arrays can be added together (slot-by-slot) by simply adding the polynomials together Multiplication 👎: no support for multiplication of arrays (Remark: multiplying the polynomials does not multiply the coefficients. It results in a cross multiplication of every term in the first polynomial with every term in the second polynomial. Further the degree of the resulting polynomial will double that of the starting polynomials). Opening 🤷🏻: proving the value of the $i$th element in the array is $\\mathsf{data}_i$ doing polynomial math on $P_1(\\square)$ is not possible. However $\\Sigma$-protocols done directly on KZG may enable this kind of proof. In any case, this is not particularly well explored. Other useful properties 👍: the sum of all values in a array can be computed by evaluating the polynomial at $P_1(\\boxed{1})$! $\\sum_{i=0}^d \\mathsf{data}_i\\cdot\\boxed{1}^i=\\sum_{i=0}^d \\mathsf{data}_i$ . You can also show two arrays have the same sum (called a \u0026ldquo;sum check\u0026rdquo;) by subtracting them and showing $P(\\boxed{1})=0$. Other useful properties 👍: when all coefficients are 0, the polynomial will be the zero polynomial ($P_1(\\square)=0$). Coefficients can be entire polynomials, not just integers. A common optimization in Poly-IOP systems is taking a set of equations of polynomials that should equal 0, placing each into the coefficient of a super-polynomial, and showing the super-polynomial is the zero polynomial (which can be proven overwhelmingly by showing it is 0 at a randomly selected point). Encoding 2: Evaluation Points # Create a list of points $\\{x,y\\}$ for the data: $\\langle\\{0,\\mathsf{data}_0\\},\\{1,\\mathsf{data}_1\\},\\{2,\\mathsf{data}_2\\},\\{3,\\mathsf{data}_3\\},\\{4,\\mathsf{data}_4\\}\\rangle$ and interpolate a polynomial $P_2(\\square)$ through these points.\nProperties:\nSlow (or moderate) 👎: converting a set of points into a set of coefficients is called interpolation and is $O(n^2)$ time generally. A certain optimization allows $O(n\\log n)$ time by chosing $x$ coordinates with a mathematical relationship (more on this later). Addition 👍: two arrays can be added together (slot-by-slot) by simply adding the polynomials together Multiplication 👍: two arrays can be multiplied together (slot-by-slot) by simply multiplying the polynomials together Opening 👍: proving the value of the $i$th element in the array is $\\mathsf{data}_i$ is possible with polynomial math by showing $P_2(\\boxed{i})=\\mathsf{data}_i$ and KZG has a precise algorithm for this. Encoding 3: Roots # Create polynomial as: $P_3(\\square)=(\\square-\\mathsf{data}_0)(\\square-\\mathsf{data}_1)(\\square-\\mathsf{data}_2)(\\square-\\mathsf{data}_3)(\\square-\\mathsf{data}_4)$\nAlternatively, create a list of roots $\\{x,0\\}$ for the data: $\\langle\\{\\mathsf{data}_0,0\\},\\{\\mathsf{data}_1,0\\},\\{\\mathsf{data}_2,0\\},\\{\\mathsf{data}_3,0\\},\\{\\mathsf{data}_4,0\\}\\rangle$ and interpolate a polynomial $P_3(\\square)$ through these points.\nProperties:\nSlow 👎 (or moderate): multiplying out naively requires $O(n^2)$ time. Treating as a set of points and interpolating also requires $O(n^2)$ time (because the x-coordinates are the data, they cannot be chosen freely to optimize interpolation). Applying divide and conquer can provide $O(n \\log^2 n)$.^[1] Addition 👎: two arrays cannot be added from adding (or otherwise manipulating) the polynomials. Multiplication 👎: two arrays cannot be multiplied from multiplying (or otherwise manipulating) the polynomials (but you can do a \u0026ldquo;union\u0026rdquo; operation below). Opening 👍: proving that a value is in the array somewhere is easy and KZG as a precise algorithm for this (opening a root is the same as opening a point, where the y-coordinate is 0). However you cannot show a value is specifically the $i$th value in the array because the polynomial loses the order of the data in the array (see next property). Other useful properties 👍: the order of the data in the array does not matter. The same polynomial will be produced even if the order is changed. This is useful when the array represents a \u0026ldquo;bag\u0026rdquo; of unordered data. You can easily prove two \u0026ldquo;bags\u0026rdquo; of data are the same because the polynomials will be the same. One use-case of this is proving the output of a shuffle/permutation is the same data as the input (just in a different order). Other useful properties 👍: multiplying two polynomials results in a concatenation of the data in the arrays (or conjunction/union of the data in both bags). This might be useful in some protocols. Decision Tree for Encoding # Basically we decide if we specifically need unordered \u0026ldquo;bags\u0026rdquo; of data. If so, encoding as roots is the only option. If not, we consider if we need to ever get the data back from the polynomial. Generally we do and encoding as evaluation points is the most common encoding technique. When do we encode the data and never want it back? Usually when (1) the coefficients are all supposed to be zero so we are just showing that property, or (2) we want back the sum of the data and not the data itself. In these cases, you can still work with evaluation point encoding but it will be faster to just do coefficient encoding.\nflowchart LR; A[Array to Polynomial] --\u003e B{Is the data unordered?}; B -- Unordered --\u003e C[Roots]; B -- Ordered or don't care --\u003e D{Open data from polynomial later?}; D -- Yes --\u003e E[Evaluation Points]; D -- No --\u003e F[Coefficients]; The short answer is to start with evaluation point encoding until you realize you need something different.\nRoots of Unity # Moving forward, we will assume we are using Encoding 2: Evaluation Points. In short, this means placing the elements of our array into the $y$-coordinates ($\\mathsf{data}_i=P(\\boxed{x_i})$) of points on the polynomial. Before commiting to $P(\\square)$, we need to use interpolation to find the coefficients of the polynomial that is fitted to these points. General interpolation algorithms are $O(n^2)$ work for $n$ evaluation points but this can be reduced to $O(n\\log n)$ with an optimization.\nThe optimization we will explore enables interpolation via the fast Fourier transform (FFT). It concerns how to choose the $x$-coordinates, which will serve as the index for accessing the data: evaluating $P(X)$ at $x_i$ will reveal $\\mathsf{data}_i$. First note, $x$-coordinates are from the exponent group ($Z_q$) and the choices exceed what is feasible to use ($2^{255}$ values in bls). Any subset can be used and interpolated. The optimization is to chose them with a mathematical structure. Specifically, instead an additive sequence (e.g., $0,1,2,3,\\ldots$), we use a multiplicative sequence $1,\\omega,\\omega\\cdot\\omega,\\omega\\cdot\\omega\\cdot\\omega,\\ldots$ or equivalently: $\\omega^0,\\omega^1,\\omega^2,\\ldots,\\omega^{\\kappa-1}$. Further, the sequence is closed under multiplication which means that next index after $\\omega^{\\kappa-1}$ wraps back to the first index: $\\omega^{k-1} \\cdot \\omega = \\omega^\\kappa = \\omega^0=1$ (this property is also useful in proving relationships between data in the array and its neighbouring values).\nFor terminology, we say $\\omega$ is a generator with multiplicative order $\\kappa$ in $\\mathbb{Z}_q$ (or $\\omega \\in \\mathbb{G}_\\kappa$). This implies $\\omega^\\kappa=1$. Rearranging, $\\omega=\\sqrt[\\kappa]{1}$. Thus we can equivalently describe $\\omega$ as a $\\kappa$-th root of 1. Finally, as 1 is the unity element in $Z_q$, $\\omega$ is commonly called a $\\kappa$-th root of unity.\nFor practical purposes, $\\kappa$ represents the length of the longest array of data we can use in our protocol. Where does $\\kappa$ come from? Different elements of $Z_q$ will have different multiplicative orders but every order must be a divisor of $q-1$. Thus $\\kappa$ is the largest divisor of the exact value of $q$ used in an elliptic curve standard. BLS12-384 has $\\kappa=2^{32}$ (for terminology, this called a $2$-adicity of $32$). In summary, we can only encode data arrays of length up to $2^{32}=4,294,967,296$.\nInterpolation via FFT # Background # FFT is a fast algorithm for transitions between coefficients (Encoding 1) and evaluation points (Encoding 2) .\nflowchart LR co[coefficients] points[points] co --evaluation--\u0026gt; points points --interpolation--\u0026gt; co Polynomials, interpolation, and Fourier transforms are all big topics that have general theories and applications. This article will not try to explain anything in its full generality. Instead we will simplify as much as possible, limiting ourselves to only what we need for many cryptographic applications.\nHere are the simplifications:\nWe only use integers. No real numbers. No imaginary numbers. Integers are from a bounded range: $[0,q-1]$ or $\\mathbb{Z}_q$ for a large (e.g., 256 bit) prime $q$. Polynomials are univariate (only one variable). Worked Example: Evaluation # Assume $q=97$.\nWe will start with the more intuitive direction: going from a polynomial in coefficient form to a set of points on the polynomial. Consider the following polynomial in coefficient form: $$ P(\\square)=81 \\square^7+57 \\square^6+11 \\square^5+59 \\square^4+60 \\square^3+83 \\square^2+45 \\square+44 $$ In this case, the list of coefficients (from least to greatest) is $\\{44,45,83,60,59,11,57,81\\}$. The degree of the polynomial is 7 and the number of coefficients is 8. Our goal is determine 8 unique points of form ($x_i, y_i=P(x_i))$. Why 8? We need 8 points to fully determine a degree 7 polynomial, so this will let us reverse the process (go from points to coefficients) in the future if need to.\n(Remark: Think of a straight line. It is of form $P(\\square)=c_1\\square+c_0$ which is degree $1$ with $2$ coefficients. You need $2$ points to figure out what the line should be. Generalizing, for a degree $d$ polynomial, $d+1$ coefficients or $d+1$ points are needed to fully determine it.)\nSo the goal is to find $8$ points on the polynomial $P(\\square)$. The points can be at any x-coordinates so we will chose $\\{1,2,3,4,5,6,7,8\\}$ for now. We call this the domain. Finding the points is a simple as plugging the x-coordinates into the $P(\\square)$ equation:\n$$ \\begin{alignat}{1} P(\\boxed{1})=81 \\boxed{1}^7+57 \\boxed{1}^6+11 \\boxed{1}^5+59 \\boxed{1}^4+60 \\boxed{1}^3+83 \\boxed{1}^2+45 \\boxed{1}+44=52 \\\\ P(\\boxed{2})=81 \\boxed{2}^7+57 \\boxed{2}^6+11 \\boxed{2}^5+59 \\boxed{2}^4+60 \\boxed{2}^3+83 \\boxed{2}^2+45 \\boxed{2}+44=59 \\\\ P(\\boxed{3})=81 \\boxed{3}^7+57 \\boxed{3}^6+11 \\boxed{3}^5+59 \\boxed{3}^4+60 \\boxed{3}^3+83 \\boxed{3}^2+45 \\boxed{3}+44=69 \\\\ P(\\boxed{4})=81 \\boxed{4}^7+57 \\boxed{4}^6+11 \\boxed{4}^5+59 \\boxed{4}^4+60 \\boxed{4}^3+83 \\boxed{4}^2+45 \\boxed{4}+44=81 \\\\ P(\\boxed{5})=81 \\boxed{5}^7+57 \\boxed{5}^6+11 \\boxed{5}^5+59 \\boxed{5}^4+60 \\boxed{5}^3+83 \\boxed{5}^2+45 \\boxed{5}+44=12 \\\\ P(\\boxed{6})=81 \\boxed{6}^7+57 \\boxed{6}^6+11 \\boxed{6}^5+59 \\boxed{6}^4+60 \\boxed{6}^3+83 \\boxed{6}^2+45 \\boxed{6}+44=15 \\\\ P(\\boxed{7})=81 \\boxed{7}^7+57 \\boxed{7}^6+11 \\boxed{7}^5+59 \\boxed{7}^4+60 \\boxed{7}^3+83 \\boxed{7}^2+45 \\boxed{7}+44=92 \\\\ P(\\boxed{8})=81 \\boxed{8}^7+57 \\boxed{8}^6+11 \\boxed{8}^5+59 \\boxed{8}^4+60 \\boxed{8}^3+83 \\boxed{8}^2+45 \\boxed{8}+44=36 \\\\ \\end{alignat} $$ In more succinct form, we are moving between a list of 8 coefficients and a list of 8 points on the polynomial.\n$$ \\left( \\begin{array}{cccccccc} 44 \u0026 45 \u0026 83 \u0026 60 \u0026 59 \u0026 11 \u0026 57 \u0026 81 \\\\ \\end{array} \\right) \\leftrightarrow \\left( \\begin{array}{cccccccc} 1 \u0026 2 \u0026 3 \u0026 4 \u0026 5 \u0026 6 \u0026 7 \u0026 8 \\\\ 52 \u0026 59 \u0026 69 \u0026 81 \u0026 12 \u0026 15 \u0026 92 \u0026 36 \\\\ \\end{array} \\right) $$ Before figuring out how to go backward, we are going redo the same thing one more time, this time using matrix notation. The equivalent computation we just did is the following:\n$$ \\left( \\begin{array}{cccccccc} \\boxed{1}^0 \u0026 \\boxed{1}^1 \u0026 \\boxed{1}^2 \u0026 \\boxed{1}^3 \u0026 \\boxed{1}^4 \u0026 \\boxed{1}^5 \u0026 \\boxed{1}^6 \u0026 \\boxed{1}^7\\\\ \\boxed{2}^0 \u0026 \\boxed{2}^1 \u0026 \\boxed{2}^2 \u0026 \\boxed{2}^3 \u0026 \\boxed{2}^4 \u0026 \\boxed{2}^5 \u0026 \\boxed{2}^6 \u0026 \\boxed{2}^7\\\\ \\boxed{3}^0 \u0026 \\boxed{3}^1 \u0026 \\boxed{3}^2 \u0026 \\boxed{3}^3 \u0026 \\boxed{3}^4 \u0026 \\boxed{3}^5 \u0026 \\boxed{3}^6 \u0026 \\boxed{3}^7\\\\ \\boxed{4}^0 \u0026 \\boxed{4}^1 \u0026 \\boxed{4}^2 \u0026 \\boxed{4}^3 \u0026 \\boxed{4}^4 \u0026 \\boxed{4}^5 \u0026 \\boxed{4}^6 \u0026 \\boxed{4}^7\\\\ \\boxed{5}^0 \u0026 \\boxed{5}^1 \u0026 \\boxed{5}^2 \u0026 \\boxed{5}^3 \u0026 \\boxed{5}^4 \u0026 \\boxed{5}^5 \u0026 \\boxed{5}^6 \u0026 \\boxed{5}^7\\\\ \\boxed{6}^0 \u0026 \\boxed{6}^1 \u0026 \\boxed{6}^2 \u0026 \\boxed{6}^3 \u0026 \\boxed{6}^4 \u0026 \\boxed{6}^5 \u0026 \\boxed{6}^6 \u0026 \\boxed{6}^7\\\\ \\boxed{7}^0 \u0026 \\boxed{7}^1 \u0026 \\boxed{7}^2 \u0026 \\boxed{7}^3 \u0026 \\boxed{7}^4 \u0026 \\boxed{7}^5 \u0026 \\boxed{7}^6 \u0026 \\boxed{7}^7\\\\ \\boxed{8}^0 \u0026 \\boxed{8}^1 \u0026 \\boxed{8}^2 \u0026 \\boxed{8}^3 \u0026 \\boxed{8}^4 \u0026 \\boxed{8}^5 \u0026 \\boxed{8}^6 \u0026 \\boxed{8}^7\\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} ? \\\\ ? \\\\ ? \\\\ ? \\\\ ? \\\\ ? \\\\ ? \\\\ ? \\\\ \\end{array} \\right) $$ Evaluating it:\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \u0026 16 \u0026 32 \u0026 64 \u0026 31 \\\\ 1 \u0026 3 \u0026 9 \u0026 27 \u0026 81 \u0026 49 \u0026 50 \u0026 53 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \u0026 62 \u0026 54 \u0026 22 \u0026 88 \\\\ 1 \u0026 5 \u0026 25 \u0026 28 \u0026 43 \u0026 21 \u0026 8 \u0026 40 \\\\ 1 \u0026 6 \u0026 36 \u0026 22 \u0026 35 \u0026 16 \u0026 96 \u0026 91 \\\\ 1 \u0026 7 \u0026 49 \u0026 52 \u0026 73 \u0026 26 \u0026 85 \u0026 13 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \u0026 22 \u0026 79 \u0026 50 \u0026 12 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} 52 \\\\ 59 \\\\ 69 \\\\ 81 \\\\ 12 \\\\ 15 \\\\ 92 \\\\ 36 \\\\ \\end{array} \\right) $$ Efficiency # Let\u0026rsquo;s pause for a moment and think about efficiency. First, consider the matrix: it does not depend on the polynomial values at all. It only depends on the domain (or set of x-values) that you want to evaluate the points at. The domain can be decided ahead of time (e.g., we will always use a domain of 1, 2, 3, \u0026hellip;) and then the matrix can be computed at that time. From a protocol perspective, the matrix can be pre-computed and can be shared between operations on polynomials of the same degree.\nThe multiplication is clearly $O(n^2)$ where $n$ is the number of coefficients/evaluation points. The whole point of FFT to reduce the work to $O(n \\cdot \\log_2{n})$ and that is it. In a world where efficiency is not a concern, you can just do the above and ignore FFT.\nCryptography # Moving back to cryptography, imagine you have the polynomial in encrypted (or committed or secret shared) form and this encryption is additively homomorphic. To compute the evaluation points under encryption only involves multiplying in known values from the matrix (which are not secret and depend only on the domain), and then doing additions under encryption. Therefore we can evaluate (and, as you will see below, interpolate) under encryption. Sometimes doing things on the points of a polynomial is simpler than on the polynomials themselves (e.g., multiplying polynomials were you only care about a subset of the points on the polynomial). And vice-versa (rotating an array of values: if encode values into a set of polynomial points, interpolate it, multiply in some constants into the polynomial coefficients, and convert back to points, the array will be rotated).\nJargon # A matrix with the above form is called a Vandermonde matrix. This process is called a discrete Fourier transform (or DFT). FFT is a special case of DFT and is faster.\nWorked Example: Interpolation # Now assume we have a set of points and want to go backwards to determine the coefficients:\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 2 \u0026 3 \u0026 4 \u0026 5 \u0026 6 \u0026 7 \u0026 8 \\\\ 52 \u0026 59 \u0026 69 \u0026 81 \u0026 12 \u0026 15 \u0026 92 \u0026 36 \\\\ \\end{array} \\right) \\rightarrow \\left( \\begin{array}{cccccccc} 44 \u0026 45 \u0026 83 \u0026 60 \u0026 59 \u0026 11 \u0026 57 \u0026 81 \\\\ \\end{array} \\right) $$ Placing the evaluation process into matrix multiplication makes interpolation very easy to understand. We simply move the matrix to the other side of the equation, which involves inverting it. Above, we did the following (coefficients to points):\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \u0026 16 \u0026 32 \u0026 64 \u0026 31 \\\\ 1 \u0026 3 \u0026 9 \u0026 27 \u0026 81 \u0026 49 \u0026 50 \u0026 53 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \u0026 62 \u0026 54 \u0026 22 \u0026 88 \\\\ 1 \u0026 5 \u0026 25 \u0026 28 \u0026 43 \u0026 21 \u0026 8 \u0026 40 \\\\ 1 \u0026 6 \u0026 36 \u0026 22 \u0026 35 \u0026 16 \u0026 96 \u0026 91 \\\\ 1 \u0026 7 \u0026 49 \u0026 52 \u0026 73 \u0026 26 \u0026 85 \u0026 13 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \u0026 22 \u0026 79 \u0026 50 \u0026 12 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} 52 \\\\ 59 \\\\ 69 \\\\ 81 \\\\ 12 \\\\ 15 \\\\ 92 \\\\ 36 \\\\ \\end{array} \\right) $$ To do interpolation (points to coefficients), we move the matrix to the other side of the equation:\n$$ \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \u0026 16 \u0026 32 \u0026 64 \u0026 31 \\\\ 1 \u0026 3 \u0026 9 \u0026 27 \u0026 81 \u0026 49 \u0026 50 \u0026 53 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \u0026 62 \u0026 54 \u0026 22 \u0026 88 \\\\ 1 \u0026 5 \u0026 25 \u0026 28 \u0026 43 \u0026 21 \u0026 8 \u0026 40 \\\\ 1 \u0026 6 \u0026 36 \u0026 22 \u0026 35 \u0026 16 \u0026 96 \u0026 91 \\\\ 1 \u0026 7 \u0026 49 \u0026 52 \u0026 73 \u0026 26 \u0026 85 \u0026 13 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \u0026 22 \u0026 79 \u0026 50 \u0026 12 \\\\ \\end{array} \\right)^{-1} \\cdot \\left( \\begin{array}{c} 52 \\\\ 59 \\\\ 69 \\\\ 81 \\\\ 12 \\\\ 15 \\\\ 92 \\\\ 36 \\\\ \\end{array} \\right) $$ Solving the inverse matrix, we arrive at:\n$$ \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{cccccccc} 8 \u0026 69 \u0026 56 \u0026 27 \u0026 56 \u0026 69 \u0026 8 \u0026 96 \\\\ 50 \u0026 33 \u0026 54 \u0026 3 \u0026 53 \u0026 10 \u0026 57 \u0026 31 \\\\ 7 \u0026 70 \u0026 8 \u0026 86 \u0026 20 \u0026 39 \u0026 76 \u0026 82 \\\\ 47 \u0026 89 \u0026 24 \u0026 11 \u0026 90 \u0026 12 \u0026 37 \u0026 78 \\\\ 85 \u0026 57 \u0026 80 \u0026 34 \u0026 90 \u0026 63 \u0026 71 \u0026 5 \\\\ 55 \u0026 85 \u0026 43 \u0026 77 \u0026 2 \u0026 67 \u0026 91 \u0026 65 \\\\ 64 \u0026 11 \u0026 45 \u0026 86 \u0026 44 \u0026 12 \u0026 22 \u0026 7 \\\\ 73 \u0026 71 \u0026 78 \u0026 64 \u0026 33 \u0026 19 \u0026 26 \u0026 24 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 52 \\\\ 59 \\\\ 69 \\\\ 81 \\\\ 12 \\\\ 15 \\\\ 92 \\\\ 36 \\\\ \\end{array} \\right) $$ Can we always invert the matrix? The answer is yes, assuming each row of the matrix is unique, which is to say, each evaluation point is unique (no repeats). The complexity analysis is the same as evaluation: the matrix can be pre-computed and the multiplication is $O(n^2)$. The FFT trick will work equally well on this matrix.\nJargon # This process is called the inverse discrete Fourier transform (or iDFT). If each column of the matrix is taken to be a coefficient list of a polynomial, such polynomials are called Lagrange polynomials.\nSpeeding up evaluation and interpolation # Divide-and-conquer # The high level idea of speeding up both processes is called divide-and-conquer. Recall this equation:\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \u0026 16 \u0026 32 \u0026 64 \u0026 31 \\\\ 1 \u0026 3 \u0026 9 \u0026 27 \u0026 81 \u0026 49 \u0026 50 \u0026 53 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \u0026 62 \u0026 54 \u0026 22 \u0026 88 \\\\ 1 \u0026 5 \u0026 25 \u0026 28 \u0026 43 \u0026 21 \u0026 8 \u0026 40 \\\\ 1 \u0026 6 \u0026 36 \u0026 22 \u0026 35 \u0026 16 \u0026 96 \u0026 91 \\\\ 1 \u0026 7 \u0026 49 \u0026 52 \u0026 73 \u0026 26 \u0026 85 \u0026 13 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \u0026 22 \u0026 79 \u0026 50 \u0026 12 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} 52 \\\\ 59 \\\\ 69 \\\\ 81 \\\\ 12 \\\\ 15 \\\\ 92 \\\\ 36 \\\\ \\end{array} \\right) $$ What if we split this up? For example, say we find the evaluation at $\\{1,2,3,4\\}$ using the first four coefficients $\\{44,45,83,60\\}$, then we find the evaluation at $\\{5,6,7,8\\}$ using the last four coefficients $\\{59,11,57,81\\}$:\n$$ \\left( \\begin{array}{cccc} 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \\\\ 1 \u0026 3 \u0026 9 \u0026 27 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} 38 \\\\ 73 \\\\ 24 \\\\ 57 \\\\ \\end{array} \\right) $$ $$ \\left( \\begin{array}{cccc} 1 \u0026 5 \u0026 25 \u0026 28 \\\\ 1 \u0026 6 \u0026 36 \u0026 22 \\\\ 1 \u0026 7 \u0026 49 \u0026 52 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} 24 \\\\ 79 \\\\ 60 \\\\ 65 \\\\ \\end{array} \\right) $$ Next, we need some way to combine $\\{38,73,24,57\\}$ and $\\{24, 79, 60, 65\\}$ to generate $\\{52,59,69,81,12,15,92,36\\}$ (that does not add a bunch more work). Assume we can pull this off, then we can recurse using this trick. Instead of directly computing the above two equations (involving two 4x4 matricies), we can split each of them into 2x2 matrices (for a total of four) using the same process. There is just one problem: there isn\u0026rsquo;t a simple algorithm for the combine step (faster than just computing the entire original matrix) that is going to work for us.\nOne parameter we can change # Reconsider the original problem, moving between coefficients (left) and evaluation points (right): $$ \\left( \\begin{array}{cccccccc} 44 \u0026 45 \u0026 83 \u0026 60 \u0026 59 \u0026 11 \u0026 57 \u0026 81 \\\\ \\end{array} \\right) \\leftrightarrow \\left( \\begin{array}{cccccccc} 1 \u0026 2 \u0026 3 \u0026 4 \u0026 5 \u0026 6 \u0026 7 \u0026 8 \\\\ 52 \u0026 59 \u0026 69 \u0026 81 \u0026 12 \u0026 15 \u0026 92 \u0026 36 \\\\ \\end{array} \\right) $$ We cannot control the coefficients of the polynomial — they are what they are. What the polynomial evaluates to at $\\{1,2,3,\\ldots\\}$ is also what it is, we cannot control it. However the one thing we did get to choose is $\\{1,2,3,\\ldots\\}$ itself (which we call the domain). We can map between coefficients and any domain, assuming there are 8 unique evaluation points. They do not have to be these specific points. So the question is, are there a different set of points that are \u0026ldquo;nicer\u0026rdquo; to deal with than $\\{1,2,3,\\ldots\\}$?\nThe domain shows up in the second column of the matrix:\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \u0026 16 \u0026 32 \u0026 64 \u0026 31 \\\\ 1 \u0026 3 \u0026 9 \u0026 27 \u0026 81 \u0026 49 \u0026 50 \u0026 53 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \u0026 62 \u0026 54 \u0026 22 \u0026 88 \\\\ 1 \u0026 5 \u0026 25 \u0026 28 \u0026 43 \u0026 21 \u0026 8 \u0026 40 \\\\ 1 \u0026 6 \u0026 36 \u0026 22 \u0026 35 \u0026 16 \u0026 96 \u0026 91 \\\\ 1 \u0026 7 \u0026 49 \u0026 52 \u0026 73 \u0026 26 \u0026 85 \u0026 13 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \u0026 22 \u0026 79 \u0026 50 \u0026 12 \\\\ \\end{array} \\right) $$ What if we make the points (the second column) the same values as the second row of the table: a domain of $\\{1,2,4,8,16,32,64,31\\}$? In this case, we will get a symmetric matrix which is a little \u0026ldquo;nicer\u0026rdquo; than one that is asymmetric. We will show both the matrix (using for evaluation) and its inverse (used for interpolation):\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 2 \u0026 4 \u0026 8 \u0026 16 \u0026 32 \u0026 64 \u0026 31 \\\\ 1 \u0026 4 \u0026 16 \u0026 64 \u0026 62 \u0026 54 \u0026 22 \u0026 88 \\\\ 1 \u0026 8 \u0026 64 \u0026 27 \u0026 22 \u0026 79 \u0026 50 \u0026 12 \\\\ 1 \u0026 16 \u0026 62 \u0026 22 \u0026 61 \u0026 6 \u0026 96 \u0026 81 \\\\ 1 \u0026 32 \u0026 54 \u0026 79 \u0026 6 \u0026 95 \u0026 33 \u0026 86 \\\\ 1 \u0026 64 \u0026 22 \u0026 50 \u0026 96 \u0026 33 \u0026 75 \u0026 47 \\\\ 1 \u0026 31 \u0026 88 \u0026 12 \u0026 81 \u0026 86 \u0026 47 \u0026 2 \\\\ \\end{array} \\right)= \\left( \\begin{array}{cccccccc} 32 \u0026 41 \u0026 79 \u0026 38 \u0026 34 \u0026 89 \u0026 74 \u0026 2 \\\\ 41 \u0026 29 \u0026 45 \u0026 70 \u0026 42 \u0026 46 \u0026 25 \u0026 90 \\\\ 79 \u0026 45 \u0026 2 \u0026 66 \u0026 43 \u0026 95 \u0026 14 \u0026 44 \\\\ 38 \u0026 70 \u0026 66 \u0026 2 \u0026 44 \u0026 89 \u0026 60 \u0026 19 \\\\ 34 \u0026 42 \u0026 43 \u0026 44 \u0026 47 \u0026 25 \u0026 22 \u0026 34 \\\\ 89 \u0026 46 \u0026 95 \u0026 89 \u0026 25 \u0026 81 \u0026 76 \u0026 81 \\\\ 74 \u0026 25 \u0026 14 \u0026 60 \u0026 22 \u0026 76 \u0026 15 \u0026 5 \\\\ 2 \u0026 90 \u0026 44 \u0026 19 \u0026 34 \u0026 81 \u0026 5 \u0026 16 \\\\ \\end{array} \\right)^{-1} $$ This is nice but once we invert the matrix, is not symmetric any more. Is there a matrix where both the original and its inverse are symmetric? The answer is yes! Consider the domain $\\{1,33,22,47,96,64,75,50\\}$:\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 33 \u0026 22 \u0026 47 \u0026 96 \u0026 64 \u0026 75 \u0026 50 \\\\ 1 \u0026 22 \u0026 96 \u0026 75 \u0026 1 \u0026 22 \u0026 96 \u0026 75 \\\\ 1 \u0026 47 \u0026 75 \u0026 33 \u0026 96 \u0026 50 \u0026 22 \u0026 64 \\\\ 1 \u0026 96 \u0026 1 \u0026 96 \u0026 1 \u0026 96 \u0026 1 \u0026 96 \\\\ 1 \u0026 64 \u0026 22 \u0026 50 \u0026 96 \u0026 33 \u0026 75 \u0026 47 \\\\ 1 \u0026 75 \u0026 96 \u0026 22 \u0026 1 \u0026 75 \u0026 96 \u0026 22 \\\\ 1 \u0026 50 \u0026 75 \u0026 64 \u0026 96 \u0026 47 \u0026 22 \u0026 33 \\\\ \\end{array} \\right)= \\left( \\begin{array}{cccccccc} 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \\\\ 85 \u0026 79 \u0026 70 \u0026 8 \u0026 12 \u0026 18 \u0026 27 \u0026 89 \\\\ 85 \u0026 70 \u0026 12 \u0026 27 \u0026 85 \u0026 70 \u0026 12 \u0026 27 \\\\ 85 \u0026 8 \u0026 27 \u0026 79 \u0026 12 \u0026 89 \u0026 70 \u0026 18 \\\\ 85 \u0026 12 \u0026 85 \u0026 12 \u0026 85 \u0026 12 \u0026 85 \u0026 12 \\\\ 85 \u0026 18 \u0026 70 \u0026 89 \u0026 12 \u0026 79 \u0026 27 \u0026 8 \\\\ 85 \u0026 27 \u0026 12 \u0026 70 \u0026 85 \u0026 27 \u0026 12 \u0026 70 \\\\ 85 \u0026 89 \u0026 27 \u0026 18 \u0026 12 \u0026 8 \u0026 70 \u0026 79 \\\\ \\end{array} \\right)^{-1} $$ With this new domain and the same coefficients, we can find the evaluation points:\n$$ \\left( \\begin{array}{cccccccc} 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \u0026 1 \\\\ 1 \u0026 33 \u0026 22 \u0026 47 \u0026 96 \u0026 64 \u0026 75 \u0026 50 \\\\ 1 \u0026 22 \u0026 96 \u0026 75 \u0026 1 \u0026 22 \u0026 96 \u0026 75 \\\\ 1 \u0026 47 \u0026 75 \u0026 33 \u0026 96 \u0026 50 \u0026 22 \u0026 64 \\\\ 1 \u0026 96 \u0026 1 \u0026 96 \u0026 1 \u0026 96 \u0026 1 \u0026 96 \\\\ 1 \u0026 64 \u0026 22 \u0026 50 \u0026 96 \u0026 33 \u0026 75 \u0026 47 \\\\ 1 \u0026 75 \u0026 96 \u0026 22 \u0026 1 \u0026 75 \u0026 96 \u0026 22 \\\\ 1 \u0026 50 \u0026 75 \u0026 64 \u0026 96 \u0026 47 \u0026 22 \u0026 33 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{c} 52 \\\\ 13 \\\\ 33 \\\\ 27 \\\\ 46 \\\\ 34 \\\\ 87 \\\\ 60 \\\\ \\end{array} \\right) $$ Or we can find the coefficients, given the evaluation points:\n$$ \\left( \\begin{array}{c} 44 \\\\ 45 \\\\ 83 \\\\ 60 \\\\ 59 \\\\ 11 \\\\ 57 \\\\ 81 \\\\ \\end{array} \\right)= \\left( \\begin{array}{cccccccc} 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \u0026 85 \\\\ 85 \u0026 79 \u0026 70 \u0026 8 \u0026 12 \u0026 18 \u0026 27 \u0026 89 \\\\ 85 \u0026 70 \u0026 12 \u0026 27 \u0026 85 \u0026 70 \u0026 12 \u0026 27 \\\\ 85 \u0026 8 \u0026 27 \u0026 79 \u0026 12 \u0026 89 \u0026 70 \u0026 18 \\\\ 85 \u0026 12 \u0026 85 \u0026 12 \u0026 85 \u0026 12 \u0026 85 \u0026 12 \\\\ 85 \u0026 18 \u0026 70 \u0026 89 \u0026 12 \u0026 79 \u0026 27 \u0026 8 \\\\ 85 \u0026 27 \u0026 12 \u0026 70 \u0026 85 \u0026 27 \u0026 12 \u0026 70 \\\\ 85 \u0026 89 \u0026 27 \u0026 18 \u0026 12 \u0026 8 \u0026 70 \u0026 79 \\\\ \\end{array} \\right) \\cdot \\left( \\begin{array}{c} 52 \\\\ 13 \\\\ 33 \\\\ 27 \\\\ 46 \\\\ 34 \\\\ 87 \\\\ 60 \\\\ \\end{array} \\right) $$ In summary:\n$$ \\left( \\begin{array}{cccccccc} 44 \u0026 45 \u0026 83 \u0026 60 \u0026 59 \u0026 11 \u0026 57 \u0026 81 \\\\ \\end{array} \\right) \\leftrightarrow \\left( \\begin{array}{cccccccc} 1 \u0026 33 \u0026 22 \u0026 47 \u0026 96 \u0026 64 \u0026 75 \u0026 50 \\\\ 52 \u0026 13 \u0026 33 \u0026 27 \u0026 46 \u0026 34 \u0026 87 \u0026 60 \\\\ \\end{array} \\right) $$ Two questions:\nHow did we find the domain $\\{1,33,22,47,96,64,75,50\\}$? If we use $\\{1,33,22,47,96,64,75,50\\}$, can we do the divide-and-conquer strategy? Is there a combine function that is workable and efficient for these \u0026ldquo;nice\u0026rdquo; matrices? Generating symmetric matrices # $\\{1,33,22,47,96,64,75,50\\}$ is a special form. It is of the form $\\{\\omega^0,\\omega^1,\\omega^2,\\omega^3,\\omega^4,\\omega^5,\\omega^6,\\omega^7\\}$ where $\\omega=33$. Why 33? The size of the domain is $8$, so we choose 33 because the multiplicative order of $\\omega=33$ in $q=97$ is also $8$. Equivalently (in different jargon):\n33 is a generator that generates a multiplicative subgroup of size 8 (mod 97) 33 is an 8-th root of unity of 97 So the trick is setting the $x$-values to be generators of a subgroup of the same size as the number of points/coefficients you have. Here we have 8, so we found a generator of order 8.\nCan we find a generator of order 9 or 10 or 11 instead? The answer is no. Only certain sized subgroups exist. What dictates it? The answer is the value of $q$. Once $q$ is chosen, then the sizes of subgroups are locked in. Specifically the sizes available are the divisors of $q-1$. So if we factor $96$, we get $96=2^5\\cdot3$. That means we have subgroups of size: $\\{1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 96\\}$. The value of $q$ for cryptography depends on the elliptic curve used. Something like $\\texttt{bls12-381}$ uses a $q$ that purposefully has lots of subgroups: $\\{2,4,8,\\ldots,2^{32}\\}$.\nThe idea is that you find the degree of your polynomial $d$, then you need $d+1$ coefficients/points to represent it, and then you round $d+1$ up to the nearest power of 2 as necessary. The leading coefficients are set to 0.\nRevisiting divide-and-conquer # The remaining question is whether we can split the matrices into smaller (halve) matrices, and then combine the results. The answer is yes if the domain is based on roots of unity (for completeness, the answer is not necessarily no for other kinds of domains, but we do not explore that here).\nRecall, with the new domain, we have:\n$$ \\left( \\begin{array}{cccccccc} 44 \u0026 45 \u0026 83 \u0026 60 \u0026 59 \u0026 11 \u0026 57 \u0026 81 \\\\ \\end{array} \\right) \\leftrightarrow \\left( \\begin{array}{cccccccc} 1 \u0026 33 \u0026 22 \u0026 47 \u0026 96 \u0026 64 \u0026 75 \u0026 50 \\\\ 52 \u0026 13 \u0026 33 \u0026 27 \u0026 46 \u0026 34 \u0026 87 \u0026 60 \\\\ \\end{array} \\right) $$ Instead of dividing the coefficients into the first half and second halves, we will divide them into even coefficients (coefficients of terms $x^i$ where $i$ is even, including 0) and odd coefficients. We treat these two sets of coefficients as new polynomials $P_\\mathsf{even}(\\square)$ and $P_\\mathsf{odd}(\\square)$. Then we combine the two based on the following property:\n$$ P(\\square)=P_{\\mathsf{even}}(\\square^2)+\\square\\cdot P_{\\mathsf{odd}}(\\square^2) $$ How does this save computation? We compute the following values:\n$$ \\begin{alignat}{1} P_\\mathsf{even}(\\boxed{\\omega^0}^2)=P_\\mathsf{even}(1)=57 \\boxed{1}^3+59 \\boxed{1}^2+83 \\boxed{1}^1+44=49 \\\\ P_\\mathsf{even}(\\boxed{\\omega^1}^2)=P_\\mathsf{even}(22)=57 \\boxed{22}^3+59 \\boxed{22}^2+83 \\boxed{22}^1+44=72 \\\\ P_\\mathsf{even}(\\boxed{\\omega^2}^2)=P_\\mathsf{even}(96)=57 \\boxed{96}^3+59 \\boxed{96}^2+83 \\boxed{96}^1+44=60 \\\\ P_\\mathsf{even}(\\boxed{\\omega^3}^2)=P_\\mathsf{even}(75)=57 \\boxed{75}^3+59 \\boxed{75}^2+83 \\boxed{75}^1+44=92 \\\\ \\hline P_\\mathsf{odd}(\\boxed{\\omega^0}^2)=P_\\mathsf{odd}(1)=81\\boxed{1}^3+11\\boxed{1}^2+60\\boxed{1}^1+45=3 \\\\ P_\\mathsf{odd}(\\boxed{\\omega^1}^2)=P_\\mathsf{odd}{(22})= 81\\boxed{22}^3+11\\boxed{22}^2+60\\boxed{22}^1+45=57 \\\\ P_\\mathsf{odd}(\\boxed{\\omega^2}^2)=P_\\mathsf{odd}(96)=81\\boxed{96}^3+11\\boxed{96}^2+60\\boxed{96}^1+45=12 \\\\ P_\\mathsf{odd}(\\boxed{\\omega^3}^2)=P_\\mathsf{odd}(75)=81\\boxed{75}^3+11\\boxed{75}^2+60\\boxed{75}^1+45=11 \\\\ \\end{alignat} $$ We are not done, we have to figure out what to do with these 8 values still. But before showing that, note that while we are performing 8 evaluations, the evaluations only have 4 coefficients, so this is half the work of not using divide-and-conquer. Further, through recursion, we will be halving this over and over again anyways.\nAlso note that $P_\\mathsf{even}(\\boxed{\\omega^0}^2)=P_\\mathsf{even}(\\boxed{\\omega^4}^2)$ (or the multiplicative order of $\\omega^2$ is half of $\\omega$) which is why we only need to evaluate the first 4 values.\nTo combine these values, we take the output of the even evaluations: $\\{49, 72, 60, 92\\}$ and repeat it: $E=\\{49, 72, 60, 92,49, 72, 60, 92\\}$. We do the same with odd: $O=\\{3, 57, 12, 11,3, 57, 12, 11\\}$. We then compute: $E+O\\cdot\\mathsf{domain}$ (where multiplication is element-wise):\n$$ \\{49, 72, 60, 92,49, 72, 60, 92\\}+(\\{3, 57, 12, 11,3, 57, 12, 11\\}\\cdot\\{1,33,22,47,96,64,75,50\\})\\\\ =\\{52, 13, 33, 27, 46, 34, 87, 60\\} $$ That completes the operation and we have.\n$$ \\left( \\begin{array}{cccccccc} 44 \u0026 45 \u0026 83 \u0026 60 \u0026 59 \u0026 11 \u0026 57 \u0026 81 \\\\ \\end{array} \\right) \\leftrightarrow \\left( \\begin{array}{cccccccc} 1 \u0026 33 \u0026 22 \u0026 47 \u0026 96 \u0026 64 \u0026 75 \u0026 50 \\\\ 52 \u0026 13 \u0026 33 \u0026 27 \u0026 46 \u0026 34 \u0026 87 \u0026 60 \\\\ \\end{array} \\right) $$ Footnotes # ^[1]: Hat tip Pratyush Mishra for suggesting a state-of-the-art algorithm.\n"},{"id":23,"href":"/docs/background/proofs/","title":"Proofs","section":"Background","content":" Security Proofs # To be added.\nDefinitions # Definition 1 (Polynomial Commitment Scheme). A polynomial commitment scheme (PCS) is an interactive proof system that enables $\\mathcal{P}$ to convince $\\mathcal{V}$ that he knows a polynomial, without revealing the polynomial directly. $\\mathcal{P}$ and $\\mathcal{V}$ run the protocol in three moves: gen, com, and open. [Plonk]\nDefinition 2 (Polynomial IOP). Let $\\mathcal{R}$ be a set of the relations among polynomials $\\{P_i\\}$. Let $\\mathcal{C}_f$ is the commitment to $f$. Given common input $\\mathcal{R}(\\{P_i\\})$ to $\\mathcal{P}$ and $\\mathcal{V}$, and private input $\\{P_i\\}$ to $\\mathcal{P}$, they run the following protocol:\n$\\mathcal{P}$ converts the relations into polynomials $\\{Q_j\\}$ $\\mathcal{P}$ commits to $\\{P_i\\}$ and $\\{Q_j\\}$, and sends the commitments to $\\mathcal{V}$ $\\mathcal{V}$ sends a random challenge $\\xi$ $\\mathcal{P}$ runs open for $\\{P_i(\\xi)\\}$ and $\\{Q_j(\\xi)\\}$ and outputs the result $\\mathcal{V}$ checks: the evaluations of $P_i(\\xi)$ and $Q_j(\\xi)$ are correct $\\{Q_j\\}$ satisfy $\\mathcal{R}(\\{P_i\\})$ At the end of the protocol, $\\mathcal{V}$ outputs $\\textbf{acc}$ if and only if the two conditions hold, otherwise $\\textbf{rej}$.\nMoreover, a Poly-IOP has to satisfy the following properties.\nDefinition 3 (Completeness). If each pair of $(\\mathcal{C}_{P_i},P_i)$ and $(\\mathcal{C}_{Q_j},Q_j)$ is valid and $\\{Q_j\\}$ satisfy $\\mathcal{R}(\\{P_i\\})$, $\\text{Pr}[out_{\\mathcal{V}}=\\textbf{acc}]=1$.\nDefinition 4 (Soundness). If $(\\mathcal{C}_{P_i},P_i)$ or $(\\mathcal{C}_{Q_j},Q_j)$ are not a valid pair, or $\\{Q_j\\}$ does not satisfy $\\mathcal{R}(\\{P_i\\})$, $\\text{Pr}[out_{\\mathcal{V}}=\\textbf{rej}]\\ge{1-\\text{negl}(k)}$.\nDefinition 5 (Zero Knowledge). For every possible set of relations $\\mathcal{R}$, there exists a probabilistic polynomial time simulator $\\mathcal{S}$ that can produce $\\{\\mathcal{C}_{P_i}^*\\},\\{\\mathcal{C}_{Q_i}^*\\}$ and the corresponding proofs making $\\mathcal{V}$ output $\\textbf{acc}$; the proofs generated by $\\mathcal{S}$ are computationally indistinguishable from those produced by $\\mathcal{P}$.\n"},{"id":24,"href":"/docs/background/red-tape/","title":"Red Tape","section":"Background","content":" Red Tape # Generally speaking, the gadgets are quite flexible and work well as defined. However there are some subtle issues to pay attention to when using them.\nMax array size # Arrays can be very large but encoding points into a multiplicative domain (using roots of unity) means a root of unity must exist that is the same or larger than the array size. A domain of size $\\kappa$ exists only if $\\kappa$ divides $q-1$, where $q$ is the modulus that applies to exponents in the elliptic curve. For BLS12-384, the largest $\\kappa=2^{32}$. In summary, we can only encode data arrays of length up to $2^{32}=4,294,967,296$. We can use smaller domains. If $2^{32}$ divides $q-1$, so does $2^{31}$ or $2^{30}$ or any lesser power of 2. For terminology, this called a $2$-adicity of $32$.\nIn a sense, $2^{32}$ is an artificial limit since we do not need to encode data into multiplicative domains. We can use any domain, we just need spending more time interpolating with Lagrange. But since we only consider doing this when the domain gets really large, quadratic-time algorithms might be prohibitively expensive for numbers this big.\nTrusted setup # Recall that KZG polynomial commitments require a trusted setup, which implicitly impacts the maximum length an array can take on. Interpolating an array of length $n$ into a univariate polynomial will output a polynomial of degree $n-1$. The trusted setup needs to have an SRS with $n$ elements.\nArray expansions # Some gadgets operate on arrays of size $n$ but create temporary arrays that are larger than $n$ in order to prove the operation is done correctly. In particular, two gadgets are guilty of this:\nIn $\\texttt{lookup2}$, there are a few methods. In the method based on plookup, the temporary arrays need length $n_1$ + $n_2$ where $n_1$ is the length of the array and $n_2$ is the length of the lookup table. In $\\mathtt{range}$, each element is decomposed into binary. So if integers are shown to be the range $\\{0,1\\}^b$, an array of length $n$ needs a temporary array of size $n\\cdot2^b$. This can quickly lead to an array length exceeding the maximum root of unity. See the $\\texttt{range}$ gadget for discussion of other options. You need to ensure you have long enough arrays for all operations.\nPadding arrays # Usually the domain of the array is larger than what is needed since we are stuck with sizes like powers of 2 assuming we are using standard elliptic curves. This is fine, we just add some dummy elements to the end of the array to pad it out. The dummy elements can be zeroed out at any time with $\\texttt{zero1}$ or $\\texttt{zero2}$. However if we choose padding mindfully, we can avoid this extra work. For example, in $\\texttt{add2}$, padding with $0$ does not impact the protocol, while padding with $1$ does not impact $\\texttt{mult2}$.\nBoundary conditions # Many gadgets involve comparisons between neighbouring values in the same array (or across two arrays). This comparison works until you hit the last element of the array and there is no \u0026ldquo;next\u0026rdquo; element in the array. In practice, there is always a \u0026ldquo;next\u0026rdquo; element but attention needs to be paid to what it is. Using a multiplicative domain, the next element will be a dummy element if the array is smaller than the domain, or it will \u0026ldquo;wrap\u0026rdquo; back to the first element of the array if it is full. Many gadgets will just let the constraint end up with some arbitrary value in the last element, and then manually zero it out with $\\texttt{zero2}$.\nAdditional reading # Article (Thaler): includes points comparing univariate Poly-IOP to other zk-SNARK models Paper (Nikolaenko): trusted setup ceremony "}] \ No newline at end of file diff --git a/en.search.min.6ec6eba6938494757b9fe5011c54cba2af69700e962f29d208fa6852b65853ab.js b/en.search.min.bc63bd6cafeda2b6b745976a2712e961b005f4a45bd23c3f3136bb08fbd20177.js similarity index 90% rename from en.search.min.6ec6eba6938494757b9fe5011c54cba2af69700e962f29d208fa6852b65853ab.js rename to en.search.min.bc63bd6cafeda2b6b745976a2712e961b005f4a45bd23c3f3136bb08fbd20177.js index ae257bf..eb3d09b 100644 --- a/en.search.min.6ec6eba6938494757b9fe5011c54cba2af69700e962f29d208fa6852b65853ab.js +++ b/en.search.min.bc63bd6cafeda2b6b745976a2712e961b005f4a45bd23c3f3136bb08fbd20177.js @@ -1 +1 @@ -"use strict";(function(){const o="/en.search-data.min.b3da462909c11499509a5595d9bfd93ab5120cfadab575f568dd98af79163e5d.json",i=Object.assign({cache:!0},{includeScore:!0,useExtendedSearch:!0,fieldNormWeight:1.5,threshold:.2,ignoreLocation:!0,keys:[{name:"title",weight:.7},{name:"content",weight:.3}]}),e=document.querySelector("#book-search-input"),t=document.querySelector("#book-search-results");if(!e)return;e.addEventListener("focus",n),e.addEventListener("keyup",s),document.addEventListener("keypress",a);function a(t){if(t.target.value!==void 0)return;if(e===document.activeElement)return;const n=String.fromCharCode(t.charCode);if(!r(n))return;e.focus(),t.preventDefault()}function r(t){const n=e.getAttribute("data-hotkeys")||"";return n.indexOf(t)>=0}function n(){e.removeEventListener("focus",n),e.required=!0,fetch(o).then(e=>e.json()).then(e=>{window.bookSearchIndex=new Fuse(e,i)}).then(()=>e.required=!1).then(s)}function s(){for(;t.firstChild;)t.removeChild(t.firstChild);if(!e.value)return;const n=window.bookSearchIndex.search(e.value).slice(0,10);n.forEach(function(e){const n=c("
  • "),s=n.querySelector("a"),o=n.querySelector("small");s.href=e.item.href,s.textContent=e.item.title,o.textContent=e.item.section,t.appendChild(n)})}function c(e){const t=document.createElement("div");return t.innerHTML=e,t.firstChild}})() \ No newline at end of file +"use strict";(function(){const o="/en.search-data.min.095fef5514cefcc621486d2d6eb615cc3f20ff8f3d6f8d5568a0c4e9a152148e.json",i=Object.assign({cache:!0},{includeScore:!0,useExtendedSearch:!0,fieldNormWeight:1.5,threshold:.2,ignoreLocation:!0,keys:[{name:"title",weight:.7},{name:"content",weight:.3}]}),e=document.querySelector("#book-search-input"),t=document.querySelector("#book-search-results");if(!e)return;e.addEventListener("focus",n),e.addEventListener("keyup",s),document.addEventListener("keypress",a);function a(t){if(t.target.value!==void 0)return;if(e===document.activeElement)return;const n=String.fromCharCode(t.charCode);if(!r(n))return;e.focus(),t.preventDefault()}function r(t){const n=e.getAttribute("data-hotkeys")||"";return n.indexOf(t)>=0}function n(){e.removeEventListener("focus",n),e.required=!0,fetch(o).then(e=>e.json()).then(e=>{window.bookSearchIndex=new Fuse(e,i)}).then(()=>e.required=!1).then(s)}function s(){for(;t.firstChild;)t.removeChild(t.firstChild);if(!e.value)return;const n=window.bookSearchIndex.search(e.value).slice(0,10);n.forEach(function(e){const n=c("
  • "),s=n.querySelector("a"),o=n.querySelector("small");s.href=e.item.href,s.textContent=e.item.title,o.textContent=e.item.section,t.appendChild(n)})}function c(e){const t=document.createElement("div");return t.innerHTML=e,t.firstChild}})() \ No newline at end of file diff --git a/index.html b/index.html index 3d0a87c..05b1ffe 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ Contributors: Elizabeth van Oorschot (McGill), Youwei Deng (Concordia), Jeremy Clark (Concordia) Some rights reserved: cc-by 4.01 @misc{vODC24, author = {Elizabeth van Oorschot and Youwei Deng and Jeremy Clark}, title = {Plonkbook: A Handbook for Poly-IOP Gadgets}, howpublished = {GitHub Pages}, year = {2024}, url = {https://www.plonkbook.org} } Motivation # The zoo of zk-SNARKs is complex to navigate and always changing.">Plonkbook | Handbook - +
    Plonkbook

    Plonkbook: A Handbook for Poly-IOP Gadgets diff --git a/index.xml b/index.xml index 28ec229..b461f52 100644 --- a/index.xml +++ b/index.xml @@ -4,8 +4,8 @@ Intuition # The prover ($\mathcal{P}$) holds two arrays $\mathsf{Arr_1}$ and $\m Intuition # Given a PLONK circuit, and two private input/public input pairs, we want to reduce the work of checking each of these individually to the work of checking one such relation a single time. This is called folding, and the model we explain here for Plonk, specifically, is called Sangria. Before we get into folding, though, let&rsquo;s review how a PLONK circuit works.<link>http://plonkbook.org/docs/gadgets/lookup1/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://plonkbook.org/docs/gadgets/lookup1/</guid><description>Lookup (Type 1) # Recap of types # Type Description Recap This lookup1 $\mathsf{Arr}[i]\in \{0,1\}$ Each element of array $\mathsf{Arr}$ is in $\{0,1\}$ (or another small set). ✅ lookup2 $\mathsf{Arr}[i]\in \mathsf{Table}$ Each element of array $\mathsf{Arr}$ is in a disclosed table of values $\mathsf{Table}$. Relation # $ \mathcal{R}_{\mathtt{lookup1}} := \left\{ \begin{array}{l} (K_\mathsf{Arr}) \end{array} \middle | \begin{array}{l} \mathsf{Arr} = [a_0, a_1, a_2, \dots, a_{n-1}], \\ \mathsf{Poly}_\mathsf{Arr}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr}), \\ K_\mathsf{Arr}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr}), \end{array} \right\} $</description></item><item><title/><link>http://plonkbook.org/docs/gadgets/lookup2/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://plonkbook.org/docs/gadgets/lookup2/</guid><description>Lookup (Type 2) # Recap of types # Type Description Recap This lookup1 $\mathsf{Arr}[i]\in \{0,1\}$ Each element of array $\mathsf{Arr}$ is in $\{0,1\}$ (or another small set). lookup2 $\mathsf{Arr}[i]\in \mathsf{Table}$ Each element of array $\mathsf{Arr}$ is in a disclosed table of values $\mathsf{Table}$. ✅ Relation # $ \mathcal{R}_{\mathtt{lookup2}} := \left\{ \begin{array}{l} (\mathsf{Arr},\mathsf{T}) \end{array} \middle | \begin{array}{l} \mathsf{Arr}[i]\in\mathsf{T}, 0\leq i \leq n-1, \\ \mathsf{Poly}_\mathsf{Arr}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr}), \\ \mathsf{Poly}_\mathsf{T}=\mathsf{FFT.Interp}(\omega,\mathsf{T}), \\ K_\mathsf{Arr}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr}), \\ K_\mathsf{T}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{T}), \end{array} \right\} $</description></item><item><title/><link>http://plonkbook.org/docs/gadgets/mult1/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://plonkbook.org/docs/gadgets/mult1/</guid><description>Multiplication (Type 1) # Recap of types # Type Description Recap This mult1 $\mathsf{Arr}_3=\mathsf{Arr}_1 \cdot \mathsf{Arr}_2$ $\mathsf{Arr}_3$ is the element-wise multiplication of $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$. ✅ mult2 $\mathsf{Prod}_\mathsf{Arr}=\prod_{i = 0}^{n-1} \mathsf{Arr}[i]$ $\mathsf{Prod}_\mathsf{Arr}$ is the disclosed product of all the elements in $\mathsf{Arr}$. mult3 $\prod_{i = 0}^{n-1} \mathsf{Arr}_1[i]=\prod_{i = 0}^{n-1} \mathsf{Arr}_2[i]$ $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ have the same undisclosed product. Relation # $ \mathcal{R}_{\mathtt{mult1}} := \left\{ \begin{array}{l} (K_\mathsf{Arr_1},K_\mathsf{Arr_2},K_\mathsf{Arr_3}) \end{array} \middle | \begin{array}{l} \mathsf{Arr_3}[i]=\mathsf{Arr_1}[i]\cdot\mathsf{Arr_2}[i], 0\leq i \leq n-1, \\ \mathsf{Poly}_\mathsf{Arr_j}=\mathsf{FFT.</description></item><item><title/><link>http://plonkbook.org/docs/gadgets/mult2/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://plonkbook.org/docs/gadgets/mult2/</guid><description>Multiplication (Type 2) # Recap of types # Type Description Recap This mult1 $\mathsf{Arr}_3=\mathsf{Arr}_1 \cdot \mathsf{Arr}_2$ $\mathsf{Arr}_3$ is the element-wise multiplication of $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$. mult2 $\mathsf{Prod}_\mathsf{Arr}=\prod_{i = 0}^{n-1} \mathsf{Arr}[i]$ $\mathsf{Prod}_\mathsf{Arr}$ is the disclosed product of all the elements in $\mathsf{Arr}$. ✅ mult3 $\prod_{i = 0}^{n-1} \mathsf{Arr}_1[i]=\prod_{i = 0}^{n-1} \mathsf{Arr}_2[i]$ $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ have the same undisclosed product. Relation # $ \mathcal{R}_{\mathtt{mult2}} := \left\{ \begin{array}{l} (K_\mathsf{Arr},\mathsf{Prod}_\mathsf{Arr}) \end{array} \middle | \begin{array}{l} \mathsf{Arr} = [a_0, a_1, a_2, \dots, a_{n-1}], \\ \mathsf{Prod}_\mathsf{Arr} = \prod_{i = 0}^{n-1} a_i, \\ \mathsf{Poly}_\mathsf{Arr}=\mathsf{FFT.</description></item><item><title/><link>http://plonkbook.org/docs/gadgets/mult3/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://plonkbook.org/docs/gadgets/mult3/</guid><description>Multiplication (Type 3) # Recap of types # Type Description Recap This mult1 $\mathsf{Arr}_3=\mathsf{Arr}_1 \cdot \mathsf{Arr}_2$ $\mathsf{Arr}_3$ is the element-wise multiplication of $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$. mult2 $\mathsf{Prod}_\mathsf{Arr}=\prod_{i = 0}^{n-1} \mathsf{Arr}[i]$ $\mathsf{Prod}_\mathsf{Arr}$ is the disclosed product of all the elements in $\mathsf{Arr}$. mult3 $\prod_{i = 0}^{n-1} \mathsf{Arr}_1[i]=\prod_{i = 0}^{n-1} \mathsf{Arr}_2[i]$ $\mathsf{Arr}_1$ and $\mathsf{Arr}_2$ have the same undisclosed product. ✅ Relation # $ \mathcal{R}_{\mathtt{mult3}} := \left\{ \begin{array}{l} (K_\mathsf{Arr_1},K_\mathsf{Arr2}) \end{array} \middle | \begin{array}{l} \mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \dots, a_{(1,n-1)}],\\ \mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \dots, a_{(2,n-1)}], \\ \mathsf{Poly}_\mathsf{Arr_1}=\mathsf{FFT.</description></item><item><title/><link>http://plonkbook.org/docs/gadgets/range/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://plonkbook.org/docs/gadgets/range/</guid><description>Range # Recap of types # Type Description Recap This range $\mathsf{Arr}[i]\in[0,r]$ Each element of array $\mathsf{Arr}$ is in the range $[0,r]$ ✅ Relation # $\mathcal{R}_{\mathtt{add1}} := \left\{ \begin{array}{l} (K_\mathsf{Arr}) \end{array} \middle | \begin{array}{l} 0\le{\mathsf{Arr}[i]}\le{r}, i\in[0,n), \\ \mathsf{Poly}_\mathsf{Arr}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr}), \\ K_\mathsf{Arr}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr}), \end{array} \right\}$ Intuition # To prove each element of array $\mathsf{Arr}$ is in the range $[0,r]$, one of the most intuitive ways is we create a vector containing the numbers from $0$ to $r$ and run the lookup argument for $\mathsf{Arr}$.</description></item><item><title/><link>http://plonkbook.org/docs/gadgets/rotate/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://plonkbook.org/docs/gadgets/rotate/</guid><description>Rotate # Recap of types # $ \mathcal{R}_{\mathtt{rotate}} := \left\{ \begin{array}{l} (K_\mathsf{Arr}, K_\mathsf{Arr'}) \end{array} \middle | \begin{array}{l} \mathsf{Arr} = [a_0, a_1, a_2, \dots, a_{n-1}],\\ \mathsf{Arr'}[i] = \mathsf{Arr}[i +\alpha], \\ \mathsf{Poly}_\mathsf{Arr}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr}),\\ \mathsf{Poly}_\mathsf{Arr'}=\mathsf{FFT.Interp}(\omega,\mathsf{Arr'}), \\ K_\mathsf{Arr}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr}),\\ K_\mathsf{Arr'}=\mathsf{KZG.Commit}(\mathsf{Poly}_\mathsf{Arr'}),\\ \end{array} \right\} $ Intuition # Assume $\mathsf{Arr}$ is an array of data of size $n$. It is encoded as the y-coordinates into univariant polynomials where the x-coordinates (called the domain $\mathcal{H}_\kappa$) are chosen as the multiplicative group of order $\kappa$ with generator $\omega\in\mathbb{G}_\kappa$ (see Background for more).</description></item><item><title/><link>http://plonkbook.org/docs/gadgets/shuffle1/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://plonkbook.org/docs/gadgets/shuffle1/</guid><description>Shuffle (Type 1) # Recap of types # Type Description Recap This shuffle1 $\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1)$ Array $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ for some undisclosed permutation $\pi$. ✅ shuffle2 $\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1 ,\pi)$ Array $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ under a disclosed permutation $\pi$. Relation # $ \mathcal{R}_{\mathtt{shuffle1}} := \left\{ \begin{array}{l} (K_\mathsf{Arr_1},K_\mathsf{Arr2}) \end{array} \middle | \begin{array}{l} \mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \dots, a_{(1,n-1)}],\\ \mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \dots, a_{(2,n-1)}], \\ \mathsf{Poly}_\mathsf{Arr_1}=\mathsf{FFT.</description></item><item><title/><link>http://plonkbook.org/docs/gadgets/shuffle2/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://plonkbook.org/docs/gadgets/shuffle2/</guid><description>Shuffle (Type 2) # Recap of types # Type Description Recap This shuffle1 $\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1)$ Array $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ for some undisclosed permutation $\pi$. shuffle2 $\mathsf{Arr}_2=\mathsf{Permute}(\mathsf{Arr}_1 ,\pi)$ Array $\mathsf{Arr}_2$ is a shuffle of $\mathsf{Arr}_1$ under a disclosed permutation $\pi$. ✅ Relation # $\mathcal{R}_{\mathtt{shuffle2}} := \left\{ \begin{array}{l} (K_\mathsf{Arr_1},K_\mathsf{Arr2}, K_\pi) \end{array} \middle | \begin{array}{l} \mathsf{Arr_1} = [a_{(1,0)}, a_{(1,1)}, a_{(1,2)}, \dots, a_{(1,n-1)}],\\ \mathsf{Arr_2} = [a_{(2,0)}, a_{(2,1)}, a_{(2,2)}, \dots, a_{(2,n-1)}], \\ \mathsf{Arr_\pi} = [\pi(\omega^0), \pi(\omega^1), \pi(\omega^2), \dots, \pi(\omega^{n-1})], \\ \mathsf{Poly}_\mathsf{Arr_1}=\mathsf{FFT.</description></item><item><title/><link>http://plonkbook.org/docs/gadgets/zero1/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://plonkbook.org/docs/gadgets/zero1/</guid><description>Zero (Type 1) # Recap of types # Type Description Recap This zero1 $\mathsf{Arr}[i]\leftarrow0$ Zero-out elements of an array $\mathsf{Arr}$ such as: all, first, last, all-but-first, all-but-last. ✅ zero2 $\mathsf{Arr}[i]\leftarrow0$ iff $\mathsf{Sel}[i]=0$ Zero-out elements of an array $\mathsf{Arr}$ according to a binary array $\mathsf{Sel}$. Subtypes of $\texttt{zero1}$ # Operation Output Array Zero all $\langle 0,0,0,0,0 \rangle$ Zero first $\langle 0,\bot,\bot,\bot,\bot \rangle$ Zero last $\langle \bot,\bot,\bot,\bot,0 \rangle$ Zero all but first $\langle \bot,0,0,0,0 \rangle$ Zero all but last $\langle 0,0,0,0,\bot \rangle$ Relation # Shown for &ldquo;zero last&rdquo; but can be adapted to the other sub-types of $\texttt{zero1}$:</description></item><item><title/><link>http://plonkbook.org/docs/gadgets/zero2/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://plonkbook.org/docs/gadgets/zero2/</guid><description>Zero (Type 2) # Recap of types # Type Description Recap This zero1 $\mathsf{Arr}[i]\leftarrow0$ Zero-out elements of an array $\mathsf{Arr}$ such as: all, first, last, all-but-first, all-but-last. zero2 $\mathsf{Arr}[i]\leftarrow0$ iff $\mathsf{Sel}[i]=0$ Zero-out elements of an array $\mathsf{Arr}$ according to a binary array $\mathsf{Sel}$. ✅ Zeroing Parts of an Array (2) # Assume both $\mathsf{Arr}$ (an array of data) and $\mathsf{Sel}$ (a binary array) are of size $n$. They are encoded as the y-coordinates into univariant polynomials where the x-coordinates (called the domain $\mathcal{H}_\kappa$) are chosen as the multiplicative group of order $\kappa$ with generator $\omega\in\mathbb{G}_\kappa$ (see Background for more).</description></item><item><title>Overviewhttp://plonkbook.org/docs/background/overview/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/overview/Overview # Preliminaries # While we may add more background in future iterations, for now we punt on explaining the following concepts and assume you are already familiar with them: -Elliptic curve cryptography Hardness of the discrete logarithm problem and related problems Pairing-based cryptography at a &ldquo;black-box&rdquo; level (what it does, not necessarily how it works) Resources: Lecture (Boneh) Commitment schemes Properties: hiding and binding Construction: Pedersen Commitments Resources: Lecture (Boneh) Zero knowledge proofs (high level idea) Properities: completeness, soundness, zero-knowledge Resources: Lecture (Goldwasser) zk-SNARKs # Plonk is a zk-SNARK proof system.PCShttp://plonkbook.org/docs/background/kzg/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/kzg/Polynomial Commitment Schemes (PCS) # Comparing Polynomials # Say that Carol sends a polynomial to Alice and the same polynomial to Bob. Later Alice and Bob are sitting together and want to make sure their polynomials, which they got from Carol, are actually the same. How do you compare polynomials? There are many sufficient comparisons, but here are two ways to get started: -Ensure the degree $d$ is the same and each coefficient is the same, Ensure the degree $d$ is the same and check at $d+1$ unique points.Polynomialshttp://plonkbook.org/docs/background/poly-iop/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/poly-iop/Polynomials # All the gadgets in Plonkbook follow the same high level model, called a polynomial interactive proof (Poly-IOP). Each gadget is defined as an operation on one or more arrays of data. The arrays are encoded into a univariate polynomial (see below) and the polynomial is committed to (next background section) and passed to the verifier. The verifier works with commitments and sees that operations on commitments are mirroring a set of operations being done on the polynomials themselves.Proofshttp://plonkbook.org/docs/background/proofs/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/proofs/Security Proofs # To be added. +Elliptic curve cryptography Hardness of the discrete logarithm problem and related problems Pairing-based cryptography at a &ldquo;black-box&rdquo; level (what it does, not necessarily how it works) Resources: Lecture (Boneh) Commitment schemes Properties: hiding and binding Construction: Pedersen Commitments Resources: Lecture (Boneh) Zero knowledge proofs (high level idea) Properties: completeness, soundness, zero-knowledge Resources: Lecture (Goldwasser) zk-SNARKs # Plonk is a zk-SNARK proof system.PCShttp://plonkbook.org/docs/background/kzg/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/kzg/Polynomial Commitment Schemes (PCS) # Comparing Polynomials # Say that Carol sends a polynomial to Alice and the same polynomial to Bob. Later Alice and Bob are sitting together and want to make sure their polynomials, which they got from Carol, are actually the same. How do you compare polynomials? There are many sufficient comparisons, but here are two ways to get started: +Ensure the degree $d$ is the same and each coefficient is the same, Ensure the degree $d$ is the same and check at $d+1$ unique points.Polynomialshttp://plonkbook.org/docs/background/poly-iop/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/poly-iop/Polynomials # All the gadgets in Plonkbook follow the same high level model, called a polynomial interactive oracle proof (Poly-IOP). Each gadget is defined as an operation on one or more arrays of data. The arrays are encoded into a univariate polynomial (see below) and the polynomial is committed to (next background section) and passed to the verifier. The verifier works with commitments and sees that operations on commitments are mirroring a set of operations being done on the polynomials themselves.Proofshttp://plonkbook.org/docs/background/proofs/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/proofs/Security Proofs # To be added. Definitions # Definition 1 (Polynomial Commitment Scheme). A polynomial commitment scheme (PCS) is an interactive proof system that enables $\mathcal{P}$ to convince $\mathcal{V}$ that he knows a polynomial, without revealing the polynomial directly. $\mathcal{P}$ and $\mathcal{V}$ run the protocol in three moves: gen, com, and open. [Plonk] Definition 2 (Polynomial IOP). Let $\mathcal{R}$ be a set of the relations among polynomials $\{P_i\}$. Let $\mathcal{C}_f$ is the commitment to $f$.Red Tapehttp://plonkbook.org/docs/background/red-tape/Mon, 01 Jan 0001 00:00:00 +0000http://plonkbook.org/docs/background/red-tape/Red Tape # Generally speaking, the gadgets are quite flexible and work well as defined. However there are some subtle issues to pay attention to when using them. Max array size # Arrays can be very large but encoding points into a multiplicative domain (using roots of unity) means a root of unity must exist that is the same or larger than the array size. A domain of size $\kappa$ exists only if $\kappa$ divides $q-1$, where $q$ is the modulus that applies to exponents in the elliptic curve. \ No newline at end of file diff --git a/tags/index.html b/tags/index.html index 10a51c2..b928382 100644 --- a/tags/index.html +++ b/tags/index.html @@ -1,5 +1,5 @@ Tags | Handbook - +
    Tags
    \ No newline at end of file