Published on

Solving Proofs, Arguments, and Zero-Knowledge

Authors
  • avatar
    Name
    Marco Besier, Ph.D.
    Twitter

This post is a work in progress.

Chapter 3: Definitions and Technical Preliminaries

Exercise 3.1

Let A,B,CA, B, C be n×nn \times n matrices over a field F\mathbb{F}. In Section 2.2, we presented a randomized algorithm for checking that C=ABC = A \cdot B. The algorithm picked a random field element rr, let x=(r,r2,...,rn)x = \left( r, r^2,...,r^n \right), and output EQUAL if Cx=A(Bx)Cx = A \cdot (Bx), and output NOT-EQUAL otherwise. Suppose instead that each entry of the vector xx is chosen independently and uniformly at random from F\mathbb{F}. Show that:

  • If Cij=(AB)ijC_{ij} = (AB)_{ij} for all i=1,...,n,j=1,...,ni = 1,...,n, j = 1,...,n, then the algorithm outputs EQUAL for every possible choice of xx.

  • If there is even one (i,j)[n]×[n](i,j) \in [n] \times [n] such that Cij(AB)ijC_{ij} \neq (AB)_{ij}, then the algorithm outputs NOT-EQUAL with probability at least 11/F1 - 1/|\mathbb{F}|.

Solution

First, let x=(x1,...,xn)Fnx = (x_1,...,x_n)\in \mathbb{F}^n, where each xix_i is chosen independently and uniformly at random from F\mathbb{F}. Furthermore, let D=ABD = A \cdot B, so that our goal is to determine whether the claimed\textit{claimed} product matrix CC actually equals the true\textit{true} product matrix DD.

The first property (completeness) is easy to see: if C=DC=D, then clearly Cx=DxCx=Dx for any xFnx\in \mathbb{F}^n, so the algorithm will output EQUAL for every choice of xx.

To see that the second property (soundness) holds, let us define the matrix E:=CDE := C-D. Furthermore, suppose CDC\neq D, i.e., E0E\neq 0. Since EE is non-zero, we have that rank(E)1\text{rank}(E) \geq 1. By the rank-nullity theorem, we then have that dim(ker(E))n1\text{dim(ker}(E)) \leq n-1. Since our vector coordinates xix_i are sampled independently and uniformly at random from F\mathbb{F}, the soundness error is given by

PrxFn[Ex=0]=ker(E)FnFn1Fn=1F\text{Pr}_{x\in \mathbb{F}^n}[Ex=0] = \frac{|\text{ker}(E)|}{|\mathbb{F}^n|}\leq \frac{|\mathbb{F}^{n-1}|}{|\mathbb{F}^{n}|} = \frac{1}{|\mathbb{F}|}

In other words, if there is even one (i,j)[n]×[n](i,j) \in [n] \times [n] such that Cij(AB)ijC_{ij} \neq (AB)_{ij}, then the algorithm outputs NOT-EQUAL with probability at least 11/F1 - 1/|\mathbb{F}|.

Exercise 3.2

In Section 2.1, we described a communication protocol of logarithmic cost for determining whether Alice's and Bob's input vectors are equal. Specifically, Alice and Bob interpreted their inputs as degree-nn univariate polynomials pap_a and pbp_b, chose a random rFr \in \mathbb{F} with F>>n|\mathbb{F}|>>n, and compared pa(r)p_a(r) to pb(r)p_b(r). Give a different communication protocol in which Alice and Bob interpret their inputs as multilinear rather than univariate polynomials over F\mathbb{F}. How large should F\mathbb{F} be to ensure that the probability Bob outputs the wrong answer is at most 1/n1/n? What is the communication cost in bits of this protocol?

Solution

For the protocol to work, we assume (without loss of generality) that Alice's and Bob's vectors are both of length 2l2^l. Whenever that's not the case, Alice and Bob agree to pad their vectors with zeros until the length becomes the next power of two available.

With that assumption, Alice's vector a=(a0,a1,...,a2l1)F2la = (a_0,a_1,...,a_{2^l-1})\in \mathbb{F}^{2^l} can be viewed as defining a function fa:{0,1}lFf_a: \{0,1\}^l \rightarrow \mathbb{F}. Let f~a:FlF\tilde{f}_a:\mathbb{F}^l\rightarrow \mathbb{F} denote the corresponding multilinear extension.

Similarly, Bob's vector b=(b0,b1,...,b2l1)F2lb = (b_0,b_1,...,b_{2^l-1})\in \mathbb{F}^{2^l} can be viewed as defining a function fb:{0,1}lFf_b: \{0,1\}^l \rightarrow \mathbb{F} with a corresponding multilinear extension f~b:FlF\tilde{f}_b:\mathbb{F}^l\rightarrow \mathbb{F}.

The steps of the protocol are as follows:

  1. Alice and Bob agree to encode their vectors into multilinear extensions as described above.
  2. Alice chooses a random point rFlr\in \mathbb{F}^l.
  3. Alice sends rr and f~a(r)\tilde{f}_a(r) to Bob.
  4. Bob computes f~b(r)\tilde{f}_b(r) and checks if it's equal to f~a(r)\tilde{f}_a(r).

Now, how large should F\mathbb{F} be to ensure that the probability Bob outputs the wrong answer is at most 1/n1/n? To answer this question, note that if fafbf_a\neq f_b, then f~af~b\tilde{f}_a - \tilde{f}_b is a non-zero multilinear polynomial of degree l\leq l. By the Schwartz-Zippel Lemma, the probability that f~a(r)=f~b(r)\tilde{f}_a(r)=\tilde{f}_b(r) for a randomly chosen rFlr\in \mathbb{F}^l is at most:

deg(f~af~b)FlF\frac{\text{deg}\left(\tilde{f}_a-\tilde{f}_b\right)}{|\mathbb{F}|} \leq \frac{l}{|\mathbb{F}|}

To ensure the error is 1/n\leq 1/n, set:

lF1nFln=l2l\frac{l}{|\mathbb{F}|} \leq \frac{1}{n} \Rightarrow |\mathbb{F}| \geq l\cdot n = l\cdot 2^l

Lastly, to compute the protocol's total communication cost in bits, recall that the number of bits needed to represent an element of F\mathbb{F} is

log2F\left \lceil{\text{log}_2|\mathbb{F}|}\right \rceil

because that's the number of bits needed to represent integers up to F1|\mathbb{F}|-1.

During the protocol, Alice sends:

  • The vector rFlr\in \mathbb{F}^l, i.e., llog2Fl\cdot \left \lceil{\text{log}_2|\mathbb{F}|}\right \rceil bits.
  • The value f~a(r)F\tilde{f}_a(r)\in \mathbb{F}, i.e., log2F\left \lceil{\text{log}_2|\mathbb{F}|}\right \rceil bits.

Therefore, the protocol's total communication cost in bits is (l+1)log2F(l+1)\cdot \left \lceil{\text{log}_2|\mathbb{F}|}\right \rceil bits.

To see how efficient this is, let's consider an example. Suppose n=1024=210n=1024=2^{10}, i.e., l=10l=10. To ensure the soundness error is 1/n\leq 1/n, we choose pln=101024=10240p \geq l\cdot n = 10\cdot 1024 = 10240. With this choice, we have log2p14\text{log}_2p \approx 14. The total communication cost in bits is, therefore, given by:

(10+1)14=154 bits(10+1)\cdot 14 = 154 \text{ bits}

Compared to naively sending the whole vector (1024 field elements = 14,336 bits), our protocol gives an exponential saving.

Exercise 3.3

Let p=11p = 11. Consider the function f:{0,1}2Fpf:\{0,1\}^2\rightarrow\mathbb{F}_p given by f(0,0)=3,f(0,1)=4,f(1,0)=1f(0,0)=3, f(0,1)=4, f(1,0)=1, and f(1,1)=2f(1,1)=2. Write out an explicit expression for the multilinear extension f~\tilde{f} of ff. What is f~(2,4)\tilde{f}(2,4)?

Now consider the function f:{0,1}3Fpf: \{0,1\}^3\rightarrow \mathbb{F}_p given by f(0,0,0)=1,f(0,1,0)=2,f(1,0,0)=3,f(1,1,0)=4,f(0,0,1)=5,f(0,1,1)=6,f(1,0,1)=7,f(1,1,1)=8f(0,0,0)=1, f(0,1,0)=2, f(1,0,0)=3, f(1,1,0)=4, f(0,0,1)=5, f(0,1,1)=6, f(1,0,1)=7, f(1,1,1)=8. What is f~(2,4,6)\tilde{f}(2,4,6)? How many field multiplications did you perform during the calculation? Can you work through the calculation of f~(2,4,6)\tilde{f}(2,4,6) that uses "just" 20 multipliactions operations? Hint: see Lemma 3.8.

Solution

Let p=11p = 11. Consider the function f:{0,1}2Fpf:\{0,1\}^2\rightarrow\mathbb{F}_p given by f(0,0)=3,f(0,1)=4,f(1,0)=1f(0,0)=3, f(0,1)=4, f(1,0)=1, and f(1,1)=2f(1,1)=2. Using Lemma 3.6, we can compute f~\tilde{f} via:

f~(x1,x2)=w{0,1}2f(w)i=12(xiwi+(1xi)(1wi))=3(1x1)(1x2)+4(1x1)x2+x1(1x2)+2x1x2\begin{aligned} \tilde{f}(x_1, x_2) &= \sum_{w\in \{0,1\}^2}f(w)\cdot \prod_{i=1}^2 (x_i w_i + (1-x_i)(1-w_i))\\ &= 3(1-x_1)(1-x_2) + 4(1-x_1)x_2 + x_1(1-x_2) + 2x_1x_2 \end{aligned}

Consequently, we have f~(2,4)=3\tilde{f}(2,4) = 3.

Now consider the function f:{0,1}3Fpf: \{0,1\}^3\rightarrow \mathbb{F}_p given by f(0,0,0)=1,f(0,1,0)=2,f(1,0,0)=3,f(1,1,0)=4,f(0,0,1)=5,f(0,1,1)=6,f(1,0,1)=7,f(1,1,1)=8f(0,0,0)=1, f(0,1,0)=2, f(1,0,0)=3, f(1,1,0)=4, f(0,0,1)=5, f(0,1,1)=6, f(1,0,1)=7, f(1,1,1)=8. Using Lemma 3.6, we can compute f~\tilde{f} via

f~(x1,x2,x3)=w{0,1}3f~w(x1,x2,x3)\tilde{f}(x_1, x_2, x_3) = \sum_{w\in \{0,1\}^3}\tilde{f}_w(x_1,x_2,x_3)

where:

f~(0,0,0)(x1,x2,x3)=1(1x1)(1x2)(1x3)f~(0,1,0)(x1,x2,x3)=2(1x1)x2(1x3)f~(1,0,0)(x1,x2,x3)=3x1(1x2)(1x3)f~(1,1,0)(x1,x2,x3)=4x1x2(1x3)f~(0,0,1)(x1,x2,x3)=5(1x1)(1x2)x3f~(0,1,1)(x1,x2,x3)=6(1x1)x2x3f~(1,0,1)(x1,x2,x3)=7x1(1x2)x3f~(1,1,1)(x1,x2,x3)=8x1x2x3\begin{aligned} \tilde{f}_{(0,0,0)}(x_1, x_2, x_3) &= 1\cdot (1-x_1)\cdot (1-x_2)\cdot (1-x_3) \\ \tilde{f}_{(0,1,0)}(x_1, x_2, x_3) &= 2\cdot(1-x_1)\cdot x_2\cdot(1-x_3) \\ \tilde{f}_{(1,0,0)}(x_1, x_2, x_3) &= 3\cdot x_1\cdot (1-x_2)\cdot (1-x_3) \\ \tilde{f}_{(1,1,0)}(x_1, x_2, x_3) &= 4\cdot x_1\cdot x_2\cdot (1-x_3) \\ \tilde{f}_{(0,0,1)}(x_1, x_2, x_3) &= 5\cdot (1-x_1)\cdot (1-x_2)\cdot x_3 \\ \tilde{f}_{(0,1,1)}(x_1, x_2, x_3) &= 6\cdot (1-x_1)\cdot x_2\cdot x_3 \\ \tilde{f}_{(1,0,1)}(x_1, x_2, x_3) &= 7\cdot x_1\cdot (1-x_2)\cdot x_3 \\ \tilde{f}_{(1,1,1)}(x_1, x_2, x_3) &= 8\cdot x_1\cdot x_2\cdot x_3 \\ \end{aligned}

Consequently, we can compute f~(2,4,6)=33 mod 11=0\tilde{f}(2,4,6) = 33 \text{ mod } 11 = 0 using a total of 24 multiplications. Using the memoization procedure from Lemma 3.8, we can reduce the number of required multiplications to 20. To see that, notice that each of the following four multiplications appears twice in the above expressions for the f~w\tilde{f}_w.

  • (1x1)(1x2)(1-x_1)\cdot (1-x_2)
  • (1x1)x2(1-x_1)\cdot x_2
  • x1(1x2)x_1\cdot (1-x_2)
  • x1x2x_1\cdot x_2

Therefore, it suffices to compute each of them only once instead of evaluating each instance at (2,4,6)(2,4,6) independently. As a result, we only need a total of 20=24420 = 24 - 4 multiplications to compute f~(2,4,6)\tilde{f}(2,4,6).

Exercise 3.4

Fix some prime pp of your choosing. Write a Python program that takes as input an array of lenght 2l2^l specifying all evaluations of a function f:{0,1}lFpf: \{0,1\}^l \rightarrow \mathbb{F}_p and a vector xFplx\in \mathbb{F}_p^l, and outputs f~(x)\tilde{f}(x).

Solution

Recall that the multilinear extension f~:FplFp\tilde{f}: \mathbb{F}_p^l\rightarrow \mathbb{F}_p of a function f:{0,1}lFpf: \{0,1\}^l\rightarrow\mathbb{F}_p is defined as

f~(x)=w{0,1}lf(w)χw(x)\tilde{f}(x) = \sum_{w\in \{0,1\}^l}f(w)\cdot \chi_w(x)

where:

χw(x)=i=1l[(1xi) if wi=0, else xi]\chi_w(x)=\prod_{i=1}^l[(1-x_i)\text{ if }w_i=0\text{, else }x_i]

We can, therefore, implement the multilinear extension in Python as follows:

from itertools import product

def eval_multilinear_extension(f_vals, x, p):
    """
    Evaluate the multilinear extension of a function f: {0,1}^l -> F_p at point x in F_p^l.

    Inputs:
      - f_vals: List of 2^l field elements IN LEX ORDER(!) (w in {0,1}^l)
      - x: List of length l, point in F_p^l
      - p: Prime field modulus

    Output:
      - tilde_f(x) in F_p
    """
    l = len(x)
    result = 0
    for idx, w in enumerate(product([0, 1], repeat=l)):
        chi = 1
        for i in range(l):
            chi *= (1 - x[i]) if w[i] == 0 else x[i]
            chi %= p
        result += f_vals[idx] * chi
        result %= p
    return result

Notice that the function assumes that the input list f_vals is ordered according to lexicoraphic order on bitstrings. That is, the input values f(w)f(w) must correspond to w{0,1}lw\in \{0,1\}^l ordered like:

(0,0,...,0),(0,0,...,1),...,(1,...,1,0),(1,...,1,1)(0,0,...,0),(0,0,...,1),...,(1,...,1,0),(1,...,1,1)

This ordering is generated by product([0, 1], repeat=l) in the above code and must match exactly. If this assumption is violated, the output will be incorrect.

As an example, here's how to correctly reproduce f~(2,4,6)\tilde{f}(2,4,6) from the previous exercise:

# Input values
p = 11
# indices map to:
# (0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0), (1,1,1)
f_vals = [1, 5, 2, 6, 3, 7, 4, 8]
x = [2, 4, 6]

# Output: 0 (= 33%11)
print(eval_multilinear_extension(f_vals, x, p))

If we had passed the f_vals in a way that would result in non-lexicographic order of the values w{0,1}lw\in \{0,1\}^l instead, our function would have given a wrong result:

# Input values
p = 11
# indices map to:
# (0,0,0), (0,1,0), (1,0,0), (1,1,0), (0,0,1), (0,1,1), (1,0,1), (1,1,1)
# Note: this order is NOT LEXICOGRAPHIC
f_vals = [1, 2, 3, 4, 5, 6, 7, 8]
x = [2, 4, 6]

# Output: 1
print(eval_multilinear_extension(f_vals, x, p))