Generating diagrams for ECDH slides¶
This is done using sagemath version
In [1]:
version()
Out[1]:
'SageMath version 10.2, Release Date: 2023-12-03'
Playing with curve from chapter 12.
\begin{equation} y^2 = x^3 - 4x + 0 \pmod{191} \end{equation}
In [2]:
p = 191
FF = GF(p)
A = -4 % p
B = 0
EC=EllipticCurve(FF , [A, B])
Simple plot. Same as in book (but with default colors)
In [3]:
plt = plot(EC)
This will mess with make, as changes to this file might not update the generated PDFs. But it is better than regenerating PDFs unnecessarily any some I tinker with things here.
In [4]:
save_pdfs = False
# save_pdfs = True # uncomment to save PDFS
def mysave(p, file_name):
if save_pdfs:
p.save(file_name)
In [5]:
def ec_coord(P):
"""Coordinates of point as integer list.
In which I try to learn to live with Duck typing.
"""
if P.is_zero():
raise ValueError("P should not be point at infinity")
try:
pxy =P.xy()
except AttributeError:
raise TypeError("P doesn't have xy coordinates")
pxy = list(pxy)
if not all(z == int(z) for z in pxy):
raise TypeError("coordinates must be integral")
return [int(x) for x in list(pxy)]
In [6]:
try:
ec_coord(5)
except TypeError:
print("Correctly got a type error")
Correctly got a type error
Now try to highlight generator
In [7]:
g = EC.gens()[0]
print(f'generator is at {g.xy()}')
generator is at (146, 131)
In [8]:
gen_plot = point(ec_coord(g), rgbcolor=(0, 0.6, 0), size=30)
plt += gen_plot
plt.show()
mysave(plt, "E191.pdf")
In [9]:
from sage.plot.graphics import is_Graphics
def plot_nG(base_plot, n, g):
"""plot path from generator g to n*G."""
if n != int(n):
raise TypeError("n must be integral")
n %= g.order()
if not is_Graphics(base_plot):
raise TypeError("The plot thins")
arrow_head_size = 2
intermediate_color = Color('gray')
final_color = Color('black')
final_arrow_width = 0.4
intermediate_arrow_width = 0.2
emph_pt_size = 40
gen_color = Color("darkgreen")
plt = base_plot
for i in range(2, n):
plt += arrow(ec_coord((i - 1)* g), ec_coord(i * g),
rgbcolor=intermediate_color,
arrowsize=arrow_head_size,
width = intermediate_arrow_width)
nG = n * g
plt += arrow(ec_coord((n - 1) * g), ec_coord(nG),
rgbcolor=final_color,
arrowsize=arrow_head_size,
width = final_arrow_width)
# emphasize point nG
plt += point(ec_coord(nG),
rgbcolor=final_color, size=emph_pt_size)
# generator
plt += point(ec_coord(g),
rgbcolor=gen_color, size=emph_pt_size)
plt.axes(False)
return plt
In [10]:
tmp_plot = plot_nG(plt, 2, g)
tmp_plot.show()
mysave(tmp_plot, "2Gpath.pdf")
In [11]:
tmp_plot = plot_nG(plt, 3, g)
tmp_plot.show()
mysave(tmp_plot, "3Gpath.pdf")
In [12]:
tmp_plot = plot_nG(plt, 7, g)
tmp_plot.show()
mysave(tmp_plot, "7Gpath.pdf")
In [13]:
print(f"|G| is {g.order()}")
print(f"(|G| - 1)G is {((g.order() - 1) * g).xy()}")
tmp_plot = plot_nG(plt, g.order() - 1, g)
tmp_plot.show()
mysave(tmp_plot, "95Gpath.pdf")
|G| is 96 (|G| - 1)G is (146, 60)