You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
2.9 KiB

  1. # Plonk-CCS (https://eprint.iacr.org/2023/552) Sage prototype
  2. # utils
  3. def matrix_vector_product(M, v):
  4. n = M.nrows()
  5. r = [F(0)] * n
  6. for i in range(0, n):
  7. for j in range(0, M.ncols()):
  8. r[i] += M[i][j] * v[j]
  9. return r
  10. def hadamard_product(a, b):
  11. n = len(a)
  12. r = [None] * n
  13. for i in range(0, n):
  14. r[i] = a[i] * b[i]
  15. return r
  16. def vec_add(a, b):
  17. n = len(a)
  18. r = [None] * n
  19. for i in range(0, n):
  20. r[i] = a[i] + b[i]
  21. return r
  22. def vec_elem_mul(a, s):
  23. r = [None] * len(a)
  24. for i in range(0, len(a)):
  25. r[i] = a[i] * s
  26. return r
  27. # end of utils
  28. # can use any finite field, using a small one for the example
  29. F = GF(101)
  30. # F = GF(21888242871839275222246405745257275088696311157297823662689037894645226208583)
  31. # The following CCS instance values have been provided by Carlos
  32. # (https://github.com/CPerezz) and Edu (https://github.com/ed255),
  33. # and this sage script was made to check the CCS relation.
  34. ## Checks performed by this Plonk/CCS instance:
  35. # - binary check for x0, x1
  36. # - 2*x2 + 2*x3 == x4
  37. M0 = matrix([
  38. [F(0), 1, 0, 0, 0, 0, 0],
  39. [0, 0, 1, 0, 0, 0, 0],
  40. [0, 0, 0, 1, 0, 0, 0],
  41. [0, 0, 0, 0, 0, 0, 1],
  42. ])
  43. M1 = matrix([
  44. [F(0), 1, 0, 0, 0, 0, 0],
  45. [0, 0, 1, 0, 0, 0, 0],
  46. [0, 0, 0, 0, 1, 0, 0],
  47. [0, 0, 0, 0, 0, 0, 1],
  48. ])
  49. M2 = matrix([
  50. [F(0), 1, 0, 0, 0, 0, 0],
  51. [0, 0, 1, 0, 0, 0, 0],
  52. [0, 0, 0, 0, 0, 1, 0],
  53. [0, 0, 0, 0, 0, 0, 1],
  54. ])
  55. M3 = matrix([
  56. [F(1), 0, 0, 0, 0, 0, 0],
  57. [1, 0, 0, 0, 0, 0, 0],
  58. [0, 0, 0, 0, 0, 0, 0],
  59. [0, 0, 0, 0, 0, 0, 0],
  60. ])
  61. M4 = matrix([
  62. [F(0), 0, 0, 0, 0, 0, 0],
  63. [0, 0, 0, 0, 0, 0, 0],
  64. [2, 0, 0, 0, 0, 0, 0],
  65. [0, 0, 0, 0, 0, 0, 0],
  66. ])
  67. M5 = matrix([
  68. [F(0), 0, 0, 0, 0, 0, 0],
  69. [0, 0, 0, 0, 0, 0, 0],
  70. [2, 0, 0, 0, 0, 0, 0],
  71. [0, 0, 0, 0, 0, 0, 0],
  72. ])
  73. M6 = matrix([
  74. [F(-1), 0, 0, 0, 0, 0, 0],
  75. [-1, 0, 0, 0, 0, 0, 0],
  76. [-1, 0, 0, 0, 0, 0, 0],
  77. [0, 0, 0, 0, 0, 0, 0],
  78. ])
  79. M7 = matrix([
  80. [F(0), 0, 0, 0, 0, 0, 0],
  81. [0, 0, 0, 0, 0, 0, 0],
  82. [0, 0, 0, 0, 0, 0, 0],
  83. [0, 0, 0, 0, 0, 0, 0],
  84. ])
  85. z = [F(1), 0, 1, 2, 3, 10, 42]
  86. print("z:", z)
  87. assert len(z) == M0.ncols()
  88. # CCS parameters
  89. n = M0.ncols() # == len(z)
  90. m = M0.nrows()
  91. t=8
  92. q=5
  93. d=3
  94. S = [[3,0,1], [4,0], [5,1], [6,2], [7]]
  95. c = [1, 1, 1, 1, 1]
  96. M = [M0,M1,M2,M3,M4,M5,M6,M7]
  97. print("CCS values:")
  98. print("n: %s, m: %s, t: %s, q: %s, d: %s" % (n, m, t, q, d))
  99. print("M:", M)
  100. print("z:", z)
  101. print("S:", S)
  102. print("c:", c)
  103. # check CCS relation (this is agnostic to Plonk, for any CCS instance)
  104. r = [F(0)] * m
  105. for i in range(0, q):
  106. hadamard_output = [F(1)]*m
  107. for j in S[i]:
  108. hadamard_output = hadamard_product(hadamard_output,
  109. matrix_vector_product(M[j], z))
  110. r = vec_add(r, vec_elem_mul(hadamard_output, c[i]))
  111. print("\nCCS relation check (∑ cᵢ ⋅ ◯ Mⱼ z == 0):", r == [0]*m)
  112. assert r == [0]*m