#!/usr/bin/env python3

import matplotlib.pyplot as plt
from Cryptotools.Groups.elliptic import Elliptic
from Cryptotools.Groups.point import Point

# https://course.ece.cmu.edu/~ece733/lectures/21-intro-ecc.pdf


a = 3
b = 7 
n = 53 # Must be prime number

E = Elliptic(n, a, b)
E.quadraticResidues()
Ep = E.pointsE()
#print(E.getQuadraticResidues())

# Now, we can make the Addition Table
#for p in Ep:
#    for q in Ep:
#        nP = E.add(p, q)
#        print(f"({p.x}, {p.y}), ({q.x}, {q.y}) {nP.x, nP.y}")
#    print()
#
#print()

# In cryptography, where is the public key and where is the private key on the elliptic curve ???
# For the graphic
MAX=n

fig, ax = plt.subplots()
ax.legend(fontsize=14)
ax.grid()

# We generate x for the graphic
x = list()
x = [i for i in range(0, MAX)]

# Drawing the point.
for p in Ep:
    ax.plot(p.x, p.y, 'bo')

# Find the order of the Curve
order = E.findOrder()
cofactor = E.cofactor
print(f"Order: {order}")
print(f"Cofactor: {cofactor}")

# Lets make an example, here, G is the first element of all points (except the point at infinity)
G = Ep[1]

for i in range(1, 15):
    P = E.scalar(G, i)

    plt.plot(P.x, P.y, marker='o', color="red")
    plt.annotate(f'P{i}', (P.x, P.y + 0.5))
    
    # Check if the point exist in the curve
    if E.pointExist(P):
        print(f"The point P ({P.x}, {P.y}) lies on the Curve")
    else:
        print(f"The point P ({P.x}, {P.y}) doesn't lies on the Curve")

plt.show()
