1"""H05 — Can the automorphism orbits of a j = 0 curve be given a group structure that makes the DLP a problem of size n/6?23Claim under test: the quotient map E(F_p) → E(F_p)/Aut(E) (orbits {±P, ±φP, ±φ²P}) is compatible with addition,4so that the DLP could be solved in a group of order ≈ n/6 (and lifted). Verdict: FALSE. The orbit relation is not a5congruence: P ~ φP and Q ~ Q do not imply P + Q ~ φP + Q. We exhibit explicit counterexamples on synthetic j = 0 curves6and count how often compatibility fails for random pairs (it fails for essentially all pairs).7Note: the orbit set nevertheless carries the structure needed by Pollard rho (a well-defined *iteration* on classes),8which is exactly the √6 constant-factor speed-up (Wiener–Zuccherato 1999; Duursma–Gaudry–Morain 1999) and no more.9"""10import json, random, sys, time, pathlib11ROOT = pathlib.Path(__file__).resolve().parents[2]12sys.path.insert(0, str(ROOT / "src"))13from wp34.ec import random_prime_order_curve, cube_roots_of_unity14from wp34.provenance import record151617def main():18 rng = random.Random(34); t0 = time.time(); rows = []19 for bits in (16, 20, 24):20 E = random_prime_order_curve(bits, rng, j0=True)21 beta = cube_roots_of_unity(E.p)[0]22 phi = lambda P: (beta * P[0] % E.p, P[1])23 def orbit(P):24 o = set()25 for Pi in (P, phi(P), phi(phi(P))):26 o.add(Pi); o.add(E.neg(Pi))27 return frozenset(o)28 fails, trials, example = 0, 500, None29 for _ in range(trials):30 P, Q = E.random_point(rng), E.random_point(rng)31 S = E.add(P, Q)32 S2 = E.add(phi(P), Q) # P ~ φP, so compatibility would require S2 ∈ orbit(S)33 if S2 is None or S is None:34 continue35 if S2 not in orbit(S):36 fails += 137 if example is None:38 example = {"P": [str(P[0]), str(P[1])], "Q": [str(Q[0]), str(Q[1])],39 "P+Q": [str(S[0]), str(S[1])], "phiP+Q": [str(S2[0]), str(S2[1])]}40 rows.append({"bits": bits, "p": str(E.p), "n": str(E.n), "beta": str(beta), "trials": trials,41 "compatibility_failures": fails, "failure_rate": fails / trials, "counterexample": example,42 "orbit_size_check": len(orbit(E.G)) == 6})43 print(bits, "bits: compatibility fails in", fails, "/", trials, "random pairs; |orbit(G)| = 6:", len(orbit(E.G)) == 6)44 record("orbit_quotient_counterexample", {"sizes": [16, 20, 24]}, {"rows": rows},45 seed=34, out=str(ROOT / "results/theory/orbit_quotient_counterexample.json"), started=t0)464748if __name__ == "__main__":49 main()50