5def get_order3_points_fp(A_, setup):
6 [A, C] = deepcopy(A_)
7 Fq = setup['Fp']
8
9 one_half = 1 / Fq(2)
10 one_third = 1 / Fq(3)
11 one_ninth = one_third**2
12 one_by_27 = one_third * one_ninth
13
14 A_times_one_third = A * one_third
15 A_squared = A**2
16 C_squared = C**2
17 t = (3 * C_squared - A_squared) * one_ninth
18 r = 16 * (A_squared * A) * one_by_27
19 s = 8 * A_times_one_third
20 u = r - s * C_squared
21
22 aux = C_squared**2
23 tmp = A_squared * aux
24 aux = aux * C_squared
25 y = t + \
26 one_third * \
27 setup['curt'](-2 * tmp + 8 * aux)
28
29 r = 2 * y
30 s = 6 * t
31
32 s0 = setup['sqrt'](r - s)
33
36
37 s0_squared = s0**2
38 v = -(r + s)
39 s1 = setup['sqrt'](v * s0_squared + u * s0)
40 s2 = setup['sqrt'](v * s0_squared - u * s0)
41
42 z = []
43 if s2 is None:
45 assert(s1**2 == (v * s0**2 + u * s0))
46 z.append((-s0_squared + s1) * one_half)
47 z.append((-s0_squared - s1) * one_half)
48 else:
50 assert(s2**2 == (v * s0**2 - u * s0))
51 z.append((s0_squared + s2) * one_half)
52 z.append((s0_squared - s2) * one_half)
53
54 num = [zk - s0*A_times_one_third for zk in z]
55 den = s0 * C
56
57 p = Fq.characteristic()
58
59
60 x = num[0]
61 y_squared = ((C * x**3) + (A * x**2 * den) + (C * den**2 * x)) * (den**3 * C)
62 if y_squared**((p - 1) // 2) != Fq(1):
63 num = num[::-1]
64
65
66
67 inv = 1 / den
68 x = num[0] * inv
69 coeff = A * inv * s0
70 y_squared = x**3 + coeff * x**2 + x
71 assert(y_squared**((p - 1) // 2) == Fq(1))
72
73 return num, den
74