groth_poly_commit.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. # This file was *autogenerated* from the file groth_poly_commit.sage
  2. from sage.all_cmdline import * # import sage library
  3. _sage_const_0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 = Integer(0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001); _sage_const_0x00 = Integer(0x00); _sage_const_0x05 = Integer(0x05); _sage_const_0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 = Integer(0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000); _sage_const_0x02 = Integer(0x02); _sage_const_0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001 = Integer(0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001); _sage_const_1000 = Integer(1000); _sage_const_1 = Integer(1); _sage_const_110 = Integer(110); _sage_const_2 = Integer(2); _sage_const_56 = Integer(56); _sage_const_89 = Integer(89); _sage_const_6543 = Integer(6543); _sage_const_0 = Integer(0); _sage_const_77 = Integer(77)
  4. import numpy as np
  5. from collections import namedtuple
  6. PolyProof = namedtuple("PolyProof", [
  7. "poly_commit",
  8. "poly_blind_commit",
  9. "poly_response",
  10. "poly_blind_respond",
  11. "x_blind_factors",
  12. "evaluation_commits",
  13. "evaluation_response",
  14. "value"
  15. ])
  16. # Implementation of Groth09 inner product proof
  17. q = _sage_const_0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001
  18. K = GF(q)
  19. a = K(_sage_const_0x00 )
  20. b = K(_sage_const_0x05 )
  21. E = EllipticCurve(K, (a, b))
  22. G = E(_sage_const_0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 , _sage_const_0x02 )
  23. p = _sage_const_0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
  24. assert E.order() == p
  25. Scalar = GF(p)
  26. # Create some generator points. Normally we would use hash to curve.
  27. # All these points will be generators since the curve is a cyclic group
  28. H = E.random_element()
  29. G_vec = [E.random_element() for _ in range(_sage_const_1000 )]
  30. def dot_product(x, y):
  31. result = None
  32. for x_i, y_i in zip(x, y):
  33. if result is None:
  34. result = int(x_i) * y_i
  35. else:
  36. result += int(x_i) * y_i
  37. return result
  38. def poly_commit(p):
  39. # Sage randomly orders terms. No guarantee about ordering.
  40. #a = np.array(p.coefficients())
  41. a = np.array([p[i] for i in range(p.degree() + _sage_const_1 )])
  42. r = Scalar.random_element()
  43. C_x = int(r) * H + dot_product(a, G_vec)
  44. return (r, C_x)
  45. def create_proof(p, r, x):
  46. a = np.array([p[i] for i in range(p.degree() + _sage_const_1 )])
  47. #a = np.array(p.coefficients())
  48. x = np.array([x**i for i in range(p.degree() + _sage_const_1 )])
  49. # Evaluate the polynomial
  50. z = a.dot(x)
  51. assert len(a) == len(x)
  52. # We will now construct a proof
  53. # Commitments
  54. t = Scalar.random_element()
  55. #r = Scalar.random_element()
  56. s = Scalar.random_element()
  57. C_z = int(t) * H + int(z) * G
  58. C_x = int(r) * H + dot_product(a, G_vec)
  59. C_y = int(s) * H + dot_product(x, G_vec)
  60. d_x = np.array([Scalar.random_element() for _ in range(len(x))])
  61. d_y = np.array([Scalar.random_element() for _ in range(len(x))])
  62. r_d = Scalar.random_element()
  63. s_d = Scalar.random_element()
  64. A_d = int(r_d) * H + dot_product(d_x, G_vec)
  65. B_d = int(s_d) * H + dot_product(d_y, G_vec)
  66. # (cx + d_x)(cy + d_y) = d_x d_y + c(x d_y + y d_x) + c^2 xy
  67. t_0 = Scalar.random_element()
  68. t_1 = Scalar.random_element()
  69. C_0 = int(t_0) * H + int(d_x.dot(d_y)) * G
  70. C_1 = int(t_1) * H + int(a.dot(d_y) + x.dot(d_x)) * G
  71. # Challenge
  72. # Using the Fiat-Shamir transform, we would hash the transcript
  73. #c = Scalar.random_element()
  74. c = _sage_const_110
  75. # Responses
  76. f_x = c * a + d_x
  77. f_y = c * x + d_y
  78. r_x = c * r + r_d
  79. s_y = c * s + s_d
  80. t_z = c**_sage_const_2 * t + c * t_1 + t_0
  81. # Verify
  82. #B_d = int(s_d) * H + dot_product(d_y, G_vec)
  83. #C_y = int(s) * H + dot_product(x, G_vec)
  84. assert int(c) * C_x + A_d == int(r_x) * H + dot_product(f_x, G_vec)
  85. assert int(c) * C_y + B_d == int(s_y) * H + dot_product(f_y, G_vec)
  86. # Actual inner product check
  87. # Comm(f_x f_y) == e^2 C_z + c Comm(x d_y + y d_x) + Comm(d_x d_y)
  88. assert int(t_z) * H + int(f_x.dot(f_y)) * G == int(c**_sage_const_2 ) * C_z + int(c) * C_1 + C_0
  89. return PolyProof(
  90. poly_commit=C_x,
  91. poly_blind_commit=A_d,
  92. poly_response=f_x,
  93. poly_blind_respond=r_x,
  94. x_blind_factors=(s_d, d_y, s),
  95. evaluation_commits=(C_0, C_1, C_z),
  96. evaluation_response=t_z,
  97. value=z
  98. )
  99. def verify_proof(proof, x):
  100. C_x = proof.poly_commit
  101. A_d = proof.poly_blind_commit
  102. f_x = proof.poly_response
  103. r_x = proof.poly_blind_respond
  104. (s_d, d_y, s) = proof.x_blind_factors
  105. (C_0, C_1, C_z) = proof.evaluation_commits
  106. t_z = proof.evaluation_response
  107. z = proof.value
  108. x = np.array([x**i for i in range(len(a))])
  109. c = _sage_const_110
  110. f_y = c * x + d_y
  111. s_y = c * s + s_d
  112. B_d = int(s_d) * H + dot_product(d_y, G_vec)
  113. C_y = int(s) * H + dot_product(x, G_vec)
  114. if int(c) * C_x + A_d != int(r_x) * H + dot_product(f_x, G_vec):
  115. return False
  116. if int(c) * C_y + B_d != int(s_y) * H + dot_product(f_y, G_vec):
  117. return False
  118. # Actual inner product check
  119. # Comm(f_x f_y) == e^2 C_z + c Comm(x d_y + y d_x) + Comm(d_x d_y)
  120. if int(t_z) * H + int(f_x.dot(f_y)) * G != int(c**_sage_const_2 ) * C_z + int(c) * C_1 + C_0:
  121. return False
  122. return True
  123. #R = LaurentPolynomialRing(Scalar, names=('x',)); (x,) = R._first_ngens(1)
  124. #a = np.array([
  125. # Scalar(_sage_const_110 ), Scalar(_sage_const_56 ), Scalar(_sage_const_89 ), Scalar(_sage_const_6543 ), Scalar(_sage_const_2 )
  126. #])
  127. #p = _sage_const_0
  128. #for i, a_i in enumerate(a):
  129. # p += a_i * x**i
  130. #print(p)
  131. #xx = Scalar(_sage_const_77 )
  132. #r, commit = poly_commit(p)
  133. #proof = create_proof(p, r, xx)
  134. #assert verify_proof(proof, xx)
  135. #assert proof.poly_commit == commit
  136. #assert proof.value == p(xx)