sonic.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. # From the Sonic paper
  2. from finite_fields import finitefield
  3. import numpy as np
  4. from multipoly import Variable, MultivariatePolynomial
  5. p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
  6. fp = finitefield.IntegersModP(p)
  7. var_one = fp(1)
  8. var_x = fp(4)
  9. var_y = fp(6)
  10. var_s = fp(1)
  11. var_xy = var_x * var_y
  12. var_sxy = var_s * var_xy
  13. var_1_neg_s = var_one - var_s
  14. var_x_y = var_x + var_y
  15. var_1_neg_s_x_y = var_1_neg_s * var_x_y
  16. var_s_neg_1 = -var_1_neg_s
  17. var_zero = fp(0)
  18. public_v = var_s * (var_x * var_y) + (1 - var_s) * (var_x + var_y)
  19. a = np.array([
  20. var_one, var_x, var_xy, var_1_neg_s, var_s
  21. ])
  22. b = np.array([
  23. var_one, var_y, var_s, var_x_y, var_s_neg_1
  24. ])
  25. c = np.array([
  26. var_one, var_xy, var_sxy, var_1_neg_s_x_y, var_zero
  27. ])
  28. assert len(a) == len(b)
  29. assert len(b) == len(c)
  30. for i, (a_i, b_i, c_i) in enumerate(zip(a, b, c), 1):
  31. try:
  32. assert a_i * b_i == c_i
  33. except AssertionError:
  34. print("Error for %i" % i)
  35. raise
  36. # 1 - s = -(s - 1)
  37. u1 = np.array([0, 0, 0, 1, 0])
  38. v1 = np.array([0, 0, 0, 0, 1])
  39. w1 = np.array([0, 0, 0, 0, 0])
  40. k1 = 0
  41. assert a.dot(u1) + b.dot(v1) + c.dot(w1) == k1
  42. # xy = xy
  43. u2 = np.array([0, 0, 1, 0, 0])
  44. v2 = np.array([0, 0, 0, 0, 0])
  45. w2 = np.array([0, -1, 0, 0, 0])
  46. k2 = 0
  47. assert a.dot(u2) + b.dot(v2) + c.dot(w2) == k2
  48. # s = s
  49. u3 = np.array([0, 0, 0, 0, -1])
  50. v3 = np.array([0, 0, 1, 0, 0])
  51. w3 = np.array([0, 0, 0, 0, 0])
  52. k3 = 0
  53. assert a.dot(u3) + b.dot(v3) + c.dot(w3) == k3
  54. # zero = 0
  55. u4 = np.array([0, 0, 0, 0, 0])
  56. v4 = np.array([0, 0, 0, 0, 0])
  57. w4 = np.array([0, 0, 0, 0, 1])
  58. k4 = 0
  59. assert a.dot(u4) + b.dot(v4) + c.dot(w4) == k4
  60. # 1 - s
  61. u5 = np.array([1, 0, 0, -1, 0])
  62. v5 = np.array([0, 0, -1, 0, 0])
  63. w5 = np.array([0, 0, 0, 0, 0])
  64. k5 = 0
  65. assert a.dot(u5) + b.dot(v5) + c.dot(w5) == k5
  66. # x + y
  67. u6 = np.array([0, 1, 0, 0, 0])
  68. v6 = np.array([0, 1, 0, -1, 0])
  69. w6 = np.array([0, 0, 0, 0, 0])
  70. k6 = 0
  71. assert a.dot(u6) + b.dot(v6) + c.dot(w6) == k6
  72. # Final check:
  73. # v = s(xy) + (1 - s)(x + y)
  74. u7 = np.array([0, 0, 0, 0, 0])
  75. v7 = np.array([0, 0, 0, 0, 0])
  76. w7 = np.array([0, 0, 1, 1, 0])
  77. k7 = public_v
  78. assert a.dot(u7) + b.dot(v7) + c.dot(w7) == k7
  79. u = np.vstack((u1, u2, u3, u4, u5, u6, u7))
  80. v = np.vstack((v1, v2, v3, v4, v5, v6, v7))
  81. w = np.vstack((w1, w2, w3, w4, w5, w6, w7))
  82. assert u.shape == v.shape
  83. assert u.shape == w.shape
  84. k = np.array((k1, k2, k3, k4, k5, k6, k7))
  85. y = Variable("Y")
  86. p = MultivariatePolynomial()
  87. for i, (a_i, b_i, c_i) in enumerate(zip(a, b, c), 1):
  88. #print(a_i, "\t", b_i, "\t", c_i)
  89. p += y**i * (a_i * b_i - c_i)
  90. print("Polynomial:", p)
  91. p = MultivariatePolynomial()
  92. for q, (u_q, v_q, w_q, k_q) in enumerate(zip(u, v, w, k)):
  93. p += y**q * (a.dot(u_q) + b.dot(v_q) + c.dot(w_q) - k_q)
  94. print("Polynomial:", p)