In short, Im trying to add two points on an elliptic curve y^2 = x^3 + ax + b over a finite field Fp. I already have a working implementation over R, but do not know how to alter the general formulas Ive found in order for them to sustain addition over Fp.
When P does not equal Q, and Z is the sum of P and Q:
dydx = (Q.y - P.y)/(Q.x - P.x)
Z.x = dydx**2 - P.x - Q.x
Z.y = dydx * (Z.x - P.x) + P.y
When P equals Q, again with Z as the sum:
dydx = (3 * (P.x)**2 + self.a)/(2 * P.y)
Z.x = dydx**2 - 2 * P.x
Z.y = dydx * (Z.x - P.x) + P.y
These are the same formules as found here. What needs to be modified?
Clarification: The code above works for elliptic curves over R. I am looking to find what needs to be changed for it to work for addition of points over a finite field of order p.
There are a couple of issues here. First is that you have the wrong formulas: those are the formulas for the negation of the sum, or equivalently the third point of the curve that lies on the line through P and Q. Compare with the formula you linked to on Wikipedia, and you'll see that what you have for
Z.y
is the negation of the value they have.A second issue is that your formulas don't take the origin into account: if P is the inverse of Q in the group law, then P + Q will be the origin, which doesn't lie on the affine part of the curve and so can't be described as a pair of
(x, y)
coordinates. So you'll need some way to specify the origin.Let's write some code. First we need a representation for the points on the curve. We use the string
'Origin'
to represent the origin, and a simple named tuple for the points on the affine part of the elliptic curve.For demonstration purposes, we choose a particular elliptic curve and prime. The prime should be greater than
3
for the addition formulas to be valid. We also write a function that we can use to check that a particular point is a valid representation of a point on the curve. This will be useful in checking that we didn't make any mistakes in implementing the addition formulas.To do divisions modulo
p
you'll need some way to compute inverses modulop
. A simple and reasonably efficient trick here is to use Python's three-argument variant of thepow
function: by Fermat's Little Theorem,pow(a, p-2, p)
will give an inverse ofa
modulop
(provided of course that that inverse exists - that is, thata
is not divisible byp
).And finally, here are the two functions to compute negation and addition on the elliptic curve. The addition function is based directly on the formulas you gave (after correcting the sign of
Z.y
), makes use ofinv_mod_p
to perform the divisions modulop
, and does a final reduction modulop
for the computedx
andy
coordinates.We can check the code above by creating a handful of points on the curve and checking that they obey the expected arithmetic laws.