pairing-modified-tate.sage 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. # for more info check Washington example 11.7
  2. # https://github.com/narodnik/elliptic-curves-washington-solutions
  3. p = 11
  4. K = GF(p)
  5. E = EllipticCurve(K, [-1, 1])
  6. R.<x, y> = PolynomialRing(K)
  7. n = 5
  8. P = E(3, 6)
  9. assert P.order() == 5
  10. Q = P
  11. inf = E(0)
  12. # We are computing <P, P>_5
  13. # v_5 = f_5(P) / f_5(P)
  14. # where
  15. # div(f_5) = n[P + R] - n[R]
  16. D_P = ((1, P), (-1, inf))
  17. # Random point for D_Q
  18. R = E(0, 1)
  19. D_Q = ((1, Q + R), (-1, R))
  20. # n = 5 = 1 + 4
  21. # so we perform one addition, two doublings and another addition
  22. # Step 1
  23. i = n
  24. j = 0
  25. k = 1
  26. fj = fk = 1
  27. # Compute f1 such that
  28. # div(f1) = [P + R] - [P] - [R] + [∞]
  29. # But D_P = [(3, 6)] - [∞]
  30. # so R = ∞, and hence D_1 = [P + ∞] - [P] - [∞] + [∞]
  31. # = 0
  32. # hence f1 = 1
  33. # First valuations of f0, f1
  34. (vj, vk) = (1, 1)
  35. dydx = lambda x, y: (3*x^2 - 1) / (2*y)
  36. print(f"i = {i}, j = {j}, k = {k}")
  37. while i != 0:
  38. if i % 2 == 0:
  39. i /= 2
  40. # We are computing div(l) which is
  41. # the line between kP and kP
  42. kP = k*P
  43. m = dydx(kP[0], kP[1])
  44. c = kP[1] - m*kP[0]
  45. l = y - m*x - c
  46. # And now the vertical line through 2kP
  47. _2kP = 2*kP
  48. v = x - _2kP[0]
  49. f = l / v
  50. f_valuation = 1
  51. for d, X in D_Q:
  52. f_valuation *= f(X[0], X[1])^d
  53. vk = vk^2 * f_valuation
  54. print(f" f = {f}")
  55. print(f" vk = {vk}")
  56. k *= 2
  57. else:
  58. i -= 1
  59. if j + k == 1:
  60. assert k == 1
  61. # fj = fk
  62. # vj = vk
  63. else:
  64. # Interpolate jP and kP
  65. assert j != k
  66. jP = j*P
  67. kP = k*P
  68. print(f"{jP}, {kP}")
  69. if jP[0] != kP[0]:
  70. m = (jP[1] - kP[1]) / (jP[0] - kP[0])
  71. c = jP[1] - m*jP[0]
  72. l = y - m*x - c
  73. else:
  74. l = x - jP[0]
  75. # Vertical line through (j + k)P
  76. jkP = (j + k)*P
  77. if jkP != inf:
  78. v = x - jkP[0]
  79. else:
  80. v = K(1)
  81. f = l / v
  82. print(f" f = {f}")
  83. f_valuation = 1
  84. for d, X in D_Q:
  85. f_valuation *= f(X[0], X[1])^d
  86. vj = vj * vk * f_valuation
  87. print(f" vj = {vj}")
  88. j += k
  89. print(f"i = {i}, j = {j}, k = {k}")
  90. modified_tate = vj^((p - 1) / n)
  91. print(f"result = {modified_tate}")