zkrunner.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. from argparse import ArgumentParser
  2. from darkfi_sdk_py.affine import Affine
  3. from darkfi_sdk_py.base import Base
  4. from darkfi_sdk_py.point import Point
  5. from darkfi_sdk_py.proof import Proof
  6. from darkfi_sdk_py.proving_key import ProvingKey
  7. from darkfi_sdk_py.scalar import Scalar
  8. from darkfi_sdk_py.verifying_key import VerifyingKey
  9. from darkfi_sdk_py.zk_binary import ZkBinary
  10. from darkfi_sdk_py.zk_circuit import ZkCircuit
  11. from pprint import pprint
  12. from sys import getsizeof
  13. from time import time
  14. import argparse
  15. def heap_add(heap, element):
  16. heap.append(element)
  17. vprint(f"HEAP: {heap}")
  18. def pubins_add(pubins, element):
  19. pubins.append(element)
  20. vprint(f"PUBLIC INPUTS: {pubins}")
  21. def get_pubins(statements, witnesses, constant_count, literals):
  22. # Python heap for executing zk statements
  23. heap = [None] * constant_count + witnesses
  24. pubins = []
  25. for stmt in statements:
  26. vprint(f"STATEMENT: {stmt}")
  27. opcode, args = stmt[0], stmt[1]
  28. if opcode == 'BaseAdd':
  29. a = heap[args[0][1]]
  30. b = heap[args[1][1]]
  31. heap_add(heap, a + b)
  32. elif opcode == 'BaseMul':
  33. a = heap[args[0][1]]
  34. b = heap[args[1][1]]
  35. heap_add(heap, a * b)
  36. elif opcode == 'BaseSub':
  37. a = heap[args[0][1]]
  38. b = heap[args[1][1]]
  39. heap_add(heap, a - b)
  40. elif opcode == 'EcAdd':
  41. a = heap[args[0][1]]
  42. b = heap[args[1][1]]
  43. heap_add(heap, a + b)
  44. elif opcode == 'EcMul':
  45. a = heap[args[0][1]]
  46. heap_add(heap, Point.mul_r_generator(a))
  47. elif opcode in {'EcMulBase', 'EcMulVarBase'}:
  48. i = args[0][1]
  49. base = heap[i]
  50. product = Point.mul_base(base)
  51. heap_add(heap, product)
  52. elif opcode == 'EcMulShort':
  53. value = heap[args[0][1]]
  54. heap_add(heap, Point.mul_short(value))
  55. elif opcode == 'EcGetX':
  56. i = args[0][1]
  57. point = heap[i]
  58. x, _ = point.to_affine().coordinates()
  59. heap_add(heap, x)
  60. elif opcode == 'EcGetY':
  61. i = args[0][1]
  62. point = heap[i]
  63. _, y = point.to_affine().coordinates()
  64. heap_add(heap, y)
  65. elif opcode == 'PoseidonHash':
  66. messages = [heap[m[1]] for m in args]
  67. heap_add(heap, Base.poseidon_hash(messages))
  68. elif opcode == 'MerkleRoot':
  69. i = heap[args[0][1]]
  70. p = heap[args[1][1]]
  71. a = heap[args[2][1]]
  72. heap_add(heap, Base.merkle_root(i, p, a))
  73. elif opcode == 'ConstrainInstance':
  74. i = args[0][1]
  75. element = heap[i]
  76. pubins_add(pubins, element)
  77. elif opcode == 'WitnessBase':
  78. type = args[0][0]
  79. assert type == 'Lit', f"type should LitType instead of {type}"
  80. i = args[0][1]
  81. element = int(literals[i][1]) # (LitType, Lit)
  82. base = Base.from_u64(element)
  83. heap_add(heap, base)
  84. elif opcode == 'CondSelect':
  85. cnd = heap[args[0][1]]
  86. thn = heap[args[1][1]]
  87. els = heap[args[2][1]]
  88. assert cnd == Base.from_u64(0) or cnd == Base.from_u64(
  89. 1), "Failed bool check"
  90. res = thn if cnd == Base.from_u64(1) else els
  91. heap_add(heap, res)
  92. elif opcode in IGNORED_OPCODES:
  93. vprint(f"IGNORE: {opcode}")
  94. else:
  95. vprint(f"NO IMPLEMENTATION: {opcode}")
  96. return pubins
  97. def bincode_data(bincode):
  98. with open(bincode, "rb") as f:
  99. bincode = f.read()
  100. zkbin = ZkBinary.decode(bincode)
  101. return {
  102. "zkbin": zkbin,
  103. "namespace": zkbin.namespace(),
  104. "witnesses": zkbin.witnesses(),
  105. "constant_count": zkbin.constant_count(),
  106. "statements": zkbin.opcodes(),
  107. "literals": zkbin.literals(),
  108. "k": zkbin.k()
  109. }
  110. IGNORED_OPCODES = {
  111. 'Noop', 'RangeCheck', 'LessThanStrict', 'LessThanLoose', 'BoolCheck',
  112. 'ConstrainEqualBase', 'ConstrainEqualPoint', 'DebugPrint'
  113. }
  114. if __name__ == "__main__":
  115. ##### Your Inputs #####
  116. bincode_path = "opcodes.no-nipoint.zk.bin"
  117. witnesses = [
  118. Base.from_u64(3),
  119. Scalar.from_u64(4),
  120. Base.from_u64(5),
  121. Base.from_u64(6),
  122. Base.from_u64(7),
  123. Base.from_u64(8),
  124. 10,
  125. [Base.from_u64(42)] * 32,
  126. Base.from_u64(1),
  127. ]
  128. ##### Setup #####
  129. bincode_data_ = bincode_data(bincode_path)
  130. zkbin = bincode_data_['zkbin']
  131. statements = bincode_data_['statements']
  132. constant_count = bincode_data_['constant_count']
  133. literals = bincode_data_['literals']
  134. K = bincode_data_['k']
  135. # Verbosity
  136. parser = argparse.ArgumentParser()
  137. verbose = parser.add_argument(
  138. '--verbose', action='store_true', help='verbose switch')
  139. args = parser.parse_args()
  140. vprint = print if args.verbose else lambda *a, **k: None
  141. ##### Proving #####
  142. pubins = get_pubins(statements, witnesses, constant_count, literals)
  143. zkcircuit = ZkCircuit(zkbin)
  144. zkcircuit.witness_base(witnesses[0])
  145. zkcircuit.witness_scalar(witnesses[1])
  146. zkcircuit.witness_base(witnesses[2])
  147. zkcircuit.witness_base(witnesses[3])
  148. zkcircuit.witness_base(witnesses[4])
  149. zkcircuit.witness_base(witnesses[5])
  150. zkcircuit.witness_u32(witnesses[6])
  151. zkcircuit.witness_merkle_path(witnesses[7])
  152. zkcircuit.witness_base(witnesses[8])
  153. zkcircuit = zkcircuit.build(zkbin)
  154. print("Making proving key.....")
  155. start = time()
  156. proving_key = ProvingKey.build(K, zkcircuit)
  157. print(f"Time for making proving key: {time() - start}")
  158. print("Proving.....")
  159. start = time()
  160. proof = Proof.create(proving_key, [zkcircuit], pubins)
  161. print(f"Time for proving: {time() - start}")
  162. ##### Verifiying #####
  163. zkcircuit_v = zkcircuit.verifier_build(zkbin)
  164. print(f"Making verifying key.....")
  165. start = time()
  166. verifying_key = VerifyingKey.build(K, zkcircuit_v)
  167. print(f"Time for making verifying key: {time() - start}")
  168. print("Verifying.....")
  169. start = time()
  170. proof.verify(verifying_key, pubins)
  171. print(f"Time for verifying {time() - start}")