zkrunner.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #!/usr/bin/env python3
  2. from argparse import ArgumentParser
  3. from darkfi_sdk_py.affine import Affine
  4. from darkfi_sdk_py.base import Base
  5. from darkfi_sdk_py.scalar import Scalar
  6. from darkfi_sdk_py.proof import Proof
  7. from darkfi_sdk_py.proving_key import ProvingKey
  8. from darkfi_sdk_py.point import Point
  9. from darkfi_sdk_py.verifying_key import VerifyingKey
  10. from darkfi_sdk_py.zk_circuit import ZkCircuit
  11. from darkfi_sdk_py.zk_binary import ZkBinary
  12. from time import time
  13. from sys import getsizeof
  14. def insert_heap(heap, element):
  15. print(f"Heap before: {heap}, element: {element}")
  16. heap.append(element)
  17. def insert_publics(publics, element):
  18. print(f"Publics before: {publics}, element: {element}")
  19. publics.append(element)
  20. def get_publics(statements, witnesses, constant_count, literals):
  21. # Python heap for executing zk statements
  22. heap = [None] * constant_count + witnesses
  23. publics = []
  24. for stmt in statements:
  25. print('---------------- BEGIN ------------------')
  26. print(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. insert_heap(heap, a.add(b))
  32. elif opcode == 'BaseMul':
  33. a = heap[args[0][1]]
  34. b = heap[args[1][1]]
  35. insert_heap(heap, a.mul(b))
  36. elif opcode == 'BaseSub':
  37. a = heap[args[0][1]]
  38. b = heap[args[1][1]]
  39. insert_heap(heap, a.sub(b))
  40. elif opcode == 'EcAdd':
  41. a = heap[args[0][1]]
  42. b = heap[args[1][1]]
  43. insert_heap(heap, a.add(b))
  44. elif opcode == 'EcMul':
  45. a = heap[args[0][1]]
  46. insert_heap(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. insert_heap(heap, product)
  52. elif opcode == 'EcMulShort':
  53. value = heap[args[0][1]]
  54. insert_heap(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. insert_heap(heap, x)
  60. elif opcode == 'EcGetY':
  61. i = args[0][1]
  62. point = heap[i]
  63. _, y = point.to_affine().coordinates()
  64. insert_heap(heap, y)
  65. elif opcode == 'PoseidonHash':
  66. messages = [heap[m[1]] for m in args]
  67. insert_heap(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. insert_heap(heap, Base.merkle_root(i, p, a))
  73. elif opcode == 'ConstrainInstance':
  74. i = args[0][1]
  75. element = heap[i]
  76. insert_publics(publics, element)
  77. elif opcode == 'WitnessBase':
  78. type = args[0][0]
  79. assert type == 'Lit', f"type should LitType instead of {type}"
  80. print(args)
  81. i = args[0][1]
  82. element = int(literals[i][1]) # (LitType, Lit)
  83. base = Base(element)
  84. insert_heap(heap, base)
  85. elif opcode == 'CondSelect':
  86. cnd = heap[args[0][1]]
  87. thn = heap[args[1][1]]
  88. els = heap[args[2][1]]
  89. assert cnd.eq(Base(0)) or cnd.eq(Base(1)), "Failed bool check"
  90. res = thn if cnd.eq(Base(1)) else els
  91. insert_heap(heap, res)
  92. elif opcode in IGNORED_OPCODES:
  93. print(f"Processed opcode: {opcode}")
  94. else:
  95. print(f"Missing implementation: {opcode}")
  96. print("-------------------- END --------------------")
  97. print("-----------------------------------")
  98. print(f"Publics: {publics}")
  99. print("-----------------------------------")
  100. return publics
  101. def bincode_data(bincode):
  102. with open(bincode, "rb") as f:
  103. bincode = f.read()
  104. zkbin = ZkBinary.decode(bincode)
  105. return {"zkbin": zkbin,
  106. "namespace": zkbin.namespace(),
  107. "witnesses": zkbin.witnesses(),
  108. "constant_count": zkbin.constant_count(),
  109. "statements": zkbin.opcodes(),
  110. "literals": zkbin.literals()}
  111. IGNORED_OPCODES = {
  112. 'Noop',
  113. 'RangeCheck',
  114. 'LessThanStrict',
  115. 'LessThanLoose',
  116. 'BoolCheck',
  117. 'ConstrainEqualBase',
  118. 'ConstrainEqualPoint',
  119. 'DebugPrint'
  120. }
  121. K = 13
  122. if __name__ == "__main__":
  123. ##### Script inputs #####
  124. bincode_path = "opcodes.no-nipoint.zk.bin"
  125. # bincode_path = "../../example/simple.zk.bin"
  126. bincode_data_ = bincode_data(bincode_path)
  127. zkbin, statements, constant_count, literals = bincode_data_['zkbin'], bincode_data_['statements'], bincode_data_['constant_count'], bincode_data_['literals']
  128. witnesses = [
  129. Base(3),
  130. Scalar(4),
  131. Base(5),
  132. Base(6),
  133. Base(7),
  134. Base(8),
  135. 10,
  136. [Base(42)] * 32,
  137. Base(1),
  138. ]
  139. ##### Proving #####
  140. print("Making public inputs based off witnesses......")
  141. publics = get_publics(statements, witnesses, constant_count, literals)
  142. print("Witnessing into prover's circuit.....")
  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], publics)
  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, publics)
  171. print(f"Time for verifying {time() - start}")