116 lines
3.8 KiB
Python
116 lines
3.8 KiB
Python
from util import Object
|
|
from elliptic_curve import *
|
|
import elliptic_curve_display
|
|
|
|
import tkinter as tk
|
|
from tkinter import ttk
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib.backend_bases import key_press_handler
|
|
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,
|
|
NavigationToolbar2Tk)
|
|
|
|
state = None
|
|
|
|
def display():
|
|
elliptic_curve_display.clear()
|
|
elliptic_curve_display.display(state.ax, state.curve)
|
|
ps = state.curve.points()
|
|
elliptic_curve_display.addition(state.ax, state.curve, ps[0][3], ps[1][3], ps[0][6], ps[1][6])
|
|
elliptic_curve_display.double(state.ax, state.curve, ps[0][6], ps[1][6])
|
|
state.canvas.draw()
|
|
|
|
def update_curve(curve=None):
|
|
global state
|
|
a = int(state.a_input.get())
|
|
b = int(state.b_input.get())
|
|
mod = int(state.mod_input.get())
|
|
state.curve = elliptic_curve_factory(state.is_finite, a, b, mod, curve)
|
|
state.a_strvar.set(state.curve.a)
|
|
state.b_strvar.set(state.curve.b)
|
|
try:
|
|
state.b_strvar.set(state.curve.mod)
|
|
except:
|
|
pass
|
|
|
|
def rerender(curve=None):
|
|
if curve != None:
|
|
update_curve(curve)
|
|
else:
|
|
update_curve()
|
|
display()
|
|
|
|
def init(curve):
|
|
global state
|
|
state = Object()
|
|
state.points = list()
|
|
|
|
tk_init()
|
|
state.curve = elliptic_curve_factory(state.is_finite, *DEFAULT_CURVES['Default'])
|
|
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=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()
|
|
state.a_strvar = tk.StringVar(value=str(0))
|
|
state.b_strvar = tk.StringVar(value=str(0))
|
|
state.mod_strvar = tk.StringVar(value=str(0))
|
|
state.is_finite = tk.IntVar(value=0)
|
|
|
|
def tk_fill():
|
|
global state
|
|
# Finite field view toggle
|
|
tk.Checkbutton(state.controls, text="Finite field view",
|
|
variable=state.is_finite, command=lambda: rerender(state.curve),
|
|
).pack()
|
|
# 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")),
|
|
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()
|
|
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"),
|
|
("modulos", "magenta", state.mod_strvar.get(), "mod_input"),
|
|
]
|
|
(f := ttk.Frame(state.controls)).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)
|
|
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
|
|
for name, equation in DEFAULT_CURVES.items():
|
|
ttk.Button(state.controls, text=name, command=lambda: rerender(equation)).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)
|