halo2.sage 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import numpy as np
  2. q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001
  3. K = GF(q)
  4. P.<X> = K[]
  5. # GENERATOR^{2^s} where t * 2^s + 1 = q with t odd.
  6. # In other words, this is a t root of unity.
  7. generator = K(5)
  8. # There is a large 2^32 order subgroup in this curve because it is 2-adic
  9. #t = (K(q) - 1) / 2^32
  10. delta = generator^(2^32)
  11. def get_omega():
  12. generator = K(5)
  13. assert (q - 1) % 2^32 == 0
  14. # Root of unity
  15. t = (q - 1) / 2^32
  16. omega = generator**t
  17. assert omega != 1
  18. assert omega^(2^16) != 1
  19. assert omega^(2^31) != 1
  20. assert omega^(2^32) == 1
  21. return omega
  22. # Order of this element is 2^32
  23. omega = get_omega()
  24. k = 4
  25. n = 2^k
  26. omega = omega^(2^32 / n)
  27. assert omega^n == 1
  28. # Arithmetization for:
  29. # sxy + (s - 1)(x + y) - z = 0
  30. # s(s - 1) = 0
  31. # F1(A1 - 1) + F2 (A1 - I) + F3((1 - A1)(A2 + A3) - A4) + F4(A1 A2 A3 - A4) = 0
  32. A = []
  33. F = []
  34. var_one = K(1)
  35. var_zero = K(0)
  36. var_x = K(4)
  37. var_y = K(6)
  38. var_s = K(1)
  39. var_sxy = var_s * var_x * var_y
  40. var_1s_xy = (1 - var_s) * (var_x + var_y)
  41. # Public
  42. var_z = var_sxy + var_1s_xy
  43. # 4 advice columns
  44. # 4 fixed columns
  45. # 1 instance column
  46. # Row 1
  47. A_1_1, A_2_1, A_3_1, A_4_1 = var_one, 0, 0, 0
  48. F_1_1, F_2_1, F_3_1, F_4_1 = 1, 0, 0, 0
  49. I_1 = 0
  50. # Row 2
  51. A_1_2, A_2_2, A_3_2, A_4_2 = var_zero, 0, 0, 0
  52. F_1_2, F_2_2, F_3_2, F_4_2 = 0, 1, 0, 0
  53. I_2 = 0
  54. # Row 3
  55. A_1_3, A_2_3, A_3_3, A_4_3 = var_s, var_s, var_zero, var_zero
  56. F_1_3, F_2_3, F_3_3, F_4_3 = 0, 0, 1, 0
  57. I_3 = 0
  58. # Row 4
  59. A_1_4, A_2_4, A_3_4, A_4_4 = var_s, var_x, var_y, var_sxy
  60. F_1_4, F_2_4, F_3_4, F_4_4 = 0, 0, 0, 1
  61. I_4 = 0
  62. # Row 5
  63. A_1_5, A_2_5, A_3_5, A_4_5 = var_s, var_x, var_y, var_1s_xy
  64. F_1_5, F_2_5, F_3_5, F_4_5 = 0, 0, 1, 0
  65. I_5 = 0
  66. # Row 6
  67. A_1_6, A_2_6, A_3_6, A_4_6 = var_zero, var_sxy, var_1s_xy, var_z
  68. F_1_6, F_2_6, F_3_6, F_4_6 = 0, 0, 1, 0
  69. I_6 = 0
  70. # Row 7
  71. # z = public z
  72. A_1_7, A_2_7, A_3_7, A_4_7 = var_z, 0, 0, 0
  73. F_1_7, F_2_7, F_3_7, F_4_7 = 0, 1, 0, 0
  74. I_7 = var_z
  75. A1 = [A_1_1, A_1_2, A_1_3, A_1_4, A_1_5, A_1_6, A_1_7]
  76. A2 = [A_2_1, A_2_2, A_2_3, A_2_4, A_2_5, A_2_6, A_2_7]
  77. A3 = [A_3_1, A_3_2, A_3_3, A_3_4, A_3_5, A_3_6, A_3_7]
  78. A4 = [A_4_1, A_4_2, A_4_3, A_4_4, A_4_5, A_4_6, A_4_7]
  79. F1 = [F_1_1, F_1_2, F_1_3, F_1_4, F_1_5, F_1_6, F_1_7]
  80. F2 = [F_2_1, F_2_2, F_2_3, F_2_4, F_2_5, F_2_6, F_2_7]
  81. F3 = [F_3_1, F_3_2, F_3_3, F_3_4, F_3_5, F_3_6, F_3_7]
  82. F4 = [F_4_1, F_4_2, F_4_3, F_4_4, F_4_5, F_4_6, F_4_7]
  83. I = [I_1, I_2, I_3, I_4, I_5, I_6, I_7]
  84. # There should be 5 unused blinding rows.
  85. # see src/plonk/circuit.rs: fn blinding_factors(&self) -> usize;
  86. # We have 9 so we are perfectly fine.
  87. # Add 9 empty rows
  88. assert n - len(A1) == 9
  89. for i in range(9):
  90. A1.append(K.random_element())
  91. A2.append(K.random_element())
  92. A3.append(K.random_element())
  93. A4.append(K.random_element())
  94. F1.append(0)
  95. F2.append(0)
  96. F3.append(0)
  97. F4.append(0)
  98. I.append(K.random_element())
  99. assert (len(A1) == len(A2) == len(A3) == len(A4) == len(F1) == len(F2)
  100. == len(F3) == len(F4) == len(I) == n)
  101. for A_1_i, A_2_i, A_3_i, A_4_i, F_1_i, F_2_i, F_3_i, F_4_i, I_i in zip(
  102. A1, A2, A3, A4, F1, F2, F3, F4, I):
  103. assert (F_1_i * (A_1_i - 1)
  104. + F_2_i * (A_1_i - I_i)
  105. + F_3_i * ((1 - A_1_i) * (A_2_i + A_3_i) - A_4_i)
  106. + F_4_i * (A_1_i * A_2_i * A_3_i - A_4_i)) == 0
  107. a_1_X = P.lagrange_polynomial((omega^i, A_1_i) for i, A_1_i in enumerate(A1))
  108. a_2_X = P.lagrange_polynomial((omega^i, A_2_i) for i, A_2_i in enumerate(A2))
  109. a_3_X = P.lagrange_polynomial((omega^i, A_3_i) for i, A_3_i in enumerate(A3))
  110. a_4_X = P.lagrange_polynomial((omega^i, A_4_i) for i, A_4_i in enumerate(A4))
  111. f_1_X = P.lagrange_polynomial((omega^i, F_1_i) for i, F_1_i in enumerate(F1))
  112. f_2_X = P.lagrange_polynomial((omega^i, F_2_i) for i, F_2_i in enumerate(F2))
  113. f_3_X = P.lagrange_polynomial((omega^i, F_3_i) for i, F_3_i in enumerate(F3))
  114. f_4_X = P.lagrange_polynomial((omega^i, F_4_i) for i, F_4_i in enumerate(F4))
  115. # Treat the instance wire as a 5th advice wire
  116. a_5_X = P.lagrange_polynomial((omega^i, A_5_i) for i, A_5_i in enumerate(I))
  117. for i, (A_1_i, A_2_i, A_3_i, A_4_i, F_1_i, F_2_i, F_3_i, F_4_i, I_i) in \
  118. enumerate(zip(A1, A2, A3, A4, F1, F2, F3, F4, I)):
  119. assert a_1_X(omega^i) == A_1_i
  120. assert a_2_X(omega^i) == A_2_i
  121. assert a_3_X(omega^i) == A_3_i
  122. assert a_4_X(omega^i) == A_4_i
  123. assert a_5_X(omega^i) == I_i
  124. assert f_1_X(omega^i) == F_1_i
  125. assert f_2_X(omega^i) == F_2_i
  126. assert f_3_X(omega^i) == F_3_i
  127. assert f_4_X(omega^i) == F_4_i
  128. # beta, gamma
  129. # 0 1 2 3 4 5 6 ... 15
  130. # A1: 1, 0, s, s, s, 0, z
  131. # 16 17 18 19 20 21 22 ... 31
  132. # A2: -, -, s, x, x, sxy, -
  133. # 32 33 34 35 36 37 38 ... 47
  134. # A3: -, -, 0, y, y, (1-s)(x+y), -
  135. # 48 49 50 51 52 53 54 ... 63
  136. # A4: -, -, 0, sxy, (1-s)(x + y), z, -
  137. # 64 65 66 67 68 69 70 ... 79
  138. # A5: -, -, -, -, -, -, z
  139. permuted_indices_A1 = []
  140. y = K.random_element()
  141. gate_0 = f_1_X * (a_1_X - 1)
  142. gate_1 = f_2_X * (a_1_X - a_5_X)
  143. gate_2 = f_3_X * ((1 - a_1_X) * (a_2_X + a_3_X) - a_4_X)
  144. gate_3 = f_4_X * (a_1_X * a_2_X * a_3_X - a_4_X)
  145. h = gate_0 + y * gate_1 + y^2 * gate_2 + y^3 * gate_3
  146. t = X^n - 1
  147. for i in range(n):
  148. assert h(omega^i) == 0