$30 off During Our Annual Pro Sale. View Details »

Implementing a Zero Knowledge Proof

Implementing a Zero Knowledge Proof

Slides from the talk I gave at DEFCON 27's Crypto and Privacy Village.

Cathie Yun

August 09, 2019
Tweet

More Decks by Cathie Yun

Other Decks in Programming

Transcript

  1. 1 Cathie Yun @cathieyun C r y p t o

    V i l l a g e - D E F C O N 2 0 1 9 Implementing a Zero Knowledge Proof or, How to Write Bulletproofs in Rust
  2. The story Motivation Understanding the paper Tools of the trade

    2 1 2 3 4 5 The code Range proof Rust tricks Above and beyond 6
  3. The story Motivation Understanding the paper Tools of the trade

    3 1 2 3 4 5 The code Range proof Rust tricks Above and beyond 6
  4. Confidential transaction (broken) 6 A = Com(5) B = Com(4)

    C = Com(3) D = Com(6) INPUTS OUTPUTS A + B C + D Additively homomorphic commitment
  5. Confidential transaction (broken) 7 A = Com(5) B = Com(4)

    C = Com(-1) D = Com(10) INPUTS OUTPUTS A + B C + D OH NO!!!
 integer underflow!
  6. Confidential transaction 8 A = Com(5) B = Com(4) C

    = Com(3) proof(C) D = Com(6) proof(D) INPUTS OUTPUTS A + B C + D ZK proof that amount is in range
  7. Blockchains & Bulletproofs 10 Bulletproofs provide O(log(N)) proof sizes,
 less

    than 1 Kb for most cases. Fast verification with Ristretto and AVX2;
 scales well via batching and aggregation. No trusted setup -
 cheap on-the-fly initialization of verification circuit Blockchain requirement Constrained proof size
 (all nodes must receive and verify proofs) Fast verification 
 (low latency - all verifiers must sync quickly) Ad hoc logic
 (different value flows,
 custom smart contracts)
  8. The story Motivation Understanding the paper Tools of the trade

    11 1 2 3 4 5 The code Range proof Rust tricks Above and beyond 6
  9. 12

  10. 13

  11. 14

  12. 16 Bulletproof building block: inner products Σ = c =

    <a, b> x x x x a b a0 a1 a2 … an-1 b0 b1 b2 … bn-1 We can make a proof that c = <a, b> 
 in size and O(log(n)) instead of O(n). c
  13. 17 a b c = <a, b> alo ahi blo

    bhi a' c' = <a', b'> a' = alo·x + ahi·x-1 b' = blo·x-1 + bhi·x c' = < alo·x + ahi·x-1, blo·x-1 + bhi·x > Prover gets random challenge scalar x from verifier b' The proof size is O(log(n)) instead of O(n). ... ...
  14. 18 Bulletproof range proofs apply
 math & crypto 0≤v<2n How

    do we express a range as an inner product? c=⟨a,b⟩
  15. Range statement → inner product 19 0 ≤ v <

    2n We want to prove: If this is true, then v must be a binary number of length n. v = Σ x If v=7, n=4 0 1 1 1 23 22 21 20
  16. 20 0 ≤ v < 2n We want to prove:

    If this is true, then v must be a binary number of length n. 0 1 1 1 v = 23 22 21 20 Σ Let’s call this aL v = ⟨aL, 2n⟩ x Range statement → inner product
  17. 21 0 ≤ v < 2n We want to prove:

    We can do this by proving: 1) v = ⟨ aL, 2n⟩
 2) aL ∘(aL - 1n) = 0n binary structure of v bits are actually bits (0s or 1s) Range statement → inner product
  18. 22 0≤v<2n c=⟨a,b⟩ Add blinding factors
 Combine statements v =

    ⟨aL, 2n⟩
 aL ∘(aL - 1n) = 0n Range statement → inner product
  19. Want more details? 23 I’m giving a “Bulletproofs deep dive”

    talk at DEFCON too!
 Sunday 8/11 at 11:45am at Monero Village The Bulletproofs paper: 
 https://eprint.iacr.org/2017/1066.pdf Our notes on the Bulletproofs math:
 https://doc-internal.dalek.rs/bulletproofs/notes/index.html
  20. The story Motivation Understanding the paper Tools of the trade

    24 1 2 3 4 5 The code Range proof Rust tricks Above and beyond 6
  21. What kind of elliptic curve should we use? Weierstrass e.g.

    secp256k1 Edwards e.g. Curve25519, FourQ prime-order group fastest formulas complete formulas easy in constant time ✔ ✘ ✘ ✘ ✘ ✔ ✔ ✔
  22. Examples of cofactor problems Ed25519 signature verification differs between single

    and batch verification As specified in the RFC, the set of valid signatures is not defined! Onion Service addresses in Tor had to add extra validation. Cofactor problem: 8 addresses for the same server. Monero had a critical vulnerability due to cofactors. Cofactor problem: allowed spending the same amount 8 times.
  23. Decaf & Ristretto: the best of both worlds • Decaf

    - Mike Hamburg ’15 • Cofactor 4 reduction • Ristretto - Mike Hamburg, Henry de Valence • Cofactor 8 reduction • Curve25519 has cofactor 8 29 Decaf: https://eprint.iacr.org/2015/673.pdf
 Ristretto: https://ristretto.group
  24. Curve25519 is fast! • Curve25519 has cofactor 8 • Hisil,

    Wong, Carter, Dawson ’08 introduced 
 fast parallel formulas for Curve25519 • Curve25519-dalek is a fast, pure-Rust AVX2 
 implementation of those formulas 30 curve25519-dalek: https://doc-internal.dalek.rs/curve25519_dalek/backend/avx2/index.html
 HWCD: https://www.iacr.org/archive/asiacrypt2008/53500329/53500329.pdf
 Blog post: https://medium.com/@hdevalence/accelerating-edwards-curve-arithmetic-with-parallel-formulas-ac12cf5015be
  25. Is this strategy fast? Yes! 31 IFMA AVX2 ristretto255: a

    prime-order group up to 4x faster than secp256k1.
  26. The Fiat-Shamir Heuristic Converts an interactive argument into a non-interactive

    one. Idea: replace a verifier’s random challenges with a hash of the prover’s messages. 32 Sounds good, but how do you actually implement this?
  27. Hashing data is kind of complicated! What if you forget

    to feed data into the hash? What if your data is ambiguously encoded in the hash? How do you handle multi-round protocols? Where do you put domain separators? … and many more edge cases. 33
  28. What if there was a first-class transcript object? 34 Paper

    Implementation transcript.commit_point(b"L", L); transcript.commit_point(b"R", R); let x = transcript.challenge_scalar(b"x");
  29. Merlin: STROBE-based transcripts for ZKPs Implement protocols as if they

    were interactive,
 passing a transcript parameter.
 Transformation is done in software, not by hand. Byte-oriented API, automatic message framing. Easy domain separation. Automatic sequential composition of proofs. 35 https://merlin.cool
  30. The story Motivation Understanding the paper Tools of the trade

    36 1 2 3 4 5 The code Range proof Rust tricks Above and beyond 6
  31. The story Motivation Understanding the paper Tools of the trade

    38 1 2 3 4 5 The code Range proof Rust tricks Above and beyond 6
  32. Proving: paper & code 40 page 17, lines 36-45 of

    the Bulletproofs paper let alpha = Scalar::random(rng); let A = h * alpha + msm(g_vec, a_L) + msm(h_vec, a_R); Pseudocode of implementation: src/range_proof/party.rs lines 84-110
 and src/range_proof/dealer.rs lines 100-108
  33. Proving: paper & code 41 page 17, lines 36-45 of

    the Bulletproofs paper let s_L = (0..n).map(|_| Scalar::random(rng).collect()); let s_R = (0..n).map(|_| Scalar::random(rng).collect()); let rho = Scalar::random(rng); let S = h * rho + msm(g_vec, s_L) + msm(h_vec, s_R); let alpha = Scalar::random(rng); let A = h * alpha + msm(g_vec, a_L) + msm(h_vec, a_R); Pseudocode of implementation: src/range_proof/party.rs lines 84-110
 and src/range_proof/dealer.rs lines 100-108
  34. Proving: paper & code 42 transcript.commit_point(b"A", A); transcript.commit_point(b"S", S); let

    y = transcript.challenge_scalar(b"y"); let z = transcript.challenge_scalar(b"z"); page 17, lines 36-45 of the Bulletproofs paper let s_L = (0..n).map(|_| Scalar::random(rng).collect()); let s_R = (0..n).map(|_| Scalar::random(rng).collect()); let rho = Scalar::random(rng); let S = h * rho + msm(g_vec, s_L) + msm(h_vec, s_R); let alpha = Scalar::random(rng); let A = h * alpha + msm(g_vec, a_L) + msm(h_vec, a_R); Pseudocode of implementation: src/range_proof/party.rs lines 84-110
 and src/range_proof/dealer.rs lines 100-108
  35. The story Motivation Understanding the paper Tools of the trade

    43 1 2 3 4 5 The code Range proof Rust tricks Above and beyond 6
  36. 47 Lazy and zero-cost* • Can build up points &

    scalars using Rust iterators &
 pass them into the multiscalar API to inline computation • Don’t have to do extra allocations or manage temporaries Rust iterators * except for build times
  37. Performance of 64-bit rangeproof verification 48 IFMA 3x faster than

    libsecp256k1, 7x faster than Monero. 2x faster than libsecp256k1, 4.6x faster than Monero. <1 millisecond, with SIMD backends in curve25519-dalek AVX2
  38. The story Motivation Understanding the paper Tools of the trade

    49 1 2 3 4 5 The code Range proof Rust tricks Above and beyond 6
  39. 51 Constraints Multiplicative constraint (secret-secret multiplication): x·y = z Linear

    constraint (secret variables with cleartext weights): a·x + b·y + c·z + ... = 0
  40. Why constraint systems? A constraint system can represent
 any efficiently

    verifiable program. A CS proof is proof that all the constraints
 are satisfied by certain secret inputs. 52 https://medium.com/interstellar/programmable-constraint-systems-for-bulletproofs-365b9feb92f7 FURTHER READING
  41. 54 Composition of gadgets in Cloak Cloak transaction is a

    combination of smaller gadgets with different roles. SHUFFLE MERGE SPLIT RANGE 0/1 0/1 0/1 0/1 0/1 ? Secretly reorder N values. Secretly merge or move two values. Secretly split or move two values. Check that value is not negative.
  42. 55 INPUTS A B D E C F OUTPUTS SHUFFLE

    1 R R R RANGE CHECK SHUFFLE 2 SHUFFLE 3 MERGE MERGE SPLIT SPLIT Only the prover knows where values are modified or moved. Observers cannot tell where values are actually split, merged or moved without modification. Cloak transaction
  43. 56 Randomly ordered input values are grouped by asset type.

    INPUTS $5 ¥3 $4 OUTPUTS SHUFFLE 1 R R R RANGE CHECK $5 ¥3 $4 $5 $4 ¥3 SHUFFLE 2 SHUFFLE 3 MERGE MERGE SPLIT SPLIT ¥3 $6 $3 Cloak walkthrough
  44. 57 INPUTS $5 ¥3 $4 OUTPUTS SHUFFLE 1 R R

    R RANGE CHECK $5 ¥3 $4 $5 $4 ¥3 SHUFFLE 2 $5 $4 $0 $9 $9 ¥3 $9 ¥3 SHUFFLE 3 MERGE MERGE SPLIT SPLIT ¥3 $6 $3 Cloak walkthrough Values of the same asset type 
 are fully merged together.
  45. 58 INPUTS $5 ¥3 $4 OUTPUTS SHUFFLE 1 R R

    R RANGE CHECK $5 ¥3 $4 $5 $4 ¥3 SHUFFLE 2 $0 $9 ¥3 $9 $0 ¥3 $5 $4 $0 $9 $9 ¥3 $9 ¥3 SHUFFLE 3 MERGE MERGE SPLIT SPLIT ¥3 $6 $3 Cloak walkthrough Non-zero values are reordered to the top, still grouped by asset type.
  46. 59 INPUTS $5 ¥3 $4 OUTPUTS SHUFFLE 1 R R

    R RANGE CHECK $5 ¥3 $4 $5 $4 ¥3 SHUFFLE 2 $0 $9 ¥3 $9 $0 ¥3 $5 $4 $0 $9 $9 ¥3 $9 ¥3 SHUFFLE 3 $9 $0 $6 $3 $3 ¥3 $3 ¥3 MERGE MERGE SPLIT SPLIT ¥3 $6 $3 Cloak walkthrough Values are split into target payment amounts.
  47. 60 INPUTS $5 ¥3 ¥3 $6 $4 $3 OUTPUTS SHUFFLE

    1 R R R RANGE CHECK $5 ¥3 $4 $5 $4 ¥3 SHUFFLE 2 $0 $9 ¥3 $9 $0 ¥3 $5 $4 $0 $9 $9 ¥3 $9 ¥3 SHUFFLE 3 $6 $3 ¥3 ¥3 $6 $3 $9 $0 $6 $3 $3 ¥3 $3 ¥3 MERGE MERGE SPLIT SPLIT Cloak walkthrough Values that were grouped by asset type are shuffled into a random order.
  48. 61 INPUTS $5 ¥3 ¥3 $6 $4 $3 OUTPUTS SHUFFLE

    1 R R R RANGE CHECK $5 ¥3 $4 $5 $4 ¥3 SHUFFLE 2 $0 $9 ¥3 $9 $0 ¥3 $5 $4 $0 $9 $9 ¥3 $9 ¥3 SHUFFLE 3 $6 $3 ¥3 ¥3 $6 $3 $9 $0 $6 $3 $3 ¥3 $3 ¥3 MERGE MERGE SPLIT SPLIT Cloak walkthrough All values are checked to be non-negative.
  49. 62 INPUTS Transactions of the same size are indistinguishable. A

    B D E C F OUTPUTS SHUFFLE 1 R R R RANGE CHECK SHUFFLE 2 SHUFFLE 3 MERGE MERGE SPLIT SPLIT Complete 3:3 Cloak transaction https://github.com/stellar/slingshot/spacesuit SPEC & CODE
  50. Further Reading Bulletproofs paper: 
 https://eprint.iacr.org/2017/1066.pdf Open-source GitHub repo for

    Bulletproofs in Rust:
 https://github.com/dalek-cryptography/bulletproofs Notes on the Bulletproofs math & implementation docs:
 https://doc.dalek.rs/bulletproofs/index.html Slide deck:
 https://speakerdeck.com/cathieyun 65 @cathieyun Cathie Yun