| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- # for more info check Washington example 11.7
- # https://github.com/narodnik/elliptic-curves-washington-solutions
- p = 11
- K = GF(p)
- E = EllipticCurve(K, [-1, 1])
- R.<x, y> = PolynomialRing(K)
- n = 5
- P = E(3, 6)
- assert P.order() == 5
- Q = P
- inf = E(0)
- # We are computing <P, P>_5
- # v_5 = f_5(P) / f_5(P)
- # where
- # div(f_5) = n[P + R] - n[R]
- D_P = ((1, P), (-1, inf))
- # Random point for D_Q
- R = E(0, 1)
- D_Q = ((1, Q + R), (-1, R))
- # n = 5 = 1 + 4
- # so we perform one addition, two doublings and another addition
- # Step 1
- i = n
- j = 0
- k = 1
- fj = fk = 1
- # Compute f1 such that
- # div(f1) = [P + R] - [P] - [R] + [∞]
- # But D_P = [(3, 6)] - [∞]
- # so R = ∞, and hence D_1 = [P + ∞] - [P] - [∞] + [∞]
- # = 0
- # hence f1 = 1
- # First valuations of f0, f1
- (vj, vk) = (1, 1)
- dydx = lambda x, y: (3*x^2 - 1) / (2*y)
- print(f"i = {i}, j = {j}, k = {k}")
- while i != 0:
- if i % 2 == 0:
- i /= 2
- # We are computing div(l) which is
- # the line between kP and kP
- kP = k*P
- m = dydx(kP[0], kP[1])
- c = kP[1] - m*kP[0]
- l = y - m*x - c
- # And now the vertical line through 2kP
- _2kP = 2*kP
- v = x - _2kP[0]
- f = l / v
- f_valuation = 1
- for d, X in D_Q:
- f_valuation *= f(X[0], X[1])^d
- vk = vk^2 * f_valuation
- print(f" f = {f}")
- print(f" vk = {vk}")
- k *= 2
- else:
- i -= 1
- if j + k == 1:
- assert k == 1
- # fj = fk
- # vj = vk
- else:
- # Interpolate jP and kP
- assert j != k
- jP = j*P
- kP = k*P
- print(f"{jP}, {kP}")
- if jP[0] != kP[0]:
- m = (jP[1] - kP[1]) / (jP[0] - kP[0])
- c = jP[1] - m*jP[0]
- l = y - m*x - c
- else:
- l = x - jP[0]
- # Vertical line through (j + k)P
- jkP = (j + k)*P
- if jkP != inf:
- v = x - jkP[0]
- else:
- v = K(1)
- f = l / v
- print(f" f = {f}")
-
- f_valuation = 1
- for d, X in D_Q:
- f_valuation *= f(X[0], X[1])^d
- vj = vj * vk * f_valuation
- print(f" vj = {vj}")
- j += k
- print(f"i = {i}, j = {j}, k = {k}")
- modified_tate = vj^((p - 1) / n)
- print(f"result = {modified_tate}")
|