nova.sage 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
  2. Fp = GF(p)
  3. E = EllipticCurve(Fp, (0, 5))
  4. G = [E.random_point() for _ in range(5)]
  5. H = E.random_point()
  6. q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001
  7. assert H.order() == q
  8. K = GF(q)
  9. # def foo(s, x, y):
  10. # if s:
  11. # return x * y
  12. # else:
  13. # return x + y
  14. # z = foo(s, x, y)
  15. # Arithmetization for:
  16. # sxy + (s - 1)(x + y) - z = 0
  17. # s(s - 1) = 0
  18. def build_witness(x, y, s):
  19. var_1 = K(1)
  20. var_x = K(x)
  21. var_y = K(y)
  22. var_s = K(s)
  23. var_xy = var_x*var_y
  24. var_sxy = var_s*var_xy
  25. # w1 = (s - 1)(x + y)
  26. var_w1 = (var_s - 1)*(var_x + var_y)
  27. var_z = var_sxy + var_w1
  28. W = [var_x, var_y, var_s, var_xy, var_sxy, var_w1]
  29. X = [var_z, var_1]
  30. return W, X
  31. W1, X1 = build_witness(4, 6, 1)
  32. W2, X2 = build_witness(2, 3, 0)
  33. S1 = vector(W1 + X1)
  34. S2 = vector(W2 + X2)
  35. # Circuit
  36. L = matrix([
  37. [1, 0, 0, 0, 0, 0, 0, 0],
  38. [0, 0, 1, 0, 0, 0, 0, 0],
  39. [0, 0, 1, 0, 0, 0, 0, -1],
  40. [0, 0, 0, 0, 1, 1, 0, 0],
  41. [0, 0, 1, 0, 0, 0, 0, 0],
  42. ])
  43. R = matrix([
  44. [0, 1, 0, 0, 0, 0, 0, 0],
  45. [0, 0, 0, 1, 0, 0, 0, 0],
  46. [1, 1, 0, 0, 0, 0, 0, 0],
  47. [0, 0, 0, 0, 0, 0, 0, 1],
  48. [0, 0, 1, 0, 0, 0, 0, -1],
  49. ])
  50. O = matrix([
  51. [0, 0, 0, 1, 0, 0, 0, 0],
  52. [0, 0, 0, 0, 1, 0, 0, 0],
  53. [0, 0, 0, 0, 0, 1, 0, 0],
  54. [0, 0, 0, 0, 0, 0, 1, 0],
  55. [0, 0, 0, 0, 0, 0, 0, 0],
  56. ])
  57. def hadamard_prod(A, B):
  58. result = []
  59. for a_i, b_i in zip(A, B):
  60. result.append(a_i * b_i)
  61. return vector(K, result)
  62. def commit(T):
  63. r = K.random_element()
  64. C = r*H
  65. for t, G_i in zip(T, G):
  66. C += t*G_i
  67. return C
  68. assert hadamard_prod(L*S1, R*S1) == O*S1
  69. assert hadamard_prod(L*S2, R*S2) == O*S2
  70. # Now lets combine both proofs together
  71. μ1, μ2 = 1, 1
  72. E1, E2 = vector([0]*5), vector([0]*5)
  73. com_E1 = commit(E1)
  74. com_E2 = commit(E2)
  75. com_W1 = commit(W1)
  76. com_W2 = commit(W2)
  77. transcript = [
  78. L, R, O,
  79. com_E1, μ1, com_W1, X1,
  80. com_E2, μ2, com_W2, X2
  81. ]
  82. # First send over the cross term
  83. T = (hadamard_prod(L*S1, R*S2) + hadamard_prod(L*S2, R*S1)
  84. - μ1*O*S2 - μ2*O*S1)
  85. # Send to verifier
  86. com_T = commit(T)
  87. transcript += [com_T]
  88. #######
  89. # Verifier
  90. r = K.random_element()
  91. μ = μ1 + r*μ2
  92. X = vector(X1) + r*vector(X2)
  93. com_W = com_W1 + r*com_W2
  94. com_E = com_E1 + r*com_T + r^2*com_E2
  95. transcript += [r]
  96. #######
  97. W = vector(W1) + r*vector(W2)
  98. E = E1 + r*T + r^2*E2
  99. S = vector(list(W) + list(X))
  100. assert hadamard_prod(L*S, R*S) == μ*O*S + E
  101. witness = (W, E)
  102. proof = (L, R, O, com_E, μ, com_W, X)