plonk.sage 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001
  2. K = GF(q)
  3. # The pallas and vesta curves are 2-adic. This means there is a large
  4. # power of 2 subgroup within both of their fields.
  5. # This function finds a generator for this subgroup within the field.
  6. def get_omega():
  7. # Slower alternative:
  8. # generator = K.multiplicative_generator()
  9. # Just hardcode the value here instead
  10. generator = K(5)
  11. assert (q - 1) % 2^32 == 0
  12. # Root of unity
  13. t = (q - 1) / 2^32
  14. omega = generator**t
  15. assert omega != 1
  16. assert omega^(2^16) != 1
  17. assert omega^(2^31) != 1
  18. assert omega^(2^32) == 1
  19. return omega
  20. # Order of this element is 2^32
  21. omega = get_omega()
  22. var_one = K(1)
  23. var_x = K(4)
  24. var_y = K(6)
  25. var_s = K(1)
  26. var_xy = var_x * var_y
  27. var_x_y = var_x + var_y
  28. var_1_neg_s = var_one - var_s
  29. var_sxy = var_s * var_xy
  30. var_1_neg_s_x_y = var_1_neg_s * var_x_y
  31. #var_s_neg_1 = -var_1_neg_s
  32. var_zero = K(0)
  33. public_value = -(var_s * (var_x * var_y) + (1 - var_s) * (var_x + var_y))
  34. # See also the file plonk-naive.sage
  35. # x * y = xy
  36. a1, b1, c1 = var_x, var_y, var_xy
  37. Ql1, Qr1, Qm1, Qo1, Qc1 = 0, 0, 1, -1, 0
  38. assert Ql1 * a1 + Qr1 * b1 + Qm1 * a1 * b1 + Qo1 * c1 + Qc1 == 0
  39. # x + y = (x + y)
  40. a2, b2, c2 = var_x, var_y, var_x_y
  41. Ql2, Qr2, Qm2, Qo2, Qc2 = 1, 1, 0, -1, 0
  42. assert Ql2 * a2 + Qr2 * b2 + Qm2 * a2 * b2 + Qo2 * c2 + Qc2 == 0
  43. # 1 - s = (1 - s)
  44. a3, b3, c3 = var_one, var_s, var_1_neg_s
  45. Ql3, Qr3, Qm3, Qo3, Qc3 = 1, -1, 0, -1, 0
  46. assert Ql3 * a3 + Qr3 * b3 + Qm3 * a3 * b3 + Qo3 * c3 + Qc3 == 0
  47. # s * (xy) = sxy
  48. a4, b4, c4 = var_s, var_xy, var_sxy
  49. Ql4, Qr4, Qm4, Qo4, Qc4 = 0, 0, 1, -1, 0
  50. assert Ql4 * a4 + Qr4 * b4 + Qm4 * a4 * b4 + Qo4 * c4 + Qc4 == 0
  51. # (1 - s) * (x + y) = [(1 - s)(x + y)]
  52. a5, b5, c5 = var_1_neg_s, var_x_y, var_1_neg_s_x_y
  53. Ql5, Qr5, Qm5, Qo5, Qc5 = 0, 0, 1, -1, 0
  54. assert Ql5 * a5 + Qr5 * b5 + Qm5 * a5 * b5 + Qo5 * c5 + Qc5 == 0
  55. # (sxy) + [(1 - s)(x + y)] = public_value
  56. # c6 is unused
  57. a6, b6, c6 = var_sxy, var_1_neg_s_x_y, var_zero
  58. Ql6, Qr6, Qm6, Qo6, Qc6 = 1, 1, 0, 0, 0
  59. assert Ql6 * a6 + Qr6 * b6 + Qm6 * a6 * b6 + Qo6 * c6 + Qc6 + public_value == 0
  60. # one == 1, b7 and c7 unused
  61. a7, b7, c7 = var_one, var_zero, var_zero
  62. Ql7, Qr7, Qm7, Qo7, Qc7 = 1, 0, 0, 0, -1
  63. assert Ql7 * a7 + Qr7 * b7 + Qm7 * a7 * b7 + Qo7 * c7 + Qc7 == 0
  64. # Add a last fake constraint so n is a power of 2
  65. # This is needed since we are working with omega whose size is 2^32
  66. # and we will create a generator from it whose order is 2^3
  67. a8, b8, c8 = var_zero, var_zero, var_zero
  68. Ql8, Qr8, Qm8, Qo8, Qc8 = 0, 0, 0, 0, 0
  69. assert Ql8 * a8 + Qr8 * b8 + Qm8 * a8 * b8 + Qo8 * c8 + Qc8 == 0
  70. a = [a1, a2, a3, a4, a5, a6, a7, a8]
  71. b = [b1, b2, b3, b4, b5, b6, b7, b8]
  72. c = [c1, c2, c3, c4, c5, c6, c7, c8]
  73. Ql = [Ql1, Ql2, Ql3, Ql4, Ql5, Ql6, Ql7, Ql8]
  74. Qr = [Qr1, Qr2, Qr3, Qr4, Qr5, Qr6, Qr7, Qr8]
  75. Qm = [Qm1, Qm2, Qm3, Qm4, Qm5, Qm6, Qm7, Qm8]
  76. Qo = [Qo1, Qo2, Qo3, Qo4, Qo5, Qo6, Qo7, Qo8]
  77. Qc = [Qc1, Qc2, Qc3, Qc4, Qc5, Qc6, Qc7, Qc8]
  78. public_values = [0, 0, 0, 0, 0, public_value, 0, 0]
  79. for a_i, b_i, c_i, Ql_i, Qr_i, Qm_i, Qo_i, Qc_i, public_i in \
  80. zip(a, b, c, Ql, Qr, Qm, Qo, Qc, public_values):
  81. assert (Ql_i * a_i + Qr_i * b_i + Qm_i * a_i * b_i + Qo_i * c_i
  82. + Qc_i + public_i) == 0
  83. # 1 2 3 4 5 6 7 8
  84. # a: x, x, 1, s, 1 - s, sxy, 1 -
  85. #
  86. # 9 10 11 12 13 14 15 16
  87. # b: y, y, s, xy, x + y, (1 - s)(x + y), - -
  88. #
  89. # 17 18 19 20 21 22 23 24
  90. # c: xy, x + y, 1 - s, sxy, (1 - s)(x + y), -, - -
  91. permuted_indices_a = [2, 1, 7, 11, 19, 20, 3, 8]
  92. permuted_indices_b = [9, 10, 4, 17, 18, 21, 15, 16]
  93. permuted_indices_c = [12, 13, 5, 6, 14, 22, 23, 24]
  94. eval_domain = range(0, 8 * 3)
  95. witness = a + b + c
  96. permuted_indices = permuted_indices_a + permuted_indices_b + permuted_indices_c
  97. for i, val in enumerate(a + b + c):
  98. assert val == witness[permuted_indices[i] - 1]
  99. # Just used to check our values are correct
  100. del witness
  101. del permuted_indices