# Elliptic curves

Elliptic curves constructed over finite fields are another important cryptographic tool.

We use elliptic curves because they provide a cryptographic group, i.e. a group in which the discrete logarithm problem (discussed below) is hard.

There are several ways to define the curve equation, but for our purposes, let $F_{p}$ be a large (255-bit) field, and then let the set of solutions $(x,y)$ to $y_{2}=x_{3}+b$ for some constant $b$ define the $F_{p}$-rational points on an elliptic curve $E(F_{p})$. These $(x,y)$ coordinates are called "affine coordinates". Each of the $F_{p}$-rational points, together with a "point at infinity" $O$ that serves as the group identity, can be interpreted as an element of a group. By convention, elliptic curve groups are written additively.

*"Three points on a line sum to zero, which is the point at infinity."*

The group addition law is simple: to add two points together, find the line that intersects both points and obtain the third point, and then negate its $y$-coordinate. The case that a point is being added to itself, called point doubling, requires special handling: we find the line tangent to the point, and then find the single other point that intersects this line and then negate. Otherwise, in the event that a point is being "added" to its negation, the result is the point at infinity.

The ability to add and double points naturally gives us a way to scale them by integers,
called *scalars*. The number of points on the curve is the group order. If this number
is a prime $q$, then the scalars can be considered as elements of a *scalar field*,
$F_{q}$.

Elliptic curves, when properly designed, have an important security property. Given two random elements $G,H∈E(F_{p})$ finding $a$ such that $[a]G=H$, otherwise known as the discrete log of $H$ with respect to $G$, is considered computationally infeasible with classical computers. This is called the elliptic curve discrete log assumption.

If an elliptic curve group $G$ has prime order $q$ (like the ones used in Halo 2), then it is a finite cyclic group. Recall from the section on groups that this implies it is isomorphic to $Z/qZ$, or equivalently, to the scalar field $F_{q}$. Each possible generator $G$ fixes the isomorphism; then an element on the scalar side is precisely the discrete log of the corresponding group element with respect to $G$. In the case of a cryptographically secure elliptic curve, the isomorphism is hard to compute in the $G→F_{q}$ direction because the elliptic curve discrete log problem is hard.

It is sometimes helpful to make use of this isomorphism by thinking of group-based cryptographic protocols and algorithms in terms of the scalars instead of in terms of the group elements. This can make proofs and notation simpler.

For instance, it has become common in papers on proof systems to use the notation $[x]$ to denote a group element with discrete log $x$, where the generator is implicit.

We also used this idea in the "distinct-x theorem", in order to prove correctness of optimizations for elliptic curve scalar multiplication in Sapling, and an endomorphism-based optimization in Appendix C of the original Halo paper.

## Curve arithmetic

### Point doubling

The simplest situation is doubling a point $(x_{0},y_{0})$. Continuing with our example $y_{2}=x_{3}+b$, this is done first by computing the derivative $λ=dxdy =2y3x_{2} .$

To obtain expressions for $(x_{1},y_{1})=(x_{0},y_{0})+(x_{0},y_{0}),$ we consider

$x_{1}−x_{0}−y_{1}−y_{0} =λ ⟹−y_{1}=λ(x_{1}−x_{0})+y_{0}⟹y_{1}=λ(x_{0}−x_{1})−y_{0} . $

To get the expression for $x_{1},$ we substitute $y=λ(x_{0}−x)−y_{0}$ into the elliptic curve equation:

$y_{2}=x_{3}+b ⟹(λ(x_{0}−x)−y_{0})_{2}=x_{3}+b⟹x_{3}−λ_{2}x_{2}+⋯=0←(rearranging terms)=(x−x_{0})(x−x_{0})(x−x_{1})←(known rootsx_{0},x_{0},x_{1})=x_{3}−(x_{0}+x_{0}+x_{1})x_{2}+⋯. $

Comparing coefficients for the $x_{2}$ term gives us $λ_{2}=x_{0}+x_{0}+x_{1}⟹x_{1}=λ_{2}−2x_{0} .$

### Projective coordinates

This unfortunately requires an expensive inversion of $2y$. We can avoid this by arranging our equations to "defer" the computation of the inverse, since we often do not need the actual affine $(x_{′},y_{′})$ coordinate of the resulting point immediately after an individual curve operation. Let's introduce a third coordinate $Z$ and scale our curve equation by $Z_{3}$ like so:

$Z_{3}y_{2}=Z_{3}x_{3}+Z_{3}b$

Our original curve is just this curve at the restriction $Z=1$. If we allow the affine point $(x,y)$ to be represented by $X=xZ$, $Y=yZ$ and $Z=0$ then we have the homogenous projective curve

$Y_{2}Z=X_{3}+Z_{3}b.$

Obtaining $(x,y)$ from $(X,Y,Z)$ is as simple as computing $(X/Z,Y/Z)$ when $Z=0$. (When $Z=0,$ we are dealing with the point at infinity $O:=(0:1:0)$.) In this form, we now have a convenient way to defer the inversion required by doubling a point. The general strategy is to express $x_{′},y_{′}$ as rational functions using $x=X/Z$ and $y=Y/Z$, rearrange to make their denominators the same, and then take the resulting point $(X,Y,Z)$ to have $Z$ be the shared denominator and $X=x_{′}Z,Y=y_{′}Z$.

Projective coordinates are often, but not always, more efficient than affine coordinates. There may be exceptions to this when either we have a different way to apply Montgomery's trick, or when we're in the circuit setting where multiplications and inversions are about equally as expensive (at least in terms of circuit size).

The following shows an example of doubling a point $(X,Y,Z)=(xZ,yZ,Z)$ without an inversion. Substituting with $X,Y,Z$ gives us $λ=2y3x_{2} =2(Y/Z)3(X/Z)_{2} =2YZ3X_{2} $

and gives us $x_{′}y_{′} =λ_{2}−2x=λ_{2}−Z2X =4Y_{2}Z_{2}9X_{4} −Z2X =4Y_{2}Z_{2}9X_{4}−8XY_{2}Z =8Y_{3}Z_{3}18X_{4}YZ−16XY_{3}Z_{2} =λ(x−x_{′})−y=λ(ZX −4Y_{2}Z_{2}9X_{4}−8XY_{2}Z )−ZY =2YZ3X_{2} (ZX −4Y_{2}Z_{2}9X_{4}−8XY_{2}Z )−ZY =2YZ_{2}3X_{3} −8Y_{3}Z_{3}27X_{6}−24X_{3}Y_{2}Z −ZY =8Y_{3}Z_{3}12X_{3}Y_{2}Z−8Y_{4}Z_{2}−27X_{6}+24X_{3}Y_{2}Z $

Notice how the denominators of $x_{′}$ and $y_{′}$ are the same. Thus, instead of computing $(x_{′},y_{′})$ we can compute $(X,Y,Z)$ with $Z=8Y_{3}Z_{3}$ and $X,Y$ set to the corresponding numerators such that $X/Z=x_{′}$ and $Y/Z=y_{′}$. This completely avoids the need to perform an inversion when doubling, and something analogous to this can be done when adding two distinct points.

### Point addition

We now add two points with distinct $x$-coordinates, $P=(x_{0},y_{0})$ and $Q=(x_{1},y_{1}),$ where $x_{0}=x_{1},$ to obtain $R=P+Q=(x_{2},y_{2}).$ The line $PQ $ has slope $λ=fracy_{1}−y_{0}x_{1}−x_{0}⟹y−y_{0}=λ⋅(x−x_{0}).$

Using the expression for $PQ $, we compute $y$-coordinate $−y_{2}$ of $−R$ as: $−y_{2}−y_{0}=λ⋅(x_{2}−x_{0})⟹y_{2}=(x_{0}−x_{2})−y_{0} .$

Plugging the expression for $PQ $ into the curve equation $y_{2}=x_{3}+b$ yields $y_{2}=x_{3}+b ⟹(λ⋅(x−x_{0})+y_{0})_{2}=x_{3}+b⟹x_{3}−λ_{2}x_{2}+⋯=0←(rearranging terms)=(x−x_{0})(x−x_{1})(x−x_{2})←(known rootsx_{0},x_{1},x_{2})=x_{3}−(x_{0}+x_{1}+x_{2})x_{2}+⋯. $

Comparing coefficients for the $x_{2}$ term gives us $λ_{2}=x_{0}+x_{1}+x_{2}⟹x_{2}=λ_{2}−x_{0}−x_{1} $.

Important notes:

- There exist efficient formulae
^{1}for point addition that do not have edge cases (so-called "complete" formulae) and that unify the addition and doubling cases together. The result of adding a point to its negation using those formulae produces $Z=0$, which represents the point at infinity. - In addition, there are other models like the Jacobian representation where $(x,y)=(xZ_{2},yZ_{3},Z)$ where the curve is rescaled by $Z_{6}$ instead of $Z_{3}$, and this representation has even more efficient arithmetic but no unified/complete formulae.
- We can easily compare two curve points $(X_{1},Y_{1},Z_{1})$ and $(X_{2},Y_{2},Z_{2})$ for equality in the homogenous projective coordinate space by "homogenizing" their Z-coordinates; the checks become $X_{1}Z_{2}=X_{2}Z_{1}$ and $Y_{1}Z_{2}=Y_{2}Z_{1}$.

## Curve endomorphisms

Imagine that $F_{p}$ has a primitive cube root of unity, or in other words that $3∣p−1$ and so an element $ζ_{p}$ generates a $3$-order multiplicative subgroup. Notice that a point $(x,y)$ on our example elliptic curve $y_{2}=x_{3}+b$ has two cousin points: $(ζ_{p}x,ζ_{p}x)$, because the computation $x_{3}$ effectively kills the $ζ$ component of the $x$-coordinate. Applying the map $(x,y)↦(ζ_{p}x,y)$ is an application of an endomorphism over the curve. The exact mechanics involved are complicated, but when the curve has a prime $q$ number of points (and thus a prime "order") the effect of the endomorphism is to multiply the point by a scalar in $F_{q}$ which is also a primitive cube root $ζ_{q}$ in the scalar field.

## Curve point compression

Given a point on the curve $P=(x,y)$, we know that its negation $−P=(x,−y)$ is also on the curve. To uniquely specify a point, we need only encode its $x$-coordinate along with the sign of its $y$-coordinate.

### Serialization

As mentioned in the Fields section, we can interpret the least significant
bit of a field element as its "sign", since its additive inverse will always have the
opposite LSB. So we record the LSB of the $y$-coordinate as `sign`

.

Pallas and Vesta are defined over the $F_{p}$ and $F_{q}$ fields, which
elements can be expressed in $255$ bits. This conveniently leaves one unused bit in a
32-byte representation. We pack the $y$-coordinate `sign`

bit into the highest bit in
the representation of the $x$-coordinate:

```
<----------------------------------- x --------------------------------->
Enc(P) = [_ _ _ _ _ _ _ _] [_ _ _ _ _ _ _ _] ... [_ _ _ _ _ _ _ _] [_ _ _ _ _ _ _ sign]
^ <-------------------------------------> ^
LSB 30 bytes MSB
```

The "point at infinity" $O$ that serves as the group identity, does not have an affine $(x,y)$ representation. However, it turns out that there are no points on either the Pallas or Vesta curve with $x=0$ or $y=0$. We therefore use the "fake" affine coordinates $(0,0)$ to encode $O$, which results in the all-zeroes 32-byte array.

### Deserialization

When deserializing a compressed curve point, we first read the most significant bit as
`ysign`

, the sign of the $y$-coordinate. Then, we set this bit to zero to recover the
original $x$-coordinate.

If $x=0,y=0,$ we return the "point at infinity" $O$. Otherwise, we proceed
to compute $y=x_{3}+b .$ Here, we read the least significant bit of $y$ as `sign`

.
If `sign == ysign`

, we already have the correct sign and simply return the curve point
$(x,y)$. Otherwise, we negate $y$ and return $(x,−y)$.

## Cycles of curves

Let $E_{p}$ be an elliptic curve over a finite field $F_{p},$ where $p$ is a prime. We denote this by $E_{p}/F_{p}.$ and we denote the group of points of $E_{p}$ over $F_{p},$ with order $q=#E(F_{p}).$ For this curve, we call $F_{p}$ the "base field" and $F_{q}$ the "scalar field".

We instantiate our proof system over the elliptic curve $E_{p}/F_{p}$. This allows us to prove statements about $F_{q}$-arithmetic circuit satisfiability.

(aside) If our curve $E_{p}$ is over $F_{p},$ why is the arithmetic circuit instead in $F_{q}$?The proof system is basically working on encodings of the scalars in the circuit (or more precisely, commitments to polynomials whose coefficients are scalars). The scalars are in $F_{q}$ when their encodings/commitments are elliptic curve points in $E_{p}/F_{p}$.

However, most of the verifier's arithmetic computations are over the base field $F_{p},$ and are thus efficiently expressed as an $F_{p}$-arithmetic circuit.

(aside) Why are the verifier's computations (mainly) over $F_{p}$?The Halo 2 verifier actually has to perform group operations using information output by the circuit. Group operations like point doubling and addition use arithmetic in $F_{p}$, because the coordinates of points are in $F_{p}.$

This motivates us to construct another curve with scalar field $F_{p}$, which has an $F_{p}$-arithmetic circuit that can efficiently verify proofs from the first curve. As a bonus, if this second curve had base field $E_{q}/F_{q},$ it would generate proofs that could be efficiently verified in the first curve's $F_{q}$-arithmetic circuit. In other words, we instantiate a second proof system over $E_{q}/F_{q},$ forming a 2-cycle with the first:

### TODO: Pallas-Vesta curves

Reference: https://github.com/zcash/pasta

## Hashing to curves

Sometimes it is useful to be able to produce a random point on an elliptic curve $E_{p}/F_{p}$ corresponding to some input, in such a way that no-one will know its discrete logarithm (to any other base).

This is described in detail in the Internet draft on Hashing to Elliptic Curves. Several algorithms can be used depending on efficiency and security requirements. The framework used in the Internet Draft makes use of several functions:

`hash_to_field`

: takes a byte sequence input and maps it to a element in the base field $F_{p}$`map_to_curve`

: takes an $F_{p}$ element and maps it to $E_{p}$.

### TODO: Simplified SWU

Reference: https://eprint.iacr.org/2019/403.pdf