bootle16.py 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. # Notes from paper:
  2. # "Efficient Zero-Knowledge Arguments for Arithmetic Circuits in the
  3. # Discrete Log Setting" by Bootle and others (EUROCRYPT 2016)
  4. from finite_fields import finitefield
  5. import numpy as np
  6. q = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
  7. fq = finitefield.IntegersModP(q)
  8. # Number of variables
  9. m = 16
  10. # Number of rows for multiplication statements
  11. n = 2
  12. N = n * m
  13. # Initialize zeroed table
  14. aux = np.full(m, fq(0))
  15. # From the zk-explainer document, we will represent the function:
  16. #
  17. # def foo(w, a, b):
  18. # if w:
  19. # return a * b
  20. # else:
  21. # return a + b
  22. #
  23. # Which can be translated mathematically to the statements:
  24. #
  25. # ab = m
  26. # w(m - a - b) = v - a - b
  27. # w^2 = w
  28. #
  29. # Where m is an intermediate value.
  30. one = 0
  31. aux[one] = fq(1)
  32. a = 1
  33. b = 2
  34. w = 3
  35. aux[a] = fq(110)
  36. aux[b] = fq(4)
  37. aux[w] = fq(1)
  38. # Calculate intermediate advice values
  39. m = 4
  40. aux[m] = aux[a] * aux[b]
  41. # Calculate public input values
  42. v = 5
  43. aux[v] = aux[w] * (aux[a] * aux[b]) + \
  44. (aux[one] - aux[w]) * (aux[a] + aux[b])
  45. # Just a quick enforcement check:
  46. assert aux[a] * aux[b] == aux[m]
  47. assert aux[w] * (aux[m] - aux[a] - aux[b]) == aux[v] - aux[a] - aux[b]
  48. assert aux[w] * aux[w] == aux[w]
  49. # Setup the gates. For each row of a, b and c, the statement a b = c holds