Affine Addition
One of the key properties of an elliptic curve is that it is possible to define a group law on the set of its points such that the point at infinity serves as the neutral element, and inverses are reflections on the x-axis. The origin of this law can be understood in a geometric picture and is known as the chord-and-tangent rule.

Algebraic definition of the chord-and-tangent rule:
The point at infinity is the neutral element.
The inverse of is . For any other curve point , the inverse is given by . If P is a point on a Short Weierstrass curve with P = (x, 0) then P is called self-inverse.
For any two curve points , the group law is defined by one of the following cases:
(Neutral element) If , then the group law is defined as
(Inverse elements) If and , the group law is defined as .
(Tangent Rule) If with , the group law is defined as follows:
(Chord Rule) If and such that , the group law with is defined as follows:
It is very efficient to compute inverses on elliptic curves. However, computing the addition of elliptic curve points in the affine representation needs to consider many cases, and involves extensive finite field divisions. For point addition, we would need 1 division, 2 multiplications, 1 squaring, and 6 additions on finite fields.
In finite field, computing division is expensive and requires Extended Euclidean Theorem. Computing the division consumes ~ (e.g., 254) operations, which are several orders of magnitudes larger than remaining computations (e.g., multiplications and additions).
Sage example:
# Tiny JubJub
F13 = GF(13)
a = F13(8)
b = F13(8)
TJJ = EllipticCurve(F13,[a,b])
def add(p, q):
# we assume that (0, 1) is a neutral element
O = (0, 1)
if p == O:
return q
if q == O:
return p
if p[0] == q[0] and p[1] == -q[1]:
return O
if p == q:
k = (3 * p[0]**2 + a) / (2*p[1])
x = k**2 - 2 * p[0]
y = k * (p[0] - x) - p[1]
return (x, y)
k = (q[1] - p[1]) / (q[0] - p[0])
x = k ** 2 - p[0] - q[0]
y = k * (p[0] - x) - p[1]
return (x, y)
def to_affine(p):
if p == TJJ(0):
return (0, 1)
return p.xy()
p = TJJ.random_element()
q = TJJ.random_element()
print(to_affine(p + q))
print(add(to_affine(p), to_affine(q)))
Last updated