42def get_order3_points(A, setup):
47 one_ninth = one_third**2
48 one_by_27 = one_third * one_ninth
50 A_times_one_third = A * one_third
52 t = (Fq(3) - A_squared) * one_ninth
53 r = 16 * (A_squared * A) * one_by_27
54 s = 8 * A_times_one_third
59 setup[
'curt'](-2 * A_squared + 8)
64 s0 = setup[
'sqrt'](r - s)
67 s1 = setup[
'sqrt'](v + u * i0)
68 s2 = setup[
'sqrt'](v - u * i0)
76 x = [zk-A_times_one_third
for zk
in z]
81def cgl_hash3(message, setup, verbose=True):
89 path = base_repr(int(digest, 16), base=3)[:length]
92 print(
'\nCGL Hash function over the 3-isogeny graph (CGLHash3)')
93 print(f
'Symmetric primitive:\t{s.name}')
94 print(f
'Message digest size:\t{len(digest) // 2} bytes')
95 print(f
'Random path of size:\t{len(path)} steps')
97 P = get_order3_points(setup[
'A'], setup)
99 assert(
not (xP**2 * (3 * xP**2 + 4 * setup[
'A'] * xP + 6) - 1))
104 a1, a3 = to_model(setup[
'A'], xP)
105 a1, a3 =
random_walk3(a1, a3, [ int(b)
for b
in path ], setup)
106 return EllipticCurve(setup[
'Fq'], [a1, 0, a3, -5 * a1 * a3, -a1**3 * a3 - 7 * a3**2]).
j_invariant()