1 of 128

Demystifying Zero-Knowledge Proofs

Elena Nadolinski

@leanthebean

elena@beanstalk.network

2 of 128

Who is this workshop for:

  • No prior knowledge necessary
  • Some experience with Solidity smart contracts
  • Basic math

3 of 128

Where to get these slides & links

Twitter: @leanthebean

4 of 128

What we’ll go over

Part 1 - theory

  • Some background knowledge
  • Overview of how ZKPs work

Part 2 - coding

  • Use Zokrates to make a smart contract that will generate NFT tokens only if the correct proof to a puzzle is given

5 of 128

Coding Part:

6 of 128

What we’ll go over

Part 2 - coding

7 of 128

What is a ZKP?

8 of 128

What is a ZKP?

The ability to prove honest computation �without revealing inputs

9 of 128

10 of 128

11 of 128

12 of 128

ZKPs ≠ privacy

SNARKs

STARKs

Bulletproofs

13 of 128

ZKPs ==

honest computation

14 of 128

f(x) = y

  • proof

15 of 128

f(x) = y

  • Merkle path to my commitment notes that cover my transaction
  • Entire Blockchain

16 of 128

f(x) = y

  • Change to a smart contract
    • One machine does the computation, all others accept new state change with a proof

17 of 128

History

  • 1985 "The Knowledge Complexity of Interactive Proof-Systems"
  • Shafi Goldwasser, Silvio Micali, and Charles Rackoff

18 of 128

Proof Size

Prover Time

Verification Time

SNARKs �(has trusted setup)

STARKs

Bulletproofs

19 of 128

Proof Size

Prover Time

Verification Time

SNARKs �(has trusted setup)

288 bytes

2.3s

10ms

STARKs

45KB-200KB

1.6s

16ms

Bulletproofs

~1.3KB

30s

1100ms

20 of 128

Projects using ZKPs

SNARKs

Zcash: has optional shielded transactions that use zk-SNARKs

Has a ceremony for the trusted setup per circuit upgrade

21 of 128

Projects using ZKPs

SNARKs

Use recursive SNARKs to give a merkle root of latest global state with a proof

New nodes do not have to sync from the genesis block to build up their in-memory global state

22 of 128

Projects using ZKPs

Bulletproofs

Use Bulletproofs for more efficient range proofs only and not for privacy directly

23 of 128

Projects using ZKPs

zk-STARKs

Batching transactions off-chain for a decentralized exchange (DEX)

24 of 128

Open Source Projects

SNARKs �

Zokrates a great SNARK domain specific language (DSL) for generating proofs and validating them on Ethereum

Bellman Rust implementation

Snarky OCaml implementation (DSL)

LIbsnark C++

Iden3’s Circum (DSL) & SnarkJS Javascript Implementation

Republic Protocol’s zksnark-rs (DSL) Rust implementation

DIZK Java Distributed system

Go-SNARK zkSNARK library implementation in Go

STARKs

Go implementation (with pretty useful links!)

C++ implementation

Bulletproofs

Ristretto Rust implementation with GREAT documentation (maintained by Chain/Interstellar)

Benedikt's Bunz Java implementation

25 of 128

Modular Math

22 (mod 12) = 10

Because 12 divides 22 one time evenly with 10 as the remainder

3 + 16 (mod 12) = 7

And so on

26 of 128

Diffie Hellman (1976)

  • First published method of public-key cryptography
  • Secret sharing of an encryption key

(Learn more on early cryptography from The Code Book)

27 of 128

Diffie Hellman (1976)

  • p = 23 (modulus) g = 5 (base)

28 of 128

Diffie Hellman (1976)

  • p = 23 (modulus) g = 5 (base)
  • Alice chooses a secret a = 4, and sends Bob A = ga mod p
    • A = 54 mod 23 = 4

29 of 128

Diffie Hellman (1976)

  • p = 23 (modulus) g = 5 (base)
  • Alice chooses a secret a = 4, and sends Bob A = ga mod p
    • A = 54 mod 23 = 4
  • Bob chooses a secret b = 3, and sends Alice B = gb mod p
    • B = 53 mod 23 = 10

30 of 128

Diffie Hellman (1976)

  • p = 23 (modulus) g = 5 (base)
  • Alice chooses a secret a = 4, and sends Bob A = ga mod p
    • A = 54 mod 23 = 4
  • Bob chooses a secret b = 3, and sends Alice B = gb mod p
    • B = 53 mod 23 = 10
  • Alice computes s = Ba mod p
    • s = gb a mod p = 104 mod 23 = 18

31 of 128

Diffie Hellman (1976)

  • p = 23 (modulus) g = 5 (base)
  • Alice chooses a secret a = 4, and sends Bob A = ga mod p
    • A = 54 mod 23 = 4
  • Bob chooses a secret b = 3, and sends Alice B = gb mod p
    • B = 53 mod 23 = 10
  • Alice computes s = Ba mod p
    • s = gb a mod p = 104 mod 23 = 18
  • Bob computes s = Ab mod p
    • s = ga b mod p = 43 mod 23 = 18

32 of 128

Diffie Hellman (1976)

  • p = 23 (modulus) g = 5 (base)
  • Alice chooses a secret a = 4, and sends Bob A = ga mod p
    • A = 54 mod 23 = 4
  • Bob chooses a secret b = 3, and sends Alice B = gb mod p
    • B = 53 mod 23 = 10
  • Alice computes s = Ba mod p
    • s = gb a mod p = 104 mod 23 = 18
  • Bob computes s = Ab mod p
    • s = ga b mod p = 43 mod 23 = 18

Now Alice and Bob know to encrypt/decrypt their messages using the shared secret 18

33 of 128

RSA (1977)

  • One of the first public key cryptosystems
  • Uses Diffie-Hellman
  • Digital Signatures

34 of 128

RSA

  • Choose 2 primes: p = 5 q = 11

n = p * q = 55

35 of 128

RSA

  • Choose 2 primes: p = 5 q = 11

n = p * q = 55

  • lcm(p-1, q-1) = 20 (totient)

36 of 128

RSA

  • Choose 2 primes: p = 5 q = 11

n = p * q = 55

  • lcm(p-1, q-1) = 20 (totient)
  • Choose a private key e that is 1 < e < 20 (coprime to 20)

e = 7

37 of 128

RSA

  • Choose 2 primes: p = 5 q = 11

n = p * q = 55

  • lcm(p-1, q-1) = 40 (totient)
  • Choose a private key e that is 1 < e < 20 (coprime to 20)

e = 7

  • Choose a public key d such that

d * e mod(totient) = 1

d = 23

38 of 128

RSA

private key e = 7 and public key d = 23

message to sign= 8

39 of 128

RSA

private key e = 7 and public key d = 23

message to sign= 8

c = 87 mod 55 = 2

40 of 128

RSA

private key e = 7 and public key d = 23

message to sign= 8

c = 87 mod 55 = 2

Anyone can check the signature using the public key 23

41 of 128

RSA

private key e = 7 and public key d = 23

message to sign= 8

c = 87 mod 55 = 2

Anyone can check the signature using the public key 23

m = 223 mod 55 = 8

42 of 128

Fiat-Shamir (1986)

  • Interactive proof of knowledge
  • “Grandfather” of ZKPs
  • Allows one to prove information about a number, without revealing the number

43 of 128

Fiat-Shamir

  • g is a number (called generator) everyone knows

44 of 128

Fiat-Shamir

  • g is a number (called generator) everyone knows
  • Alice wants to prove that she knows x, such that y = gx

45 of 128

Fiat-Shamir

  • g is a number (called generator) everyone knows
  • Alice wants to prove that she knows x, such that y = gx
  • She picks a random v, and sends t such that t = gv

46 of 128

Fiat-Shamir

  • g is a number (called generator) everyone knows
  • Alice wants to prove that she knows x, such that y = gx
  • She picks a random v, and sends t such that t = gv
  • Bob pics a random c, and sends that to Alice

47 of 128

Fiat-Shamir

  • g is a number (called generator) everyone knows
  • Alice wants to prove that she knows x, such that y = gx
  • She picks a random v, and sends t such that t = gv
  • Bob pics a random c, and sends that to Alice
  • Alice sends back r = v - cx

48 of 128

Fiat-Shamir

  • g is a number (called generator) everyone knows
  • Alice wants to prove that she knows x, such that y = gx
  • She picks a random v, and sends t such that t = gv
  • Bob pics a random c, and sends that to Alice
  • Alice sends back r = v - cx
  • Bob checks t = gryc

49 of 128

Fiat-Shamir

  • g is a number (called generator) everyone knows
  • Alice wants to prove that she knows x, such that y = gx
  • She picks a random v, and sends t such that t = gv
  • Bob pics a random c, and sends that to Alice
  • Alice sends back r = v - cx
  • Bob checks t = gryc
  • Since gryc = gv-cx gxc = gv = t

50 of 128

Fiat-Shamir

  • g is a number (called generator) everyone knows
  • Alice wants to prove that she knows x, such that y = gx
  • She picks a random v, and sends t such that t = gv
  • Bob pics a random c, and sends that to Alice
  • Alice sends back r = v - cx
  • Bob checks t = gryc
  • Since gryc = gv-cx gxc = gv = t
  • Bob knows that Alice knows the “preimage” x

51 of 128

Elliptic Curve Cryptography

  • Much more powerful and efficient tool than exponentiation & modular math

52 of 128

Elliptic Curve Cryptography

  • Much more powerful and efficient tool than exponentiation & modular math
  • Great tutorial by Andrea Corbellini
    • (much of which we’ll go over here)

53 of 128

y2 = x3 + ax + b

(where 4a3 + 27b2 ≠ 0)

54 of 128

Elliptic Curve Cryptography

~ ¾ of 100k top websites use ECDHE (https://) � (Elliptic Curve Diffie-Hellman Exchange)

96.1% of those use P256 curve (a NIST standard): � y2 = x3 - 3x + b (mod p)

Parameters generated from hashing a seed

From a video by Dan Boneh

55 of 128

Elliptic Curve Cryptography

~ ¾ of 100k top websites use ECDHE (https://) � (Elliptic Curve Diffie-Hellman Exchange)

96.1% of those use P256 curve (a NIST standard): � y2 = x3 - 3x + b (mod p)

Parameters generated from hashing a seed

From a video by Dan Boneh

NSA Conspiracy Theory

56 of 128

Elliptic Curve Cryptography

Abelian Group Properties for a set 𝔾

  • Closure: if a and b are members of 𝔾 then a + b is also
  • Associativity: (a + b) + c = a + (b + c)
  • Identity: a + 0 = 0 + a = a
  • Inverse: for every a, there exists b such that a + b = 0
  • Commutativity: a + b = b + a

57 of 128

ECC - Addition

Given 3 aligned non-zero points, their sum is: P + Q + R = 0

58 of 128

ECC - Addition

If P + Q + R = 0, then P + Q = -R

If we draw a line between 2 pts P and Q, it’ll intersect at a point R

Since P + Q = -R we can easily find R and use it to compute addition of two points from it

59 of 128

ECC - Addition

P + Q = -R

m = (3xP3 + a) / 2yP

xR = m2 - xp - xQ

yR = yP + m(xR - xP) = yQ + m(xR - xQ)

60 of 128

ECC - Addition

P + P = -R for Q = P = (1, 2) on y2 = x3 - 7x + 10

m = (3xP3 + a) / 2yP = -1

xR = m2 - xp - xQ = -1

yR = yP + m(xR - xP) = yQ + m(xR - xQ) = 4

So P + P = (-1, -4)

61 of 128

62 of 128

ECC - Multiplication

nP = P + P + … + P

(We have clever optimization techniques to do this fast)

n times

63 of 128

ECC - Multiplication

nP = P + P + … + P

nP = Q : fairly easily to compute

n = Q/P : very hard to compute (no efficient method)

Logarithm Problem (it’s not called division for conformity reasons)

n times

64 of 128

ECC - Multiplication

nP = P + P + … + P

nP = Q : fairly easily to compute

n = Q/P : very hard to compute (no efficient method)

Logarithm Problem (it’s not called division for conformity reasons)

But we’re missing cycles

n times

65 of 128

ECC - Finite Fields & Discrete Log

Finite field 𝔽p: set of elements (mod p) where p is prime

y2 = x3 + ax + b (mod p)

66 of 128

y2 = x3 - 7x + 10

p = 19

p = 127

p = 97

p = 487

67 of 128

ECC - Finite Fields (Addition)

P + P = ? in a finite field

68 of 128

ECC - Finite Fields (Addition)

P + P = ? in a finite field

P + P = (-1, -4) on y2 = x3 - 7x + 10

For a finite field on p = 19

-1 (mod 19) = 18

-4 (mod 19) = 15

So P + P on y2 = x3 - 7x + 10 (mod 19) = (18, 15)

69 of 128

70 of 128

ECC - Groups

y2 = x3 + 2x + 3 (mod 97) at point P(3, 6)

Let’s calculate some multiples of P

71 of 128

n = 0

72 of 128

n = 1

73 of 128

n = 2

74 of 128

n = 3

75 of 128

n = 4

76 of 128

n = 5

Same as n = 0

77 of 128

n = 6

Same as n = 1

78 of 128

n = 7

Same as n = 2

79 of 128

n = 8

Same as n = 3

80 of 128

n = 9

Same as n = 4

81 of 128

n = 10

Same as n = 5, 0

82 of 128

n = 11

Same as n = 1, 6

83 of 128

n = 12

Same as n = 2, 7

84 of 128

… and the pattern continues

85 of 128

ECC - Groups

y2 = x3 + 2x + 3 (mod 97) on P(3, 6) we saw a cycle

There are just 5 distinct points:

0, P, 2P, 3P, 4P

86 of 128

ECC - Groups

y2 = x3 + 2x + 3 (mod 97) on P(3, 6) we saw a cycle

There are just 5 distinct points:

0, P, 2P, 3P, 4P

These five points are closed under addition. However you add 0, P, 2P, 3P or 4P, the result is always one of these five points.

87 of 128

ECC - Groups

The point P(3, 6) on y2 = x3 + 2x + 3 (mod 97)

is therefore said to be a generator

or base point of the cyclic subgroup

and the order of this subgroup is

therefore 5

(the smallest n such that nP=0)

88 of 128

ECC - Groups

Q = nP mod p : easy to calculate

n = P/Q mod p : discrete logarithm problem

If you choose your curve, parameters, and generator point carefully, finding n becomes very very very hard

And this is exactly how the ECDSA signature scheme works

89 of 128

ECDSA

ECDSA signature (used in Bitcoin, Ethereum, etc):

  • private key random integer d from {1, … n-1} where n is the order of the subgroup
  • public key where G is the base point H = dG

90 of 128

ECDSA

A Bitcoin private key is 256 bits and gives 128-bit security level

To achieve the same security with RSA you would need 3092 bit length key

91 of 128

Pedersen Commitments

Tool for Confidential Transaction: Pedersen Commitment

Used in privacy coin Grin

Learn more about how Grin works

92 of 128

Pedersen Commitments

You could use Q = vG to “hash” or hide amounts per tx

But that’s susceptible to ‘Rainbow table’ attacks as one could precompute popular amount denominations

93 of 128

Pedersen Commitments

You could use Q = vG to “hash” or hide amounts per tx

But that’s susceptible to ‘Rainbow table’ attacks as one could precompute popular amount denominations

Solution: add a blinding factor

Com(v) = vG + bH

94 of 128

Pedersen Commitments

You could use Q = vG to “hash” or hide amounts per tx

But that’s susceptible to ‘Rainbow table’ attacks as one could precompute popular amount denominations

Solution: add a blinding factor

Com(v) = vG + bH

Where G and H are generator points

b is random number used as a blinding factor

95 of 128

Pedersen Commitments

The cool property of Pedersen Commitments (or sometimes called hashes) is that you can add them to check equality

Com(v1) = v1G + b1H

Com(v2) = v2G + b2H

Such that:

v2G + b2H + v1G + b1H = G(v2 + v1) + H(b1 + b2)

96 of 128

Bulletproofs (Range Proofs)

Proving that a number is within a range

v ​∈ [0,2n)

Zero Knowledge about the Inner Product of Two Vectors

Learn more how Bulletproofs work

97 of 128

Bulletproofs (Range Proofs)

Any number can be represented as inner product of two vectors.

5 = <[1, 0, 1] , [22, 21, 20]>

5 equals inner product of 2 vectors [1, 0, 1] and [22, 21, 20]

98 of 128

Bulletproofs (Range Proofs)

This is also how binary works

101binary = 5decimal since 1(22) + 0(21) + 1(20)

99 of 128

Bulletproofs (Range Proofs)

v = <a, 2n>

Example:

v = 5 and we wanted to prove that 5 is in range of 0 to 2n without showing 5

v ​∈ [0,2n)

100 of 128

Bulletproofs (Range Proofs)

5decimal = 101binary = 1(22) + 0(21) + 1(20)

Need at least 3 bits to represent 5: n has to be at least 3

23 = 8

Therefore it’s clear that 5 must be in range of 0 to 2n

101 of 128

Bulletproofs (Range Proofs)

v = <a, 2n>

We need to prove that:

  • That assignment of a is correct
  • We can commit to secret values using Pedersen commitments and prove we know the value using a technique similar to Fiat-Shamir

102 of 128

103 of 128

104 of 128

STARKs

Please refer to Remco from 0x for all your STARK questions :)

105 of 128

SNARKs

There are many (50+) variants of SNARKs

QAP variant (quadratic arithmetic program):

Computation → Arithmetic Circuit → R1CS → QAP → SNARK

Check out this excellent primer by Decentriq

And Zcash’s explainer

106 of 128

SNARKs - Computation

x * y + 4 = 10

Prover wants to prove that they know values x and y

107 of 128

SNARKs - Arithmetic Circuit

x * y + 4 = 10

x

y

4

*

+

10

constraint 1

output1

constraint 2

108 of 128

SNARKs - Arithmetic Circuit

x

y

4

*

+

10

constraint 1

output1

Constraint 1:

output1 = x * y

Constraint 2:

output1 + 4 = 10

Constraint 3:

Equality constraint

constraint 2

109 of 128

SNARKs - R1CS

x

y

4

*

+

10

constraint 1

output1

constraint 2

Constraint has a left input, right input and output

Such that:

left(L) * right(R) = output(O)

With 3 vectors:

<L, v> * <R, v> = <O, v>

v is the variable vector

v = [1, x, y, output1]

110 of 128

SNARKs - Arithmetic Circuit

<L, v> * <R, v> = <O, v>

v = [1, x, y, output1]

Constraint 1: x * y = output1

L = [0, 1, 0, 0] // x

R = [0, 0, 1, 0] // y

O = [0, 0, 0, 1] // output1

Constraint 2: (output1 + 4) * 1 = 10

L = [4, 0, 0, 1] // output1 + 5

R = [1, 0, 0, 0] // 1

O = [10, 0, 0, 0] // 10

x

y

4

*

+

10

constraint 1

output1

constraint 2

111 of 128

SNARKs - QAP

Create polynomials for each constraint using Lagrange interpolation

L * R = O

Constraint 1:

L = [0, 1, 0, 0] // x

R = [0, 0, 1, 0] // y

O = [0, 0, 0, 1] // output1

Constraint 2:

L = [4, 0, 0, 1] // output1 + 5

R = [1, 0, 0, 0] // 1

O = [10, 0, 0, 0] // 10

L1[1] = 0 (look at 1st constraint, 1st element of L)

L1[2] = 4 (look at 2nd constraint, 1st element of L)

2 points: (1, 0) and (2, 4). We can use Lagrange interpolation to get a polynomial: 4x - 4

L1(x) = 4x - 4

And we do this for each constraint, for each variable Li(x), Ri(x), Oi(x)

112 of 128

SNARKs - QAP

L * R = O

Constraint 1:

L = [0, 1, 0, 0] // x

R = [0, 0, 1, 0] // y

O = [0, 0, 0, 1] // output1

Constraint 2:

L = [4, 0, 0, 1] // output1 + 5

R = [1, 0, 0, 0] // 1

O = [10, 0, 0, 0] // 10

L1(x) = 4x - 4

L2(x) = -1x + 2

L3(x) = 0

L4(x) = 1x - 1

113 of 128

SNARKs - QAP

L(x) * R(x) = O(x) for x in {1, 2} (since we have 2 constraints)

114 of 128

SNARKs - QAP

L(x) * R(x) = O(x) for x in {1, 2} (since we have 2 constraints)

P = L(x) * R(x) - O(x)

115 of 128

SNARKs - QAP

L(x) * R(x) = O(x) for x in {1, 2} (since we have 2 constraints)

P = L(x) * R(x) - O(x) = T(x) * H(x)

T(x) is a publicly known evaluation used for Verification

116 of 128

SNARKs - QAP

L(x) * R(x) = O(x) for x in {1, 2} (since we have 2 constraints)

P = L(x) * R(x) - O(x) = T(x) * H(x)

T(x) is a publicly known evaluation used for Verification

H(x) is provided by the Prover and divides �L(x) * R(x) - O(x) evenly (without remainder)

117 of 128

SNARKs - QAP

L(x) * R(x) - O(x) = T(x) * H(x)

The Prover would send evaluations of x for L, R, O, and H polynomials

But how would we ensure that:

  • This “x” is hidden
  • Prover actually uses its polynomials

118 of 128

SNARKs - QAP

L(s) * R(s) - O(s) = T(s) * H(s)

s is a linear combination of (g, s⋅g ,…, sd⋅g) of length d (which corresponds to the max degrees of these polynomials)

This achieves two things:

  • We’re forcing the Prover to evaluate s on its polynomials
  • This s is encrypted, or “hidden”

119 of 128

SNARKs

How can we evaluate a value that is encrypted?

Ex: Instead of sending s plaintext, we can send E(s)

E(s) = sG

(where G is a generator point on a elliptic curve)

120 of 128

SNARKs

We can still do evaluations of E(s), even though it’s encrypted (sometimes called homomorphic addition):

Example:

E(3) + E(4) = E(3 + 4) = E(7)

121 of 128

SNARKs

L(s) * R(s) - O(s) = T(s) * H(s)

Using encrypted s, the Prover would send back:

E(L(s)), E(L(s)), E(O(s)), E(L(s)),

122 of 128

SNARKs

L(s) * R(s) - O(s) = T(s) * H(s)

Using encrypted s, the Prover would send back:

E(L(s)), E(L(s)), E(O(s)), E(L(s)),

But we still don’t have zero-knowledge as some information about the assignment is leaked

123 of 128

SNARKs

L(s) * R(s) - O(s) = T(s) * H(s)

Adding zero-knowledge:

The Prover simply adds a form of a blinding factor to the L, R, O evaluations

124 of 128

SNARKs - Protocol

  • Setup: E(s) is known to everyone, T(s) is known to everyone (s itself is thrown away, “toxic waste”)
  • Prover has L, R, O and H polynomials
  • Prover sends E(L(s)), E(R(s)), E(O(s)), E(H(s))
  • Anyone in the network can verify:�E(L(s)) * E(R(s)) - E(O(s)) = E(H(s)) * E(T(s))

125 of 128

SNARKs - what’s left

  • This is a huge oversimplification, and we skipped some details regarding “blinding factors”
  • Pairing of Elliptic Curves for the Verifier
  • This went over the Pinocchio Protocol (PGHR) 2013�Better proving systems already out there: Groth16

126 of 128

SNARKs - the Future

  • Enormous effort in research for further optimization
    • Research in pairings
    • Research in optionality of elliptic curves
    • Lattice-based SNARKs
    • And a lot, lot more

127 of 128

Let’s Go Ahead and Build One!

128 of 128

Part 2:

Zokrates