Recall: How to build an Efficient SNARK?

There are various paradigms on building SNARKs, but the general paradigm is made up of two steps:

  1. A functional commitment scheme, which is a cryptographic object
  2. A suitable interactive oracle proof (IOP), which is an information theoretic object

In Lecture 5, we have seen PLONK, which operated with:

  1. A univariate polynomial commitment scheme
  2. PLONK polynomial IOP

In Lecture 4, we have seen another method using the sum-check protocol:

  1. A multivariate polynomial commitment scheme
  2. Sum-check protocol for IOP

In this lecture, we will dive deeper into polynomial commitment schemes, in particular those that are based on bilinear pairings and discrete logarithm.

What is a Polynomial Commitment?

Consider a family of polynomials . The prover has some polynomial that is a function . The interactions of a polynomial commitment scheme look like the following:

sequenceDiagram
	actor P as Prover
	actor V as Verifier

	note over P: f ∈ F

	P ->> V: (1) com_f := commit(f)
	V ->> P: (2) u ∈ X
	P ->> V: (3) v ∈ Y, proof π
	note over V: (4) Accept or Reject

Let us explain each numbered step in this sequence diagram:

  1. Prover commits to the polynomial, and sends the commitment , also shown as .
  2. The verifier would like to query this polynomial at some value , so it sends this to the prover.
  3. Prover evaluates and sends this to verifier, along with a proof that indeed and .
  4. The verifier will verify this proof, and accept if it is valid.

A bit more formality

Let's make a more formal definition of polynomial commitments now. They are made of 4 algorithms:

  • generate public parameters given the polynomial family and security parameter . Note the is also known as "common reference string", or "public key" too.
  • computes the commitment to the given polynomial.
  • is the evaluation method that the prover uses to compute and generate a proof that this is true and .
  • verifies an evaluation, and it will either accept or reject (which is why I used a bit to represent output).

Polynomial commitment has the following properties:

Correctness: if the prover is honest, and follows the given algorithms above, then should always accept. We won't go too much into this one yet.

Knowledge Soundness: for every polynomial time adversary such that:

where , then there is an efficient extractor that uses as a black box (oracle) such that:

where . Meaning that if the prover can convince the verifier about some committed polynomial , then an efficient extractor can "extract" that from the prover via some algorithm, and then find out that indeed the evaluations are correct, with at most some negligible probability of failure.

Group Theory

It will be good to refresh our memory on some of the preliminary concepts, starting with group theory!

A group is a set and an operation . It satisfies the following properties:

  • Closure: it holds that . In other words, the result of this operation is still an element of this group, it is closed in this group!
  • Associativity: it holds that . The order of execution should not matter.
  • Identity: such that it holds that . We call the identity element, because the result of operating on it is identical to the operand.
  • Inverse: such that . This is very important to keep in mind.

For example, the set of integers under addition operation satisfies all these properties. You might also be familiar with rational numbers, real numbers, complex numbers and such.

In cryptography, here are some commonly used groups:

  • Positive integers some prime number , which is the set under the multiplication operation . This is denoted as .
  • Elliptic curves, we will not go into this yet though.

Generator of a Group

An element that generates all the other elements in the group by taking its powers is called the generator of that group. For example, consider the multiplicative group . See what happens if we take powers of 3 in this group.

Notice that , so you can continue to powering , and so on but you will keep getting the same values. Furthermore, there can be multiple generators within a group!

Discrete Logarithm Assumption

So think of a some group with elements. You could represent the group by literally writing out all its elements. Alternatively, you could just note down the generator and find its powers to obtain the group elements; keep in mind that there may be different generators too. With that in mind, let us look at the discrete logarithm problem:

  • given find such that

It turns out that this is very hard to do, you basically have to try your luck with . There are some clever methods too, but it is the general consensus that this problem is computationally hard, meaning that you can't solve it in polynomial time.

Quantum computers can actually solve this in polynomial time, and any scheme that uses discrete log is therefore not post-quantum secure.

Diffie-Hellman Assumption

You might remember this duo from the Diffie-Hellman Key-Exchange [Diffie-Hellamn'76]. The paper is based on the Diffie-Hellman Assumption, which is very similar to the discrete logarithm assumption.

  • given compute

This is a stronger assumption that the discrete logarithm assumption, meaning that it "assumes more stuff". In other words, if discrete logarithm assumption breaks, you can break this one too. What you could do it, simply find from and from and just compute .

To our best knowledge, this is also a hard problem and there is no efficient solution yet.

Bilinear Pairing

Bilinear pairings are an awesome building block that we will make use of. You have the following:

  • : the base group, a multiplicative cyclic group
  • : the target group, yet another multiplicative cyclic group
  • : the order of both and
  • : the generator of base group
  • : a pairing operation

The pairing must have the following bilinearity property:

Note that computing itself may be efficient or not, that depends on the groups that are being used. Also note that you could have two different base groups, unlike our example above which just uses on base group for both and .

Example: Diffie-Hellman

Consider , what can this be equal to?

That means . We know that given we can't compute that is the Diffie-Hellman assumption. However, what if someone claims that they have computed ? Well, we can check this without learning what is simply with the aforementioned equality.

Example: BLS Signature

BLS signature [Boneh-Lynn-Shacham'01] is an example usage of bilinear pairings. It is a signature scheme with the following functions:

  • that is the secret (private) key and public key respectively
  • where is a cryptographic hash function that maps the message space to
  • will verify if . Notice that comes from , and is a known public hash function

KZG Poly-Commit Scheme with Pairings

Remember we had went over KZG in the previous lecture, but there at some point we had to mention "pairings". Now, we will look at KZG again but with pairings included.

Suppose you have a univariate polynomial function family and some polynomial that you would like to commit . You also have a bilinear pairing . Let's see how KZG works with these.

    • Sample a random
    • Set
    • Delete , its toxic waste at this point and you should make sure no one gets it. If they do, they can generate fake proofs. This is why a trusted setup is required for KZG.
    • The polynomial is represented with its coefficients .
    • The commitment is . How can this be done without knowing ? Well, that is where comes into play.
    • Notice that
    • Its equal to which can be done using just the elements in the public parameters and the coefficients of .
    • A verifier wants to query this polynomial at point , and you would like to show that along with a proof that this is indeed true.
    • To do this, first you find a quotient polynomial such that . Note that is a a root of .
    • Then, your proof is which you can do without knowing but instead using , as shown in the last bullet under .
    • The idea is to check the equation at point as .
    • The verifier knows as is in and the verifier can calculate, and it also knows because that is the proof sent by the prover. However, Diffie-Hellman assumption tells us that just by knowing these two, the verifier can't compute . So what do we do?
    • We can use a bilinear pairing! We will make use of the pairing . Notice that this pairing translates to . The verifier can simply check this equality, and accepts if it is correct.
sequenceDiagram
  actor P as Prover
  actor V as Verifier

  %% keygen
  note over P, V: gp = (g, g^t, g^(t^2), ..., g^(t^d))

  %% comittment
  note over P: f ∈ F
  P ->> V: com_f := g^f(t)

  %% eval
  V ->> P: u
  note over P: v = f(u)
  note over P: f(x)-f(u) = (x-u)q(x)

  %% verify
  P ->> V: v, proof π = g^q(t)
  note over V: g^(t-u) = g^t / g^u
  note over V: e(com_f / g^v, g) ?= e(g^(t-u), π)
  note over V: if true, Accept, otherwise Reject

q-Strong Bilinear Diffie-Hellman

What about the properties of KZG?

  • Correctness: if the prover is honest, then the verifier will always accept.
  • Soundness: how likely is a fake proof to be verified?

The answer to this comes from something called "q-Strong Bilinear Diffie-Hellman" (short for q-SBDH) assumption. That is, given and it is hard to compute for any . This is a stronger assumption that computational Diffie-Hellman.

Let us prove the soundness then! We will do a Proof by Contradiction. Suppose yet a fake proof passes the verification. We begin the proof by writing the bilinear pairing equivalence that the verifier checks for:

We will assume that the prover knows , which is a strong assumption but we will explain it later (see Knowledge of Exponent). Therefore, we have the following equivalence:

Now the trick of the proof: we add to the leftmost exponent, which is effectively adding 0 so it does not change anything.

Now define , which is non-zero because we have said above that . We rewrite the left hand-side:

As a result of pairing, we can move the exponents outside as:

Dividing both sides by we get:

Finally, taking both sides to power leads to a contradiction!

Notice the left side that is , which is what q-SBDH was about! Even more, the right side of the equation only has globally available variables, so this means that the prover can break q-SBDH assumption.

Knowledge of Exponent (KoE)

We have said that we assume the prover knows such that . How can we make sure of this? Here is how:

  • Again you have
  • Sample some random compute
  • Now compute two commitments instead of one, and

Now we can make use of bilinear pairings: if there exists an extractor that extracts such that . This extractor will extract in our proof above, where we assumed the prover knows .

Let us then describe the KZG with knowledge soundness:

  • Keygen generates both and
  • Commit computes both and
  • Verify additionally checks

Note that this doubles the cost of key generation and commitments, as well as the verifier time.

Generic Group Model (GGM)

GGM [Shoup'97], [Maurer'05] can replace the KoE assumption and reduce commitment size in KZG. The informal definition is that the adversary is only given an oracle to compute the group operation, that is: given the adversary can only compute their linear combinations.

Properties of KZG

So let us write down the properties of KZG.

  • Keygen requires trusted setup
  • Commit requires group exponentiations and commitment size
  • Eval requires group exponentiations, and can be computed efficiently in linear time
  • Proof size is for the single group element
  • Verifier time is for the pairing check

Powers of Tau Ceremony

Okay, trusted setup sucks but we can make it a bit nicer: instead of letting one party come up with the global parameters, we will distribute this process to multiple parties. In doing so, even if only one party is honest and gets rid of the "toxic waste", then that is enough for us so that no one will be able to reconstruct the trapdoor. Here is how:

  • Suppose your global parameters are right now:

  • As a participant in this ceremony, you sample some random , and obtain new as:

A new method [Nikolaenko-Ragsdale-Bonneau-Boneh'22] provides a way to check the correctness of too. The idea is:

  • the contributor knows such that
  • and consists of consecutive powers where

Variants of KZG

We will look at several extensions of KZG univariate polynomial commitment scheme.

Multivariate KZG

[Papamanthou-Shi-Tamassia'13] describes a way to use KZG for multivariate polynomials. The idea is:

  • Keygen will sample to compute as raised to all possible monomials of
  • Commit will compute
  • Eval will compute a group element for each polynomial
  • Verify will check

Notice that the proof size and verifier time is greater here.

You can find in practice vSQL [ZGKPP'17] and Libra [XZZPS'19] that makes use of multivariate KZG as the commitment scheme and Sum-check protocol or GKR protocol as the IOP to obtain a SNARK.

Achieving Zero-Knowledge

Plain KZG is not zero-knowledge, e.g. is deterministic. Also remember that to formally show zero-knowledgeness, we need a simulator construction that can simulate the view of the commitment scheme.

[ZGKPP'18] shows a method to do this by masking with randomizers.

  • Commit will compute the masked
  • Eval will also be masked as follows:

The proof will therefore be . Note that this looks much like the bivariate extension of KZG, but the other polynomial is like some added randomness to provide zero-knowledge property.

Batch Proofs on a Single Polynomial

Prover wants to prove at multiple points for . The key idea is to extrapolate to obtain . Then,

  • we find a quotient polynomial from
  • the proof then becomes
  • verifier will check

Batch Proofs on Multiple Polynomials

Prover wants to prove at multiple points and polynomials for . The key idea is to extrapolate to obtain . Then,

  • we find quotient polynomials from
  • the proof will have all in a random linear combination

Bulletproofs

Although the powers-of-tau ceremony helps on the "trusted setup" problem, Bulletproofs [BCCGP'16], [BBBPWM'18] completely remove the "trusted setup" problem of KZG!

    • Bulletproofs have a "transparent setup" phase, which is to simply randomly sampled elements from a group , resulting in
    • suppose you have a polynomial
    • commitment is
    • notice that this is a "vector commitment" version of a Pedersen Commitment

Then, do and recursively around times:

    • find
    • compute
    • receive a random from verifier and reduce to of degree
    • update the global parameter to be
    • check
    • generate randomly
    • update (this is the magic trick)
    • update the global parameter to be
    • set

The idea of Bulletproofs is to recursively divide a polynomial in two polynomials, and commit to those smaller polynomials, eventually reducing whatever degree you have started with to 1.

The Magic Trick

So let's go over what happens in that magical line where we obtain the new commitment given (left & right respectively). Suppose we have a polynomial of degree 3

and our commitment is:

The prover splits the polynomial into two polynomials of half the degree:

  • left half:
  • right half:

It will also commit the each half:

  • left half:
  • right half:

Did you notice the criss-cross between the group elements and their exponents? The terms are fitting nicely with the coefficients, but the exponents are actually belonging to the other polynomial! This is a way of "relating" both halves together, so to restrain the prover to some extent and keep the computations sound.

The magical line is the following:

Now notice that this commitment is what you would have gotten if you had:

  • a polynomial
  • and

Both are half the size of what we had started with! If you keep doing this recursively, you will end up with a degree-1 polynomial in around steps. Without caring about zero-knowledge property, the prover could simply send the constant sized polynomial for the last step to prove the evaluation.

Also to mention, you could take "odd-elements & even-elements" instead of "left-half & right-half" for this process, which is similar to what is done in FFT, and it would still work!

sequenceDiagram
	actor P as Prover
	actor V as Verifier

  %% keygen
	note over P, V: gp = (g_0, g_1, g_2, ..., g_d)

	%% comittment
	note over P: f ∈ F
	P ->> V: com_f := g_0f^0 * g_1f^1 * ... * g_df^d

  %% eval
	V ->> P: u
  note over P: v = f(u)
	P ->> V: v

	loop while deg(f) > 1
	note over V: sample random r
	V ->> P: r

  note over P: L, R := split(f)
	P ->> V: v_L = L(u), com_L, v_R = R(u), com_R
	note over P: f' := reduce(L, R, r)

  %% verify
  note over V: assert: v == v_L + v_R * u^2
	note over V: com' = L^r * com_f * R^{r^-1}
	note over V: update gp as gp'
	note over V: v' = r * v_L + v_R
	note over V, P: recurse with f', com', v', gp'
	end

	note over V, P: prove eval of a const-sized polynomial
	note over V: accept or reject

More Poly-Commit Schemes

More advanced schemes based on d-log with transparent setup are out there, and we will go over them quickly.

Hyrax

Hyrax [Wahby-Tzialla-Shelat-Thaler-Walfish'18] improves the verifier time to by representing the coefficients as a 2D matrix. This way, it commits to the matrix row-wise, and does reduction column-wise. Proof size also becomes .

Dory

Dory [Lee'21] delegates the structured computation to the prover using inner pairing product arguments [BMMTV'21]. This way, verifier time becomes and prover time becomes exponentiations plus field operations, so prover time is still linear but in practice it is a bit more efficient.

Dark

Dark [Bünz-Fisch-Szepieniec'20] achieves proof size and verifier time! The trick here is to use group of an unknown order.

Summary

Here is a quick summary of all the methods covered in this lecture.

SchemeProver TimeProof SizeVerifier TimeSetup PhaseCryptographic primitive
KZGTrustedPairing
BulletproofsTransparentDiscrete-log
HyraxTransparentDiscrete-log
DoryTransparentPairing
DarkTransparentUnknown order Group