"""Figure: geometry of the elliptic-curve group law over the reals (illustrative; curve y² = x³ − 3x + 3).""" import numpy as np, matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt, pathlib ROOT = pathlib.Path(__file__).resolve().parents[1] plt.rcParams.update({"font.family": "serif", "font.size": 9, "mathtext.fontset": "stix"}) a, b = -3.0, 3.0 f = lambda x: x**3 + a * x + b xs = np.linspace(-2.2, 2.6, 2000); ys = np.sqrt(np.clip(f(xs), 0, None)); m = f(xs) >= 0 fig, axes = plt.subplots(1, 2, figsize=(7.0, 3.2)) for ax in axes: ax.plot(xs[m], ys[m], "k-", lw=1.2); ax.plot(xs[m], -ys[m], "k-", lw=1.2) ax.axhline(0, color="gray", lw=0.4); ax.axvline(0, color="gray", lw=0.4); ax.set_xlim(-2.3, 2.7); ax.set_ylim(-4.5, 4.5) ax.set_xlabel("$x$"); ax.set_ylabel("$y$") # addition P + Q xP, xQ = -1.6, 0.3 P = (xP, np.sqrt(f(xP))); Q = (xQ, np.sqrt(f(xQ))) lam = (Q[1] - P[1]) / (Q[0] - P[0]); x3 = lam**2 - P[0] - Q[0]; y3 = lam * (P[0] - x3) - P[1] ax = axes[0] ax.plot(xs, P[1] + lam * (xs - P[0]), "C0--", lw=0.9) for pt, lab in ((P, "$P$"), (Q, "$Q$"), ((x3, -y3), "$-(P+Q)$"), ((x3, y3), "$P+Q$")): ax.plot(*pt, "o", color="C3", ms=4); ax.annotate(lab, pt, xytext=(4, 4), textcoords="offset points") ax.plot([x3, x3], [y3, -y3], "C2:", lw=0.9); ax.set_title("Chord: $P+Q$") # doubling xP = -0.9; P = (xP, np.sqrt(f(xP))); lam = (3 * xP**2 + a) / (2 * P[1]); x3 = lam**2 - 2 * xP; y3 = lam * (xP - x3) - P[1] ax = axes[1] ax.plot(xs, P[1] + lam * (xs - P[0]), "C0--", lw=0.9) for pt, lab in ((P, "$P$"), ((x3, -y3), "$-2P$"), ((x3, y3), "$2P$")): ax.plot(*pt, "o", color="C3", ms=4); ax.annotate(lab, pt, xytext=(4, 4), textcoords="offset points") ax.plot([x3, x3], [y3, -y3], "C2:", lw=0.9); ax.set_title("Tangent: $2P$") fig.suptitle("Group law on $y^2 = x^3 - 3x + 3$ over $\\mathbb{R}$ (illustrative)", fontsize=9) fig.tight_layout() out = ROOT / "figures/ec_geometry.pdf"; out.parent.mkdir(exist_ok=True); fig.savefig(out); fig.savefig(ROOT / "paper/figures/ec_geometry.pdf") print(out)