diff --git a/elliptic_curve.py b/elliptic_curve.py index 992be61..f6d822f 100644 --- a/elliptic_curve.py +++ b/elliptic_curve.py @@ -4,21 +4,20 @@ import numpy as np CURVE_LINSPACE = np.linspace(-10, 30, num=1000) -DEFAULT_CURVE = (1, 3, 3) -NSA_CURVE = (1, 3, 0) -BTC_CURVE = (1, 0, 7) +DEFAULT_CURVE = (3, 3) +NSA_CURVE = (3, 0) +BTC_CURVE = (0, 7) class EllipticCurve(Object): - def __init__(self, a, b, c): + def __init__(self, a, b): self.a = a self.b = b - self.c = b self.xl = CURVE_LINSPACE self.yl = self._x2y() def _x2y(self): r = np.empty((self.xl.size, 2)) for i, xi in enumerate(self.xl): - r[i][0] = np.sqrt((self.a * xi**3) + (self.b * xi**2) + self.c) + r[i][0] = np.sqrt((xi**3) + (self.a * xi**2) + self.b) for i in range(self.xl.size): r[i][1] = -r[i][0] return r diff --git a/main.py b/main.py index f2b07a2..363c42b 100755 --- a/main.py +++ b/main.py @@ -1,14 +1,13 @@ #!/bin/python3 from util import Object +import elliptic_curve import state import tkinter as tk -def init(): - state.init() - def main(): - init() + state.init(elliptic_curve.DEFAULT_CURVE) + state.display() tk.mainloop() if __name__ == '__main__': diff --git a/state.py b/state.py index 732642d..7c5e3df 100644 --- a/state.py +++ b/state.py @@ -10,56 +10,52 @@ from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, state = None + def clear(): + global state for i in state.plot: i.remove() -def display(curve=None): - global state - if curve != None: - a, b, c = curve - else: - a = int(state.a_input.get()) - b = int(state.b_input.get()) - c = int(state.c_input.get()) +def display(): clear() - state.curve = EllipticCurve(a, b, c) - state.curve_equation_a.config(text=str(a)) - state.curve_equation_b.config(text=str(b)) - state.curve_equation_c.config(text=str(c)) state.plot = state.ax.plot(state.curve.xl, state.curve.yl) state.canvas.draw() +def update_curve(curve=None): + global state + if curve != None: + a, b = curve + else: + a = int(state.a_input.get()) + b = int(state.b_input.get()) + state.a_strvar.set(a) + state.b_strvar.set(b) + state.curve = EllipticCurve(a, b) -def init(): +def rerender(curve=None): + if curve != None: + update_curve(curve) + else: + update_curve() + display() + +def init(curve): global state state = Object() - state.curve = EllipticCurve(*DEFAULT_CURVE) state.plot = tuple() - # Tk init + + tk_init() + update_curve(DEFAULT_CURVE) + tk_fill() + +def tk_init(): state.root = root = tk.Tk() root.wm_title("Eliptic curves") root.attributes('-zoomed', True) + state.figure = plt.figure(figsize=(5, 4), dpi=100) + state.canvas = FigureCanvasTkAgg(state.figure, master=root) state.controls = ttk.Frame(root) - state.curve_equation = ttk.Frame(state.controls) - re = [ - ttk.Label(state.curve_equation, text="y² = "), - (curve_equation_a := ttk.Label(state.curve_equation, text="a", foreground="blue")), - ttk.Label(state.curve_equation, text="x³ + "), - (curve_equation_b := ttk.Label(state.curve_equation, text="b", foreground="green")), - ttk.Label(state.curve_equation, text="x² + "), - (curve_equation_c := ttk.Label(state.curve_equation, text="c", foreground="red")), - ] - state.curve_equation_a, state.curve_equation_b, state.curve_equation_c = curve_equation_a, curve_equation_b, curve_equation_c - # Matplotlib init - state.ax = ax = state.figure.add_subplot() - ax.grid() - ax.axhline(0, color='black', linewidth=1.5) - ax.axvline(0, color='black', linewidth=1.5) - # Tk/Mpl wiring - state.canvas = FigureCanvasTkAgg(state.figure, master=root) # A tk.DrawingArea. - state.canvas.draw() state.toolbar = NavigationToolbar2Tk(state.canvas, root, pack_toolbar=False) state.toolbar.update() # XXX TEST REMOVE ?!?! @@ -67,28 +63,55 @@ def init(): "key_press_event", lambda event: print(f"you pressed {event.key}") ) state.canvas.mpl_connect("key_press_event", key_press_handler) - # Packing - state.controls.pack(side=tk.RIGHT) + state.a_strvar = tk.StringVar() + state.b_strvar = tk.StringVar() + state.c_strvar = tk.StringVar() + +def tk_fill(): + global state + # Equation -- y^2 = x^3 + a * x^2 + b + state.curve_equation = ttk.Frame(state.controls) + equation = [ + ttk.Label(state.curve_equation, text="y² = x³ + "), + (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")), + ] + state.curve_equation_a, state.curve_equation_b = curve_equation_a, curve_equation_b state.curve_equation.pack() - for i, ix in enumerate(re): + for i, ix in enumerate(equation): ix.grid(row=0, column=i) + + # Input --- a b + entry_keys = ("name", "color", "value_var", "label_name") + entry_values = [ + ("a", "blue", state.a_strvar.get(), "a_input"), + ("b", "red", state.b_strvar.get(), "b_input"), + ] f = ttk.Frame(state.controls) f.pack() - b = [ - ("a", "blue", state.curve.a, "a_input"), - ("b", "green", state.curve.b, "b_input"), - ("c", "red", state.curve.c, "c_input"), - ] - for i, d in enumerate(b): - ttk.Label(f, text=d[0], foreground=d[1]).grid(row=i, column=0) - e = state[d[3]] = ttk.Entry(f) - e.insert(tk.END, str(d[2])) - e.bind('', lambda event: display()) + 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('', lambda event: rerender()) e.grid(row=i, column=1) - ttk.Button(state.controls, text="secp384r1 (NSA backdoor)", command=lambda: display(NSA_CURVE)).pack() - ttk.Button(state.controls, text="secp256k (BTC)", command=lambda: display(BTC_CURVE)).pack() - ttk.Button(state.controls, text="ree", command=lambda: display((1, 4, 0))).pack() + # XXX TEST ?!?!? + scale = tk.Scale(state.controls, from_=0, to=100, orient=tk.HORIZONTAL, length=200) + scale.pack() + + # Preset buttons + ttk.Button(state.controls, text="Default", command=lambda: rerender(DEFAULT_CURVE)).pack() + ttk.Button(state.controls, text="secp384r1 (NSA backdoor)", command=lambda: rerender(NSA_CURVE)).pack() + ttk.Button(state.controls, text="secp256k (BTC)", command=lambda: rerender(BTC_CURVE)).pack() + + # Matplotlib init + state.ax = ax = state.figure.add_subplot() + ax.grid() + ax.axhline(0, color='black', linewidth=1.5) + ax.axvline(0, color='black', linewidth=1.5) + + # Extra Packing + state.controls.pack(side=tk.RIGHT) state.toolbar.pack(side=tk.BOTTOM, fill=tk.X) state.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True) - # --- - display()