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")
No description has been provided for this image
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")
No description has been provided for this image
In [11]:
tmp_plot = plot_nG(plt, 3, g)
tmp_plot.show()
mysave(tmp_plot, "3Gpath.pdf")
No description has been provided for this image
In [12]:
tmp_plot = plot_nG(plt, 7, g)
tmp_plot.show()
mysave(tmp_plot, "7Gpath.pdf")
No description has been provided for this image
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)
No description has been provided for this image