diff --git a/.gitignore b/.gitignore index c18dd8d..92afa22 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ __pycache__/ +venv/ diff --git a/elliptic_curve.py b/elliptic_curve.py index f6d822f..66df766 100644 --- a/elliptic_curve.py +++ b/elliptic_curve.py @@ -2,16 +2,17 @@ from util import Object import numpy as np -CURVE_LINSPACE = np.linspace(-10, 30, num=1000) +CURVE_LINSPACE = np.linspace(-10, 10, num=2000) -DEFAULT_CURVE = (3, 3) -NSA_CURVE = (3, 0) -BTC_CURVE = (0, 7) +DEFAULT_CURVE = (3, 3, 11) +NSA_CURVE = (3, 0, 2**384 - 2**128 - 2**96 + 2**32 - 1) +BTC_CURVE = (0, 7, 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1) class EllipticCurve(Object): - def __init__(self, a, b): + def __init__(self, a, b, mod): self.a = a self.b = b + self.mod = mod self.xl = CURVE_LINSPACE self.yl = self._x2y() def _x2y(self): @@ -21,3 +22,7 @@ class EllipticCurve(Object): for i in range(self.xl.size): r[i][1] = -r[i][0] return r + def yfromx(self, x, is_top = True): + r = np.sqrt((x**3) + (self.a * x**2) + self.b) + r = +r if is_top else -r + return r diff --git a/main.py b/main.py index 363c42b..cbd7ab2 100755 --- a/main.py +++ b/main.py @@ -7,6 +7,8 @@ import tkinter as tk def main(): state.init(elliptic_curve.DEFAULT_CURVE) + state.update_points(-1) + state.update_points(-2.7, False) state.display() tk.mainloop() diff --git a/state.py b/state.py index 7c5e3df..e97b564 100644 --- a/state.py +++ b/state.py @@ -19,18 +19,35 @@ def clear(): def display(): clear() state.plot = state.ax.plot(state.curve.xl, state.curve.yl) + state.ax.scatter( + [i[0] for i in state.points], + [i[1] for i in state.points], + color='red', s=20, marker='o' + ) + state.ax.axline( + (state.points[0][0], state.points[0][1]), + (state.points[1][0], state.points[1][1]), + linestyle='--' + ) state.canvas.draw() def update_curve(curve=None): global state if curve != None: - a, b = curve + a, b, mod = curve else: a = int(state.a_input.get()) b = int(state.b_input.get()) + mod = int(state.mod_input.get()) state.a_strvar.set(a) state.b_strvar.set(b) - state.curve = EllipticCurve(a, b) + state.mod_strvar.set(mod) + state.curve = EllipticCurve(a, b, mod) + +def update_points(x, is_top = True): + y = state.curve.yfromx(x, is_top) + if y == y: # False if NaN + state.points.append((x, y)) def rerender(curve=None): if curve != None: @@ -43,6 +60,7 @@ def init(curve): global state state = Object() state.plot = tuple() + state.points = list() tk_init() update_curve(DEFAULT_CURVE) @@ -53,19 +71,14 @@ def tk_init(): root.wm_title("Eliptic curves") root.attributes('-zoomed', True) - state.figure = plt.figure(figsize=(5, 4), dpi=100) + state.figure = plt.figure(figsize=(5, 4), dpi=150) state.canvas = FigureCanvasTkAgg(state.figure, master=root) state.controls = ttk.Frame(root) state.toolbar = NavigationToolbar2Tk(state.canvas, root, pack_toolbar=False) state.toolbar.update() - # XXX TEST REMOVE ?!?! - state.canvas.mpl_connect( - "key_press_event", lambda event: print(f"you pressed {event.key}") - ) - state.canvas.mpl_connect("key_press_event", key_press_handler) - state.a_strvar = tk.StringVar() - state.b_strvar = tk.StringVar() - state.c_strvar = tk.StringVar() + state.a_strvar = tk.StringVar() + state.b_strvar = tk.StringVar() + state.mod_strvar = tk.StringVar() def tk_fill(): global state @@ -76,6 +89,8 @@ def tk_fill(): (curve_equation_a := ttk.Label(state.curve_equation, textvariable=state.a_strvar, foreground="blue")), ttk.Label(state.curve_equation, text="x² + "), (curve_equation_b := ttk.Label(state.curve_equation, textvariable=state.b_strvar, foreground="red")), + ttk.Label(state.curve_equation, text=" mod "), + (curve_equation_mod := ttk.Label(state.curve_equation, textvariable=state.mod_strvar, foreground="magenta")), ] state.curve_equation_a, state.curve_equation_b = curve_equation_a, curve_equation_b state.curve_equation.pack() @@ -87,18 +102,16 @@ def tk_fill(): entry_values = [ ("a", "blue", state.a_strvar.get(), "a_input"), ("b", "red", state.b_strvar.get(), "b_input"), + ("modulos", "magenta", state.mod_strvar.get(), "mod_input"), ] f = ttk.Frame(state.controls) f.pack() for i, d in enumerate([{k:v for k,v in zip(entry_keys, t)} for t in entry_values]): ttk.Label(f, text=d["name"], foreground=d["color"]).grid(row=i, column=0) - e = state[d["label_name"]] = ttk.Entry(f) - e.insert(tk.END, str(d["value_var"])) - e.bind('<FocusOut>', lambda event: rerender()) - e.grid(row=i, column=1) - # XXX TEST ?!?!? - scale = tk.Scale(state.controls, from_=0, to=100, orient=tk.HORIZONTAL, length=200) - scale.pack() + w = state[d["label_name"]] = tk.Scale(f, from_=0, to=100, orient=tk.HORIZONTAL, length=200) + w.set(d["value_var"]) + w.config(command=lambda event: rerender()) + w.grid(row=i, column=1) # Preset buttons ttk.Button(state.controls, text="Default", command=lambda: rerender(DEFAULT_CURVE)).pack()