Available About Elliptic Curve Cryptography

Original author: Andrea Corbellini
  • Transfer

Those familiar with public-key cryptography are probably familiar with the acronyms ECC , ECDH, and ECDSA . The first is an abbreviation for Elliptic Curve Cryptography (cryptography on elliptic curves), the rest are the names of the algorithms based on it.

Today, elliptic curve cryptosystems are used in TLS , PGP and SSH , the most important technologies on which the modern web and IT world are based. I'm not talking about Bitcoin and other cryptocurrencies.

Before ECC became popular, almost all public key algorithms were based on RSA, DSA and DH, alternative cryptosystems based on modular arithmetic. RSA and company are still popular, and are often used with ECC. However, despite the fact that the magic underlying RSA and similar algorithms is easy to explain and understandable to many, and rude implementations are written quite simply , the basics of ECC are still a mystery to most people.

In this series of articles, I will introduce you to the basics of the world of cryptography on elliptic curves. My goal is not to create a complete and detailed guide to ECC (the Internet is full of information on this topic), but a simple overview of ECC and an explanation of why it is considered safe. I will not spend time on long mathematical proofs or boring implementation details. I will also provide useful examples with visual interactive tools and scripts .

In particular, I will consider the following topics:

  1. Elliptic curves over real numbers and group law
  2. Elliptic curves over finite fields and the discrete logarithm problem
  3. Key pair generation and two ECC algorithms: ECDH and ECDSA
  4. ECC Hacking Algorithms and Comparison with RSA

To understand the article, you need to know the basics of set theory, geometry and modular arithmetic, understand the principles of symmetric and asymmetric cryptography. Finally, you must clearly understand what the “simple” and “complex” tasks are and their roles in cryptography.

Ready? Let's get started!

Part 1: elliptic curves over real numbers and group law

Elliptical curves

First: what is an elliptic curve? Wolfram MathWorld has an excellent and comprehensive definition . But for us it is enough that an elliptic curve is just a set of points described by the equation :

$ y ^ 2 = x ^ 3 + ax + b $

Where $ 4a ^ 3 + 27b ^ 2 \ ne 0 $, (this is necessary in order to exclude special curves ). The above equation is called the usual Weierstrass formulation for elliptic curves.

Different shapes for different elliptic curves

Different shapes of elliptic curves ($ b = 1 $, $ a $ varies from 2 to -3).

Types of singularities

Types of features: on the left - a curve with a return point (cusp) ($ y ^ 2 = x ^ 3 $) On the right is a self-intersecting curve ($ y ^ 2 = x ^ 3 - 3x + 2 $) Both of these examples are not complete elliptic curves.

Depending on the values$ a $ and $ b $elliptic curves can take on a plane different shapes. As you can easily see and check, the elliptic curves are symmetric about the axis$ X $.

For our purposes, we will also need the infinitely distant point (also known as the ideal point) to be part of the curve . From now on, we will denote an infinitely distant point by the symbol 0 (zero).

If we need to explicitly take into account a point at infinity, then the definition of an elliptic curve can be clarified as follows:

$ \ left \ {(x, y) \ in \ mathbb {R} ^ 2 \ | \ y ^ 2 = x ^ 3 + ax + b, \ 4 a ^ 3 + 27 b ^ 2 \ ne 0 \ right \ } \ \ cup \ \ left \ {0 \ right \} $


In mathematics, a group is a set for which we have defined a binary operation called “addition” and denoted by +. To set$ \ mathbb {G} $ was a group, addition must be defined in such a way that it corresponds to the following four properties:

  1. circuit: if$ a $ and $ b $ are included $ \ mathbb {G} $then $ a + b $ included in $ \ mathbb {G} $;
  2. associativity:$ (a + b) + c = a + (b + c) $;
  3. there is a unit element 0 such that$ a + 0 = 0 + a = a $;
  4. each element has an inverse value , that is: for each$ a $ there is such $ b $, what $ a + b = 0 $.

If we add the fifth requirement:

  1. commutability:$ a + b = b + a $,

then the group is called an abelian group .

In the usual addition, the set of integers$ \ mathbb {Z} $is a group (moreover, it is an Abelian group). Many natural numbers$ \ mathbb {N} $however, it is not a group because it does not satisfy the fourth property.

The groups are convenient in that if we prove compliance with all four properties, we automatically get some other properties “to the load”. For example: a single element is unique ; in addition, the reciprocal values ​​are unique , that is: for each$ a $ there is only one $ b $such that $ a + b = 0 $ (and we can write $ b $ as $ -a $) Directly or indirectly, these and other properties of groups will be very useful to us in the future.

Group law for elliptic curves

We can define a group for elliptic curves. Namely:

  • the elements of the group are points of an elliptic curve;
  • the unit element is the infinitely distant point 0;
  • reciprocal of a point$ P $ Is a point symmetric about the axis $ x $;
  • addition is defined by the following rule: the sum of three nonzero points$ P $, $ Q $ and $ R $lying on one straight line will be equal to $ P + Q + R = 0 $.

Three aligned points

The sum of three points located on one straight line is 0.

It is worth considering that in the last rule we need only three points on one straight line, and the order of these three points is not important. This means that if three points$ P $, $ Q $ and $ R $ lie on one straight line then $ P + (Q + R) = Q + (P + R) = R + (P + Q) = \ cdots = 0 $. Thus, we intuitively proved that our operator + has the properties of associativity and commutativity: we are in an abelian group .

So far, everything is going fine. But how do we calculate the sum of two arbitrary points?

Geometric addition

Due to the fact that we are in the abelian group, we can write $ P + Q + R = 0 $ as $ P + Q = -R $. This equation in this form allows us to derive a geometric way of calculating the sum of two points$ P $ and $ Q $: if we draw a line through$ P $ and $ Q $, this line intersects the third point of the curve $ R $ (this is implied because $ P $, $ Q $ and $ R $are on the same line) . If we take the reciprocal of this point$ -R $we will find the amount $ P + Q $.

Point addition

Draw a straight line through $ P $ and $ Q $. The line crosses the third point$ R $. Symmetric to her point$ -R $ is the result $ P + Q $.

The geometric method works, but needs improvement. In particular, we need to answer several questions:

  • What if $ P = 0 $ or $ Q = 0 $? Of course, we cannot draw a straight line (0 is not on the plane$ xy $) But since we defined 0 as a single element,$ P + 0 = P $ and $ 0 + Q = Q $ for any $ P $ and any $ Q $.
  • What if $ P = -Q $? In this case, the line passing through two points is vertical and does not intersect the third point. But if$ P $ is the inverse of $ Q $then $ P + Q = P + (-P) = 0 $ from the definition of the reciprocal.
  • What if $ P = Q $? In this case, an infinite number of lines passes through a point. Here, things get a little more complicated. But imagine that the point$ Q '\ ne P $. What happens if we force$ Q '$ strive to $ P $getting closer to her?

    The result of P + Q as Q is approaching P

    When two points approach each other, the line passing through them becomes tangent to the curve.

    Because the$ Q '$ committed to $ P $straight through $ P $ and $ Q '$becomes tangent to the curve. In light of this, we can say that$ P + P = -R $where $ R $ Is the point of intersection between the curve and the tangent to the curve at $ P $.
  • What if $ P \ ne Q $but third point $ R $not? In this case, the situation is similar to the previous one. In fact, in this situation, the line passing through$ P $ and $ Q $is tangent to the curve.

    The result of P + Q as Q is approaching P

    If our line intersects only two points, then this means that it is tangent to the curve. It is easy to see how the result of addition becomes symmetric to one of the two points.

    Let's pretend that$ P $is a touch point. In the previous case, we recorded$ P + P = -Q $. This equation now turns into$ P + Q = -P $. On the other hand, if the point of contact were$ Q $then the equation would be correct $ P + Q = -Q $.

The geometric method is now complete and takes into account all cases. Using a pencil and a ruler, we can add all the points of any elliptic curve. If you want to try it, take a look at the HTML5 / JavaScript visual tool I created to calculate the sums of elliptic curves .

Algebraic addition

If we want the computer to deal with the addition of points, we need to turn the geometric method into an algebraic one. Converting the above rules into a set of equations may seem simple, but in fact it is quite tedious, because it requires solving cubic equations. Therefore, I will only present the results.

To get started, let's get rid of the most annoying deadlocks. We already know that$ P + (-P) = 0 $, and we know that $ P + 0 = 0 + P = P $. Therefore, in our equations, we will avoid these two cases and consider only two nonzero asymmetric points$ P = (x_P, y_P) $ and $ Q = (x_Q, y_Q) $.

If$ P $ and $ Q $do not match ($ x_P \ ne x_Q $), then the straight line passing through them has a slope :

$m = \frac{y_P - y_Q}{x_P - x_Q}$

The intersection of this line with the elliptic curve is the third point$R = (x_R, y_R)$:

$\begin{array}{rcl} x_R & = & m^2 - x_P - x_Q \\ y_R & = & y_P + m(x_R - x_P) \end{array}$

or similarly:

$y_R = y_Q + m(x_R - x_Q)$

therefore $(x_P, y_P) + (x_Q, y_Q) = (x_R, -y_R)$ (pay attention to the signs and remember that $P + Q = -R$)

If we needed to verify the correctness of the result, we would have to check whether$R$ curve and whether $P$, $Q$ and $R$on one straight line. The verification of being on one straight line is trivial, and the verification of belonging$R$curve - no, because we have to solve the cubic equation, which is completely sad.

Instead, let's experiment with an example: according to a visual tool , with$P = (1, 2)$ and $Q = (3, 4)$belonging to the curve $y^2 = x^3 - 7x + 10$, their sum is equal $P + Q = -R = (-3, 2)$. Let's check if this matches the equations:

$\begin{array}{rcl} m & = & \frac{y_P - y_Q}{x_P - x_Q} = \frac{2 - 4}{1 - 3} = 1 \\ x_R & = & m^2 - x_P - x_Q = 1^2 - 1 - 3 = -3 \\ y_R & = & y_P + m(x_R - x_P) = 2 + 1 \cdot (-3 - 1) = -2 \\ & = & y_Q + m(x_R - x_Q) = 4 + 1 \cdot (-3 - 3) = -2 \end{array}$

Yes that's right!

Note that these equations work even when the point$P$ or $Q$is a touch point . Let's check on$P = (-1, 4)$ and $Q = (1, 2)$.

$\begin{array}{rcl} m & = & \frac{y_P - y_Q}{x_P - x_Q} = \frac{4 - 2}{-1 - 1} = -1 \\ x_R & = & m^2 - x_P - x_Q = (-1)^2 - (-1) - 1 = 1 \\ y_R & = & y_P + m(x_R - x_P) = 4 + -1 \cdot (1 - (-1)) = 2 \end{array}$

We got the result. $P + Q = (1, -2)$, which matches the result obtained in the visual tool .

To the occasion$P = Q$need to be treated a little differently : equations for$x_R$ and $y_R$ remain the same, but considering that $x_P = x_Q$we will have to use a different equation for tilting :

$m = \frac{3 x_P^2 + a}{2 y_P}$

Note that, as you might expect, this expression is for $m$ is the first derivative:

$y_P = \pm \sqrt{x_P^3 + ax_P + b}$

To prove the correctness of this result, it is enough to verify that $R$ belongs to a curve and that line passing through $P$ and $R$has only two intersections with the curve. But again we will not prove it and instead we will analyze an example:$P = Q = (1, 2)$.

$\begin{array}{rcl} m & = & \frac{3x_P^2 + a}{2 y_P} = \frac{3 \cdot 1^2 - 7}{2 \cdot 2} = -1 \\ x_R & = & m^2 - x_P - x_Q = (-1)^2 - 1 - 1 = -1 \\ y_R & = & y_P + m(x_R - x_P) = 2 + (-1) \cdot (-1 - 1) = 4 \end{array}$

What gives us $P + P = -R = (-1, -4)$. Right!

Although the procedure for obtaining the results is very tedious, our equations are quite brief. All this is thanks to the usual formulation of Weierstrass: without it, these equations would be very long and complicated!

Scalar multiplication

In addition to addition, we can define another operation: scalar multiplication , that is:

$nP = \underbrace{P + P + \cdots + P}_{n\ \text{раз}}$

Where $n$- natural number. I also wrote a visual tool for scalar multiplication, so you can experiment with it.

When writing in this form, it’s obvious that the calculation$nP$ requires $n$additions. If$n$ comprises $k$ decimal places, then the algorithm will have complexity $O(2^k)$which is not very good. But there are faster algorithms.

One of them is the doubling-addition algorithm . The principle of its operation is easier to explain with an example. Take$n = 151$. In binary form, it has the form$10010111_2$. Such a binary form can be represented as the sum of the powers of two:

$\begin{array}{rcl} 151 & = & 1 \cdot 2^7 + 0 \cdot 2^6 + 0 \cdot 2^5 + 1 \cdot 2^4 + 0 \cdot 2^3 + 1 \cdot 2^2 + 1 \cdot 2^1 + 1 \cdot 2^0 \\ & = & 2^7 + 2^4 + 2^2 + 2^1 + 2^0 \end{array}$

(We took every binary digit $n$and multiplied by the power of two.)

With this in mind, you can write:

$151 \cdot P = 2^7 P + 2^4 P + 2^2 P + 2^1 P + 2^0 P$

The doubling-addition algorithm defines the following procedure:

  • To take $P$.
  • Double it to get$2P$.
  • To fold$2P$ and $P$ (to get the result $2^1P + 2^0P$)
  • Double$2P$, To obtain $2^2P$.
  • Add to the result (to get$2^2P + 2^1P + 2^0P$)
  • Double$2^2P$, receive $2^3P$.
  • Do not perform addition with $2^3P$.
  • Double$2^3P$, To obtain $2^4P$.
  • Add to the result (to get$2^4P + 2^2P + 2^1P + 2^0P$)
  • ...

As a result, we calculate $151 \cdot P$by completing a total of seven doublings and four additions.

If this is not completely clear to you, then here is a Python script that implements this algorithm:

def bits(n):
    Генерирует двоичные разряды n, начиная
    с наименее значимого бита.
    bits(151) -> 1, 1, 1, 0, 1, 0, 0, 1
    while n:
        yield n & 1
        n >>= 1
def double_and_add(n, x):
    Возвращает результат n * x, вычисленный
    алгоритмом удвоения-сложения.
    result = 0
    addend = x
    for bit in bits(n):
        if bit == 1:
            result += addend
        addend *= 2
    return result

If doubling and addition are operations $O(1)$then this algorithm has complexity$O(\log n)$ (or $O(k)$considering the bit length), which is pretty good. And of course, much better than the original algorithm$O(n)$!


For given $n$ and $P$ we have at least one polynomial calculation algorithm $Q = nP$. But what about the inverse problem? What if we know$Q$ and $P$, and we need to determine $n$? This problem is known as the logarithm problem . We use the word “logarithm” instead of the term “division” for consistency with other cryptosystems (in which exponentiation is used instead of multiplication).

I do not know a single “simple” algorithm for solving the logarithm problem, however, experimenting with multiplication , it is easy to detect some patterns. For example, take a curve$y^2 = x^3 - 3x + 1$ and point $P = (0, 1)$. We can immediately make sure that if$n$ odd then $nP$located on a curve in the left half-plane; if$n$ even then $nP$- in the right half-plane. If we experiment more, we may find other patterns that lead us to write an algorithm for efficiently calculating the logarithm of this curve.

But there is a variation of the logarithm problem: the discrete logarithm problem . As we will see in the next part, if we reduce the domain of definition of elliptic curves, scalar multiplication remains “simple”, and the discrete logarithm becomes a “difficult” task . Such duality is a key feature of cryptography on elliptic curves.

In the next part, we examine finite fields and the discrete logarithmization problem , as well as examples and tools for experiments.

Part 2: elliptic curves over finite fields and the discrete logarithm problem

In the previous part, we discussed how elliptic curves over real numbers can be used to define groups. Namely, we determined the rule of addition of points: the sum of three points lying on one straight line is zero ($P + Q + R = 0$) We derived geometric and algebraic methods for calculating the addition of points.

Then we introduced the concept of scalar multiplication ($nP = P + P + \cdots + P$) and found a “simple” algorithm for calculating scalar multiplication: doubling-addition.

Now we will limit the elliptic curves to finite fields rather than real numbers, and see what that changes.

Field of integers modulo p

A final field is, first of all, a set of a finite number of elements. An example of a finite field is the set of integers modulo$p$where $p$- Prime number. In general, this is written as$\mathbb{Z}/p$, $GF(p)$ or $\mathbb{F}_p$. We will use the last entry.

For fields, there are two double operations: addition (+) and multiplication (·). Both of them are closed, associative and commutative. For both operations there is a unique unit element and for each element there is a unique element of inverse value. And finally, multiplication is distributive with respect to addition:$x \cdot (y + z) = x \cdot y + x \cdot z$.

The set of integers modulo$p$ consists of all integers from 0 to $p - 1$. Addition and multiplication work as in modular arithmetic . Here are some examples of operations on$\mathbb{F}_{23}$:

  • Addition: $(18 + 9) \bmod{23} = 4$
  • Subtraction: $(7 - 14) \bmod{23} = 16$
  • Multiplication: $4 \cdot 7 \bmod{23} = 5$
  • Additive inversion: $-5 \bmod{23} = 18$. Really:$(5 + (-5)) \bmod{23} = (5 + 18) \bmod{23} = 0$
  • Multiplicative Inversion: $9^{-1} \bmod{23} = 18$

If you are unfamiliar with these equations and want to learn the basics of modular arithmetic, take a course at the Khan Academy .

As we have said integers modulo$p$Is a field, therefore all of the properties listed above are saved. Please note that the requirement that$p$was a prime number, very important! The set of integers modulo 4 is not a field: 2 does not have a multiplicative inversion (i.e., the equation$2 \cdot x \bmod{4} = 1$ has no decisions).

Modulo p

Soon we will define elliptic curves for $\mathbb{F}_p$but first we need to clearly understand that $x / y$ mean over $\mathbb{F}_p$. Simply put:$x / y = x \cdot y^{-1}$, or, in plain text, $x$ in the numerator and $y$ in the denominator is equal to $x$ times the reciprocal $y$. This does not surprise us, but it gives us a simple way to do the division: find the reciprocal of the number, and then do a simple multiplication .

The inverse number calculation can be "simply" performed using the extended Euclidean algorithm , which in the worst case has complexity$O(\log p)$ (or $O(k)$if we consider the bit length).

We will not go into details of the Euclidean extended algorithm, this is not part of the article, but I will present a working implementation in Python:

def extended_euclidean_algorithm(a, b):
    Возвращает кортеж из трёх элементов (gcd, x, y), такой, что
    a * x + b * y == gcd, где gcd - наибольший
    общий делитель a и b.
    В этой функции реализуется расширенный алгоритм
    Евклида и в худшем случае она выполняется O(log b).
    s, old_s = 0, 1
    t, old_t = 1, 0
    r, old_r = b, a
    while r != 0:
        quotient = old_r // r
        old_r, r = r, old_r - quotient * r
        old_s, s = s, old_s - quotient * s
        old_t, t = t, old_t - quotient * t
    return old_r, old_s, old_t
def inverse_of(n, p):
    Возвращает обратную величину
    n по модулю p.
    Эта функция возвращает такое целое число m, при котором
    (n * m) % p == 1.
    gcd, x, y = extended_euclidean_algorithm(n, p)
    assert (n * x + p * y) % p == gcd
    if gcd != 1:
        # Или n равно 0, или p не является простым.
        raise ValueError(
            '{} has no multiplicative inverse '
            'modulo {}'.format(n, p))
        return x % p

Elliptical curves over $\mathbb{F}_p$

Now we have all the necessary elements for restricting elliptic curves to a field $\mathbb{F}_p$. The set of points that in the previous part had the following form:

$\begin{array}{rcl} \left\{(x, y) \in \mathbb{R}^2 \right. & \left. | \right. & \left. y^2 = x^3 + ax + b, \right. \\ & & \left. 4a^3 + 27b^2 \ne 0\right\}\ \cup\ \left\{0\right\} \end{array}$

now turn into:

$\begin{array}{rcl} \left\{(x, y) \in (\mathbb{F}_p)^2 \right. & \left. | \right. & \left. y^2 \equiv x^3 + ax + b \pmod{p}, \right. \\ & & \left. 4a^3 + 27b^2 \not\equiv 0 \pmod{p}\right\}\ \cup\ \left\{0\right\} \end{array}$

where 0 is still a point at infinity, and $a$ and $b$ - two integers in $\mathbb{F}_p$.

Elliptic curves in Fp

Curve $y^2 \equiv x^3 - 7x + 10 \pmod{p}$ from $p = 19, 97, 127, 487$. Note that for each$x$there are a maximum of two points. Also notice the symmetry relative to$y = p / 2$.

Singular curve in Fp

Curve $y^2 \equiv x^3 \pmod{29}$ Is singular and has a triple point in $(0, 0)$. It is not a true elliptic curve.

What used to be a continuous curve has now become a set of individual points on the plane$xy$. But it can be proved that despite the restriction of the domain of definition, elliptic curves over$\mathbb{F}_p$still create an abelian group .

Point addition

Obviously, we need to slightly modify the definition of addition so that it works for $\mathbb{F}_p$. For real numbers, we said that the sum of three points on one line is zero ($P + Q + R = 0$) We can keep this definition, but what does it mean to have three points on one straight line above$\mathbb{F}_p$?

We can say that three points are on the same line if there is a line connecting them . Of course, straight over$\mathbb{F}_p$ differ from the lines above $\mathbb{R}$. We can say that the line above$\mathbb{F}_p$ Is a lot of points $(x, y)$satisfying the equation $ax + by + c \equiv 0 \pmod{p}$ (this is the standard equation of the line with the added part "$(\text{mod}\ p)$").

Point addition for elliptic curves in Z/p

Add points for a curve $y^2 \equiv x^3 - x + 3 \pmod{127}$at $P = (16, 20)$ and $Q = (41, 120)$. Notice how the line connecting the points$y \equiv 4x + 83 \pmod{127}$“Repeats” itself on the plane.

Given that we are still in the group, the addition of points preserves the properties we already know:

  • $Q + 0 = 0 + Q = Q$ (from the definition of a single element).
  • For $Q$ reciprocal $-Q$Is a point having the same abscissa but the inverse ordinate. Or, if you like,$-Q = (x_Q, -y_Q \bmod{p})$. For example, if the curve is over$\mathbb{F}_{29}$ has a point $Q = (2, 5)$then the inverse will be $-Q = (2, -5 \bmod{29}) = (2, 24)$.
  • Moreover, $P + (-P) = 0$ (from the definition of the reciprocal).

Algebraic Amount

The equations for performing addition of points are exactly the same as in the previous part , except that we need to add at the end of each expression "$\text{mod}\ p$"Therefore, if $P = (x_P, y_P)$, $Q = (x_Q, y_Q)$ and $R = (x_R, y_R)$then $P + Q = -R$ can be calculated in the following way:

$\begin{array}{rcl} x_R & = & (m^2 - x_P - x_Q) \bmod{p} \\ y_R & = & [y_P + m(x_R - x_P)] \bmod{p} \\ & = & [y_Q + m(x_R - x_Q)] \bmod{p} \end{array}$

If $P \ne Q$then the slope $m$ takes the form:

$m = (y_P - y_Q)(x_P - x_Q)^{-1} \bmod{p}$

Otherwise, if $P = Q$, we get:

$m = (3 x_P^2 + a)(2 y_P)^{-1} \bmod{p}$

The equations have not changed, and this is no coincidence: in fact, these equations work on any field, both finite and infinite (with the exception of $\mathbb{F}_2$ and $\mathbb{F}_3$which are special cases). I feel it needs to be explained. But there is a problem: proof of the group law usually requires complex mathematical concepts. However, I found Stefan Friedl's proof which uses only the simplest concepts. Read it if you are interested in why these equations work (almost) on any field.

Let us return to the curves - we will not determine the geometric method: in fact, problems will arise with it. For example, in the previous part, we said that to calculate$P + P$ we have to take the tangent to the curve in $P$. But in the absence of continuity, the word "tangent" loses all meaning. We can find a way around this and other problems, but the purely geometric way will be too complicated and completely impractical.

Instead, you can experiment with an interactive tool I wrote to make point additions .

Group order of an elliptic curve

We said that an elliptic curve defined over a finite field has a finite number of points. We need to answer an important question: how many points are there in it?

First, let's determine that the number of points in a group is called the group order .

Check all possible values ​​for$x$ in the range from 0 to $p - 1$ will be an impossible way to count points, because it will require $O(p)$ steps, and this task is “difficult” if $p$Is a large prime.

Fortunately, there is a faster algorithm for calculating order: Schoof's algorithm . I will not go into its details - the main thing is that it is done in polynomial time, and this is what we need.

Scalar Multiplication and Cyclic Subgroups

For real numbers, multiplication can be defined as:

$n P = \underbrace{P + P + \cdots + P}_{n\ \text{раз}}$

And again, we can use the doubling-addition algorithm to perform multiplication in $O(k)$where $k$ Is the number of bits $n$) I wrote an interactive tool for scalar multiplication .

Multiplication of points for elliptic curves over$\mathbb{F}_p$has an interesting property. Take a curve$y^2 \equiv x^3 + 2x + 3 \pmod{97}$ and point $P = (3, 6)$. Now we calculate all values ​​that are multiples of$P$:

Cyclic subgroup

All values ​​are multiples of $P = (3, 6)$are five different points ($0$, $P$, $2P$, $3P$, $4P$) that are cyclically repeated. It is easy to notice the similarity between scalar multiplication for elliptic curves and addition in modular arithmetic.

  • $0P = 0$
  • $1P = (3, 6)$
  • $2P = (80, 10)$
  • $3P = (80, 87)$
  • $4P = (3, 91)$
  • $5P = 0$
  • $6P = (3, 6)$
  • $7P = (80, 10)$
  • $8P = (80, 87)$
  • $9P = (3, 91)$
  • ...

You can immediately notice two features: firstly, values ​​that are multiples of $P$, only five: other points of the elliptic curve never become them. Secondly, they are repeated cyclically . You can write:

  • $5kP = 0$
  • $(5k + 1)P = P$
  • $(5k + 2)P = 2P$
  • $(5k + 3)P = 3P$
  • $(5k + 4)P = 4P$

for any whole $k$. Note that thanks to the remainder division operator, these five equations can be “squeezed” into one:$kP = (k \bmod{5})P$.

Moreover, we can immediately show that these five points are closed with respect to the addition operation . What does it mean: no matter how I summarize$0$, $P$, $2P$, $3P$ or $4P$, the result will always be one of these five points. And again, all the other points of the elliptic curve never become a result.

The same applies to all other points, not only to$P = (3, 6)$. In fact, if we take$P$ in general:

$nP + mP = \underbrace{P + \cdots + P}_{n\ \text{раз}} + \underbrace{P + \cdots + P}_{m\ \text{раз}} = (n + m)P$

Which means: if we add two values ​​that are multiples of$P$, then we obtain a multiple of $P$ (i.e. values ​​that are multiples of $P$are closed with respect to the addition operation). This is sufficient to prove that the set of multiple$P$values ​​is a cyclic subgroup of a group formed by an elliptic curve.

A “subgroup” is a group that is a subset of another group. A “cyclic subgroup” is a subgroup whose elements are cyclically repeated, as we showed in the previous example. Point$P$called a generator or base point of a cyclic subgroup.

Cyclic subgroups are the foundation for ECC and other cryptosystems. Later I will explain why this is so.

Subgroup Order

One may wonder what is the order of the subgroup generated by the point$P$ (or, in other words, what is the order $P$) We cannot use the Schoof algorithm to answer this question, because this algorithm works only for whole elliptic curves, but not for subgroups. Before proceeding with the solution of the problem, we need some more information:

  • So far, we have defined the order as the number of points in the group. This definition is still valid, but in cyclic subgroups we can give a new similar definition: order$P$ Is the minimum positive integer $n$such that $nP = 0$.

    In fact, if you look at the previous example, then our subgroup consisted of five points, and$5P = 0$.
  • Order $P$connected with the order of an elliptic curve by the Lagrange theorem , according to which the order of a subgroup is a divisor of the order of the original group .

    In other words, if an elliptic curve contains$N$ points, and one of the subgroups contains $n$then $n$ is a divider $N$.

Together, these two facts give us the opportunity to determine the order of the subgroup with the base point. $P$:

  1. Calculate the order of an elliptic curve $N$ using the Schuf algorithm.
  2. We find all the dividers $N$.
  3. For each divisor $n$ of order $N$ calculate $nP$.
  4. Least $n$such that $nP = 0$, is the order of the subgroup.

For example, a curve $y^2 = x^3 - x + 3$ over the field $\mathbb{F}_{37}$ has order $N = 42$. Its subgroups may be of order$n = 1$, $2$, $3$, $6$, $7$, $14$, $21$ or $42$. If we substitute$P = (2, 3)$then we will see that $P \ne 0$, $2P \ne 0$, ..., $7P = 0$that is, order $P$ is equal to $n = 7$.

Consider that it is important to take the smallest, but not a random divisor . If we choose randomly, we can get$n = 14$, which is not the order of the subgroup, but is one of the multiple.

Another example: an elliptic curve defined by the equation$y^2 = x^3 - x + 1$ over the field $\mathbb{F}_{29}$has order $N = 37$which is a prime. Its subgroups can only be ordered$n = 1$ or $37$. As you can guess when$n = 1$, the subgroup contains only an infinitely distant point; when$n = N$, the subgroup contains all points of the elliptic curve.

Base Point Search

ECC algorithms require high-order subgroups. Therefore, an elliptic curve is usually selected, its order is calculated ($N$), as the order of the group ($n$) a large divisor is selected, and then a suitable base point is found. That is, we do not select a base point, after which we calculate its order, but perform the reverse operation: first we select a fairly good order, and then we look for a suitable base point. How to do this?

First, you need to introduce another concept. The Lagrange theorem implies that the number$h = N / n$always whole (because$n$ - divider $N$) Number$h$It has its own name: it is a subgroup cofactor .

Now consider that for each point of the elliptic curve there is$NP = 0$. This is true because$N$ Is a multiple of any possible $n$. Based on the definition of cofactor, we can write:

$n(hP) = 0$

Now suppose that $n$- prime number (we prefer simple orders for the reasons stated in the first part of the article). This equation, written in this form, tells us that the point$G = hP$ creates a subgroup of order $n$ (except $G = hP = 0$in which the subgroup is of order 1).

In light of this, we can define the following algorithm:

  1. Calculate the order $N$ elliptic curve.
  2. Choose an order $n$subgroups. For the algorithm to work, the number must be prime and be a divisor$N$.
  3. Calculate the cofactor $h = N / n$.
  4. Choose a random point on the curve $P$.
  5. We calculate $G = hP$.
  6. If $G$ equal to 0, then we return to step 4. Otherwise, we found a subgroup generator with order $n$ and cofactor $h$.

Note that the algorithm only works if $n$simple. If$n$ was not easy then order $G$ could be one of the dividers $n$.

Discrete logarithm

As with continuous elliptic curves, we must now discuss the following question: if we know$P$ and $Q$then what will be $k$such that $Q = kP$?

This task, known as the discrete logarithm problem for elliptic curves, is considered to be “complex” for which no polynomial time algorithm was found running on a classical computer. However, this view does not have mathematical evidence.

This task is similar to the discrete logarithm problem used in other cryptosystems such as Digital Signature Algorithm (DSA), Diffie-Hellman Protocol (DH) and El-Gamal scheme. The names of the tasks do not coincide by chance. Their difference is that these algorithms use not scalar multiplication, but exponentiation modulo. Their discrete logarithm problem can be formulated as follows: if known$a$ and $b$then what will be $k$such that $b = a^k \bmod{p}$?

Both of these problems are “discrete” because they use finite sets (more specifically, cyclic subgroups). And they are “logarithms” because they are similar to ordinary logarithms.

ECC is interesting in that for the moment, the discrete logarithm problem for elliptic curves seems to be “more complicated” compared to other similar tasks used in cryptography. This implies that we need fewer bits for the whole$k$in order to get the same level of protection as in other cryptosystems, and we will consider this in detail in the fourth, last, part of the article.

Part 3: ECDH and ECDSA

Scope Parameters

Elliptic curve algorithms will work in a cyclic subgroup of an elliptic curve over a finite field. Therefore, the algorithms will require the following parameters:

  • Simple $p$defining the size of the final field.
  • Odds $a$ and $b$ elliptic curve equations.
  • Base point $G$generating a subgroup.
  • Order $n$ subgroups.
  • Cofactor $h$ subgroups.

As a result, the parameters of the domain for the algorithms are six$(p, a, b, G, n, h)$.

Random curves

When I said that the discrete logarithm problem was “complicated”, I was not entirely accurate. There are certain classes of elliptic curves that are rather weak and allow the use of special algorithms to effectively solve the discrete logarithm problem. For example, all curves for which$p = hn$(that is, the order of the final field is equal to the order of the elliptic curve), are vulnerable to Smart attack , which can be used to solve discrete logarithms in polynomial time on classical computers.

Suppose now that I gave you the parameters of the curve definition area. There is a possibility that I discovered a new class of weak curves unknown to anyone, and perhaps I created a “fast” algorithm for computing discrete logarithms for my curve. How can I convince you of the opposite, i.e. that I don’t know about vulnerabilities? How can I guarantee that the curve is “protected” (in the sense that I cannot use it for my own attacks)?

To solve this problem, sometimes you have to use an additional parameter of the definition area:seed value $S$. This is a random number used to generate coefficients.$a$ and $b$ or base point $G$or both. These parameters are generated by hash calculation.$S$. Hashes, as we know, are “easy” to compute, but “hard” to reverse.

A simple scheme for generating a random curve from a generating value: a random number hash is used to calculate various parameters of the curve.

If we wanted to cheat and recreate the hash from the parameters of the definition domain, then we would have to solve the “difficult” problem: inverting the hash.

The curve generated using the generating value is called checked randomly . The principle of using hashes to generate parameters is known as “ nothing up my sleeve ” and is widely used in cryptography.

This trick gives a certain guarantee that the curve was not specially created in such a way as to have vulnerabilities known to its author . In fact, if I give you a curve along with a generating value, it means that I could not arbitrarily choose the parameters$a$ and $b$, and you can be relatively calm that I can’t use special attacks. The reason for using the word “relative” will be explained in the fourth part.

A standardized algorithm for generating and checking random curves is described in ANSI X9.62 and is based on SHA-1 . If interested, you can read about the algorithms for generating verifiable random curves in the SECG specification (see "Verifiably Random Curves and Base Point Generators").

I wrote a small Python script that checks all the random curves that ship with OpenSSL right now . I highly recommend watching it!

Elliptic Curve Cryptography

We spent a lot of time, but finally got there! It's simple:

  1. The private key is a random integer$d$selected from $\{1, \dots, n - 1\}$ (Where $n$ - subgroup order).
  2. The public key is the point$H = dG$ (Where $G$ - base point of the subgroup).

See? If we know$d$ and $G$ (together with other parameters of the definition domain), then find $H$"simply". But if we know$H$ and $G$then search for the private key$d$is a “difficult” problem, because it requires solving the discrete logarithm problem .

We will now describe two public key algorithms based on this principle: ECDH (Elliptic curve Diffie-Hellman, Diffie-Hellman protocol on elliptic curves), used for encryption, and ECDSA (Elliptic Curve Digital Signature Algorithm), used for digital signatures.

Encryption with ECDH

ECDH is a variation of the Diffie-Hellman algorithm for elliptic curves. In fact, it is more likely a key agreement protocol , rather than an encryption algorithm. In essence, this means that ECDH defines (to a certain extent) the order in which keys are generated and exchanged. We can choose the method of encrypting data using such keys ourselves.

It solves the following problem: two parties (usually Alice and Bob ) want to safely exchange information so that a third party ( intermediary, Man In the Middle ) can intercept it, but cannot decrypt it. For example, this is one of the principles of TLS.

Here's how it works:

  1. First, Alice and Bob generate their own private and public keys . Alice has a private key$d_A$ and public key $H_A = d_AG$Bob has the keys $d_B$ and $H_B = d_BG$. Note that both Alice and Bob use the same definition area parameters: one base point$G$ on one elliptic curve in the same finite field.
  2. Alice and Bob exchange public keys $H_A$ and $H_B$through an unprotected channel . Intermediary (Man In the Middle) intercepts$H_A$ and $H_B$but cannot identify either $d_A$nor $d_B$without solving the discrete logarithm problem.
  3. Alice calculates $S = d_A H_B$(using Bob’s own private key and Bob’s public key), and Bob calculates$S = d_B H_A$(using Alice’s own private key and Alice’s public key). Note that$S$the same for both Alice and Bob. In fact:

    $S = d_A H_B = d_A (d_B G) = d_B (d_A G) = d_B H_A$

However, the intermediary knows only $H_A$ and $H_B$(together with other parameters of the scope) and he will not be able to find a shared secret$S$. This is known as the Diffie-Hellman problem, which can be formulated as follows:

What will be the result $abP$ for three points $P$, $aP$ and $bP$?

Or similarly:

What will be the result $k^{xy}$ for three whole $k$, $k^x$ and $k^y$?

(The latter formulation is used in the original Diffie-Hellman algorithm based on modular arithmetic.)


Diffie-Hellman Protocol: Alice and Bob can “simply” calculate the shared secret key, while the intermediary will have to solve the “difficult” problem.

The principle underlying the Diffie-Hellman problem is also explained in the excellent Khan Academy video on YouTube , which later explains the Diffie-Hellman algorithm as applied to modular arithmetic (not elliptic curves).

The Diffie-Hellman problem for elliptic curves is considered "difficult." It is believed that it is as "complicated" as the discrete logarithm problem, but there is no mathematical evidence for this. We can only say with confidence that it cannot be “harder” because solving the logarithm problem is a way to solve the Diffie-Hellman problem.

Having received a shared secret key, Alice and Bob can exchange data with symmetric encryption.

For example, they can use the coordinate$x$ the key $S$as a key to encrypt messages with secure ciphers like AES or 3DES . That's what TLS does, the difference is that TLS connects the coordinate$x$ with other numbers related to the connection, and then calculates the hash of the resulting byte string.

ECDH Experiments

I wrote another Python script to calculate private / public keys and shared secret keys over an elliptic curve .

Unlike the examples shown earlier, this script uses a standardized curve, not a simple curve in a small field. I chose the curve secp256k1of the SECG (Standards for Efficient Cryptography Group, founded by Certicom ). The same curve is used in Bitcoin for digital signatures. Here are the options for the scope:

  • $p$ = 0xffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f
  • $a$ = 0
  • $b$ = 7
  • $x_G$ = 0x79be667e f9dcbbac 55a06295 ce870b07 029bfcdb 2dce28d9 59f2815b 16f81798
  • $y_G$ = 0x483ada77 26a3c465 5da4fbfc 0e1108a8 fd17b448 a6855419 9c47d08f fb10d4b8
  • $n$ = 0xffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141
  • $h$ = 1

(These numbers are taken from the OpenSSL source code .)

Of course, you can change the script and use other curves and parameters of the definition area, just be sure to use simple fields and the usual Weierstrass formulation, otherwise the script will not work.

The script is very simple and contains some of the algorithms described above: point addition, doubling-addition, ECDH. I recommend to study and run it. It creates approximately the following output:

Curve: secp256k1
Alice's private key: 0xe32868331fa8ef0138de0de85478346aec5e3912b6029ae71691c384237a3eeb
Alice's public key: (0x86b1aa5120f079594348c67647679e7ac4c365b2c01330db782b0ba611c1d677, 0x5f4376a23eed633657a90f385ba21068ed7e29859a7fab09e953cc5b3e89beba)
Bob's private key: 0xcef147652aa90162e1fff9cf07f2605ea05529ca215a04350a98ecc24aa34342
Bob's public key: (0x4034127647bb7fdab7f1526c7d10be8b28174e2bba35b06ffd8a26fc2c20134a, 0x9e773199edc1ea792b150270ea3317689286c9fe239dd5b9c5cfd9e81b4b632)
Shared secret: (0x3e2ffbc3aa8a2836c1689e55cd169ba638b58a3a18803fcf7de153525b28c3cd, 0x43ca148c92af58ebdb525542488a4fe6397809200fe8c61b41a105449507083)

Ephemeral ECDH

Some of you may have heard of ECDHE, not ECDH. The “E” in ECHDE stands for “Ephemeral” (ephemeral) and is due to the fact that the keys being transmitted are temporary , not static.

ECDHE is used, for example, in TLS, where the client and server generate their private-public key pair on the fly when establishing a connection. Then the keys are signed with a TLS certificate (for authorization) and transmitted between the parties.

Signing with ECDSA

The scenario is as follows: Alice wants to sign the message with her private key ($d_A$), and Bob wants to verify the signature with Alice’s public key ($H_A$) No one but Alice should be able to create valid signatures. Everyone should be able to verify signatures.

Alice and Bob again use the same scope parameters. We will look at the ECDSA algorithm, a type of Digital Signature Algorithm applied to elliptic curves.

ECDSA works with the message hash, not the message itself. The choice of the hash function remains with us, but, obviously, we need to choose the cryptographic hash function . The message hash must be truncated so that the hash bit length is the same as the bit length$n$(subgroup order). A truncated hash is an integer and it will be denoted as$z$.

The algorithm performed by Alice to sign the message works as follows:

  1. Take a random integer$k$selected from $\{1, \dots, n - 1\}$ (Where $n$ - this is still the order of the group).
  2. Calculate point $P = kG$ (Where $G$ - base point of the subgroup).
  3. We calculate the number $r = x_P \bmod{n}$ (Where $x_P$ Is the coordinate $x$$P$)
  4. If $r = 0$, then choose another $k$ and try again.
  5. We calculate $s = k^{-1} (z + rd_A) \bmod{n}$ (Where $d_A$ - Alice’s private key, and $k^{-1}$ - multiplicative inversion $k$ modulo $n$)
  6. If $s = 0$, then choose another $k$ and try again.

Couple $(r, s)$is a signature .


Alice signs a hash $z$ using private key $d_A$ and random $k$. Bob verifies the signature of the message using Alice's public key$H_A$.

Simply put, this algorithm first generates a secret key ($k$) Thanks to the multiplication of points (which, as we know, is “simple” in one direction and “complex” in the opposite), the secret key is hidden in$r$. Then$r$ tied to a message hash by the equation $s = k^{-1} (z + rd_A) \bmod{n}$.

Note that to calculate$s$ we calculated the reciprocal $k$ modulo $n$. As mentioned in the previous part, this is guaranteed to work only if$n$- Prime number. If the subgroup is of a complex order, ECDSA cannot be used. It is no coincidence that all standardized curves have a simple order, and having a difficult order are not applicable to ECDSA.

Signature Verification

To verify the signature, Alice's public key is required $H_A$, (truncated) hash $z$ and obviously the signature $(r, s)$.

  1. We calculate the integer $u_1 = s^{-1} z \bmod{n}$.
  2. We calculate the integer $u_2 = s^{-1} r \bmod{n}$.
  3. Calculate point $P = u_1 G + u_2 H_A$.

Signature is valid only if $r = x_P \bmod{n}$.

Algorithm correctness

At first glance, the logic of the algorithm may not be obvious, but if we combine all the equations we have written down, everything becomes clearer.

Start with$P = u_1 G + u_2 H_A$. From the definition of the public key, we know that$H_A = d_A G$ (Where $d_A$- private key). You can write:

$\begin{array}{rl} P & = u_1 G + u_2 H_A \\ & = u_1 G + u_2 d_A G \\ & = (u_1 + u_2 d_A) G \end{array}$

Subject to definitions $u_1$ and $u_2$ can be written:

$\begin{array}{rl} P & = (u_1 + u_2 d_A) G \\ & = (s^{-1} z + s^{-1} r d_A) G \\ & = s^{-1} (z + r d_A) G \end{array}$

Here we omitted "$\text{mod}\ n$", both for brevity and because the cyclic subgroup generated by the point $G$has order $n$, that is, the "$\text{mod}\ n$"redundant.

We previously determined$s = k^{-1} (z + rd_A) \bmod{n}$. Multiplying both sides of the equation by$k$ and dividing by $s$, we get: $k = s^{-1} (z + rd_A) \bmod{n}$. Substituting this result in our equation for$P$we get:

$\begin{array}{rl} P & = s^{-1} (z + r d_A) G \\ & = k G \end{array}$

This is the same equation. $P$that we had in step 2 of the signature generation algorithm! When generating signatures and checking them, we calculate the same point$P$, just different sets of equations. That is why the algorithm works.

Experimenting with ECDSA

Of course, I wrote a Python script to generate and verify signatures . The code copies some parts from the ECDH script, in particular, the parameters of the definition area and the algorithm for generating the private / public key pair.

Here is the output generated by this script:

Curve: secp256k1
Private key: 0x9f4c9eb899bd86e0e83ecca659602a15b2edb648e2ae4ee4a256b17bb29a1a1e
Public key: (0xabd9791437093d377ca25ea974ddc099eafa3d97c7250d2ea32af6a1556f92a, 0x3fe60f6150b6d87ae8d64b78199b13f26977407c801f233288c97ddc4acca326)
Message: b'Hello!'
Signature: (0xddcb8b5abfe46902f2ac54ab9cd5cf205e359c03fdf66ead1130826f79d45478, 0x551a5b2cd8465db43254df998ba577cb28e1ee73c5530430395e4fba96610151)
Verification: signature matches
Message: b'Hi there!'
Verification: invalid signature
Message: b'Hello!'
Public key: (0xc40572bb38dec72b82b3efb1efc8552588b8774149a32e546fb703021cf3b78a, 0x8c6e5c5a9c1ea4cad778072fe955ed1c6a2a92f516f02cab57e0ba7d0765f8bb)
Verification: invalid signature

As you can see, the script first signs the message (byte string “Hello!”), And then checks the signature. Then he tries to verify the same signature for another message ("Hi there!") And the verification fails. Finally, he tries to verify the verification of the signature for the correct message, but with another random public key, after which verification also fails.

Importance k

When generating ECDSA signatures, it's important to keep secret $k$truly secret. If we used one$k$for all signatures or a random number generator would be predictable to some extent, the attacker could determine the private key !

Sony made a similar mistake a few years ago. On the PlayStation 3 game console, it was possible to run games only signed by Sony using the ECDSA algorithm. That is, if I wanted to create a new game for the PlayStation 3, I could not distribute it among users without a Sony signature. The problem was that all the signatures created by Sony were generated using static$k$.

(It seems that the creators of the random number generator, or inspired by Sony XKCD , or Dilbert .)

In this situation, you can easily recover the private key$d_S$ Sony, having bought only two signed games, then extract their hashes ($z_1$ and $z_2$) and signatures ($(r_1, s_1)$ and $(r_2, s_2)$) together with the parameters of the domain. This is done like this:

  • First you need to consider that $r_1 = r_2$ (because $r = x_P \bmod{n}$ and $P = kG$ same for both signatures).
  • Accept that $(s_1 - s_2) \bmod{n} = k^{-1} (z_1 - z_2) \bmod{n}$ (this result follows directly from the equation for $s$)
  • Multiply both sides of the equation by $k$: $k (s_1 - s_2) \bmod{n} = (z_1 - z_2) \bmod{n}$.
  • Divided by $(s_1 - s_2)$, To obtain $k = (z_1 - z_2)(s_1 - s_2)^{-1} \bmod{n}$.

The last equation allows us to calculate $k$with just two hashes and their corresponding signatures. Now using the equation for$s$ we can get the private key:

$s = k^{-1}(z + rd_S) \bmod{n}\ \ \Rightarrow\ \ d_S = r^{-1} (sk - z) \bmod{n}$

Similar techniques can be applied if $k$ not static, but somehow predictable.

Part 4: algorithms for hacking ECC protection and comparison with RSA

In the previous part we examined two algorithms (ECDH and ECDSA) and figured out why the discrete logarithm problem for elliptic curves plays an important role for their safety. But, if you remember, we said that there is no mathematical proof of the complexity of the discrete logarithm problem: we believe that it is "complex", but we are not sure about it. In the first part of the article, we tried to evaluate how “difficult” it is in practice in modern technology.

In the second part, we tried to answer the question: why do we need cryptography on elliptic curves if RSA (and other cryptosystems based on modular arithmetic) work well?

Hacking discrete logarithms

Now we will consider two of the most effective algorithms for computing discrete algorithms on an elliptic curve: the baby-step, giant-step algorithm and the Pollard ρ-algorithm.

Before starting, I’ll remind you what the discrete logarithm problem is: find for two given points$P$ and $Q$ integer $x$satisfying the equation $Q = xP$. Points belong to a subgroup of an elliptic curve with a base point$G$ and order $n$.

Baby-step, giant-step

To begin with, I’ll give a simple argument: we can always write down any whole $x$ as $x = am + b$where $a$, $m$ and $b$- three arbitrary integers. For example, you can write$10 = 2 \cdot 3 + 4$.

With this in mind, we can rewrite the equation of the discrete logarithm problem as follows:

$\begin{array}{rl} Q & = xP \\ Q & = (am + b) P \\ Q & = am P + b P \\ Q - am P & = b P \end{array}$

Baby-step giant-step is a “meeting in the middle” algorithm. Unlike brute force attack (in which all points have to be calculated$xP$ for everybody $x$until we find $Q$), it is possible to calculate “several” values ​​for $bP$ and "several" values ​​for $Q - amP$until we find a match. The algorithm works as follows:

  1. We calculate $m = \left\lceil{\sqrt{n}}\right\rceil$
  2. For everybody $b$ of ${0, \dots, m}$ calculate $bP$ and save the results to a hash table.
  3. For everybody $a$ of ${0, \dots, m}$:
    1. calculate $amP$;
    2. calculate $Q - amP$;
    3. check the hash table and look for a point $bP$such that $Q - amP = bP$;
    4. if such a point exists, then we found $x = am + b$.

As you can see, initially we calculate the points $bP$with a small increment (“baby steps ) for the coefficient$b$ ($1P$, $2P$, $3P$, ...). In the second part of the algorithm, we calculate the points$amP$with a large increment ("giant steps" "giant step" ) for$am$ ($1mP$, $2mP$, $3mP$, ... where $m$ - big number).

Baby-step, giant-step

Baby-step, giant-step algorithm: first, we calculate several points with a small step and save them in a hash table. Then we take giant steps and compare the new points with the points in the hash table. Having found a correspondence, we can calculate the discrete algorithm by simple permutation of the terms.

To understand how the algorithm works, forget for a moment that$bP$ are cached and take the equation $Q = amP + bP$. Consider what follows from this:

  • At $a = 0$ we check if $Q$ the number $bP$where $b$ - one of the integers from 0 to $m$. So we compare$Q$ with all points from $0P$ before $mP$.
  • At $a = 1$ we check whether $Q$ the number $mP + bP$. We compare$Q$ with all points from $mP$ before $2mP$.
  • At $a = 2$ we compare $Q$ with all points from $2mP$ before $3mP$.
  • ...
  • At $a = m - 1$ we compare $Q$ with all points from $(m - 1)mP$ before $m^2 P = nP$.

As a result, we checked all the points from$0P$ before $nP$(that is, all possible points) by completing no more$2m$additions and multiplications (exactly$m$ for "children's steps", no more $m$for "giant steps").

Assuming a hash table search takes time$O(1)$it’s easy to see that this algorithm has temporal and spatial complexity$O(\sqrt{n})$ (or $O(2^{k / 2})$if you consider the bit length). This is still an exponential time, but it is much better than with a brute force attack.

Baby-step giant-step in practice

It makes sense to figure out what complexity means. $O(\sqrt{n})$on practice. Let's take a standardized curve: prime192v1(she secp192r1, ansiX9p192r1). This curve is of order$n$= 0xffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831. Square root of$n$- this is approximately 7.922816251426434 · 10 28 (almost eighty octillion [approx. Transl.: On a short scale] ).

Imagine what we store$\sqrt{n}$points in the hash table. Suppose each point occupies exactly 32 bytes: a hash table will require approximately 2.5 · 10 30 bytes of memory . By searching the Internet , you can find out that the current total capacity of drives around the world has a zettabyte order (10 21 bytes). This is almost ten orders of magnitude less than the amount of memory required by our hash table! Even if the points occupied 1 byte each, we still could not store them all.

This is impressive, and even more impressive, if you remember that prime192v1- this is one of the curves with the smallest order. The order secp521r1(of another standard NIST curve) is approximately 6.9 · 10 156 !

Experiments with baby-step giant-step

I wrote a Python script that calculates discrete logarithms using the baby-step giant-step algorithm. Obviously, it only works with small-order curves: do not try to use secp521r1it unless you want to get it MemoryError.

The script produces approximately the following output:

Curve: y^2 = (x^3 + 1x - 1) mod 10177
Curve order: 10331
p = (0x1, 0x1)
q = (0x1a28, 0x8fb)
325 * p = q
log(p, q) = 325
Took 105 steps

ρ Pollard

ρ Pollard is another algorithm for computing discrete logarithms. It has the same asymptotic time complexity.$O(\sqrt{n})$as baby-step giant-step, but its spatial complexity is only $O(1)$. If baby-step giant-step could not solve the discrete logarithms due to the huge memory requirements, maybe ρ Pollard can handle it? Let's check ...

First, let me remind you again the discrete logarithm problem: find for given$P$ and $Q$ whole $x$such that $Q = xP$. In the Pollard ρ-algorithm, we will solve a slightly different problem: find for given$P$ and $Q$whole $a$, $b$, $A$ and $B$such that $aP + bQ = AP + BQ$.

Having found four integers, we can use the equation$Q = xP$ to calculate $x$:

$\begin{array}{rl} aP + bQ & = AP + BQ \\ aP + bxP & = AP + BxP \\ (a + bx) P & = (A + Bx) P \\ (a - A) P & = (B - b) xP \end{array}$

Now we can get rid of $P$. But before doing this, remember that our subgroup is cyclic and has the order$n$, that is, the coefficients used in the multiplication of points are taken modulo $n$:

$\begin{array}{rl} a - A & \equiv (B - b) x \pmod{n} \\ x & = (a - A)(B - b)^{-1} \bmod{n} \end{array}$

Oll Pollard’s principle of operation is simple: we define a pseudo-random sequence of pairs$(a, b)$. This sequence of pairs can be used to generate a sequence of points.$aP + bQ$. Because the$P$ and $Q$are elements of one cyclic subgroup, a sequence of points$aP + bQ$also cyclic .

This means that if we go around our pseudo-random sequence of pairs$(a, b)$then sooner or later we find a cycle. That is: we will find a pair$(a, b)$ and another separate pair $(A, B)$such that $aP + bQ = AP + BQ$. The same points, separate pairs: we can apply the above equation to find the logarithm.

The challenge is this: how to detect a loop in an efficient way?

Turtle and hare

To detect a loop, we can check all possible values $a$ and $b$using the pair conversion function , but provided that there is$n^2$ such pairs, the algorithm will have complexity $O(n^2)$, which is much worse than a simple brute force attack.

But there is a faster way: the turtle and hare algorithm (also known as the Floyd cycle finding algorithm). The figure below shows the principle of operation of the tortoise and hare method, on which the Pollard ρ-algorithm is based.

Tortoise and Hare

We have a curve $y^2 \equiv x^3 + 2x + 3 \pmod{97}$ and points $P = (3, 6)$ and $Q = (80, 87)$. The points belong to a cyclic subgroup with order 5. We go around a sequence of pairs with different speeds until we find two different pairs$(a, b)$ and $(A, B)$giving one point. In this case, we found pairs$(3, 3)$ and $(2, 0)$, which allows us to calculate the logarithm as $x = (3 - 2)(0 - 3)^{-1} \bmod{5} = 3$. And in fact, we did it$Q = 3P$.

In essence, we take a pseudo-random sequence of pairs$(a, b)$ together with the corresponding sequence of points $aP + bQ$. Sequence of pairs$(a, b)$ may or may not be cyclic, but the sequence of points is exactly cyclic, because $P$ and $Q$generated from one base point, and from the property of subgroups we know that we cannot “escape” from a subgroup only by scalar multiplication and addition.

Now we take two animals, a turtle and a hare, and make them go around the sequence from left to right. The turtle (the green dot in the image) is slow and reads each dot, one after the other ; The hare (red dot) is fast and skips the dot at every step .

After some time, the turtle and the hare will find one point, but with different pairs of coefficients. Or, to put it in equations, the turtle will find a pair$(a, b)$and the hare is a couple $(A, B)$such that $aP + bQ = AP + BQ$.

If a random sequence is determined through an algorithm (and not stored statically), it is easy to see that the principle of operation requires everything$O(\log n)$space . Computing the complexity of asymptotic time is not so simple, but we can construct a probabilistic proof showing that the time complexity is$O(\sqrt{n}$) , as we have said.

Experimenting with ρ Pollard

I created a Python script that computes discrete logarithms using the Pollard ρ algorithm. This is not an implementation of the original ρ Pollard, but a small variation of it (I used a more efficient way to generate a pseudo-random sequence of pairs). The script has useful comments, so read it if you are interested in the details of the algorithm.

This script, like baby-step giant-step, works for small curves and produces the same output.

Ro Pollard in practice

We said that baby-step giant-step cannot be used in practice due to the huge memory requirements. Pollard's ro-algorithm, on the other hand, requires very little memory. How practical is it?

In 1998, Certicom started the competition for computing discrete logarithms on elliptic curves with a bit length from 109 to 369. To date, only 109 bit curves have been successfully cracked . The last successful attempt was made in 2004. To quote Wikipedia :

The award was presented on April 8, 2004 to approximately 2,600 people represented by Chris Monico. They also used a kind of Pollard’s parallelized ro-algorithm, the calculations on which took 17 months of calendar time.

As we said, prime192v1this is one of the "smallest" elliptic curves. We also said that ρ Pollard has temporary complexity$O(\sqrt{n})$. If we used the same technique as Chris Moniko (the same algorithm, the same equipment and the number of machines), how much would it take to calculate the logarithm for prime192v1?

$17\ \text{месяцев}\ \times \frac{\sqrt{2^{192}}}{\sqrt{2^{109}}} \approx 5 \cdot 10^{13}\ \text{месяцев}$

The result obtained speaks for itself and makes it clear how difficult it is to crack a discrete logarithm using such techniques.

Compare ρ Pollard and Baby-step giant-step

I decided to combine the baby-step giant-step script , the Pollard script and the brute force script into a fourth script to compare their performance.

This fourth script calculates all the logarithms for all points on the “small” curve using different algorithms and reports how long it took:

Curve order: 10331
Using bruteforce
Computing all logarithms: 100.00% done
Took 2m 31s (5193 steps on average)
Using babygiantstep
Computing all logarithms: 100.00% done
Took 0m 6s (152 steps on average)
Using pollardsrho
Computing all logarithms: 100.00% done
Took 0m 21s (138 steps on average)

As you might expect, the enumeration method is monstrously slow compared to the other two. Baby-step giant-step is faster, and Pollard's ro-algorithm is more than three times slower than baby-step giant-step (although it uses much less memory and fewer steps on average).

Take a look at the number of steps: on average, 5193 steps were required to calculate each logarithm by brute force. 5193 is very close to 10331/2 (half the order of the curve). Baby-step giant-steps and ro Pollard used 152 steps and 138 steps respectively. These two numbers are very close to the square root of 10331 (101.64).

Further considerations

In the discussion of these algorithms, I used a lot of numbers. When reading them, it is important to be careful: algorithms in many aspects can be greatly optimized. Equipment may be improved. You can create specialized equipment.

If the approach seems impractical today, this does not mean that it cannot be improved. This also does not mean that there are no other, better approaches (do not forget that we have no evidence of the complexity of the discrete logarithm problem).

Shore Algorithm

If modern techniques are not applicable, then what about techniques for the near future? The situation is causing more and more concern: there is already a quantum algorithm capable of computing discrete logarithms in polynomial time: the Shore algorithm with time complexity$O((\log n)^3)$ and spatial complexity $O(\log n)$.

The efficiency of quantum algorithms lies in superposition of the state. On classic computers, memory cells (i.e., bits) can have a value of 1 or 0. There are no intermediate states between them. On the other hand, the memory cells of quantum computers (qubits) are subject to the principle of uncertainty: until they are measured, they do not have a fully defined state. Superposition of the state does not mean that each qubit can simultaneously have the value 0 and 1 (as is often written on the Internet). It means that when measuring a qubit, we have a certain probability of observing 0 and another probability of observing 1. The work of quantum algorithms consists in changing the probability of each qubit.

This oddity means that with a limited number of qubits, we can simultaneously deal with many possible input data at the same time. For example, we can tell a quantum computer that there is a number$x$uniformly distributed between 0 and $n - 1$. All that is required$\log n$ qubits instead $n \log n$bit. Then we can order the quantum computer to perform scalar multiplication$xP$. As a result, we obtain a superposition of states given by all points from$0P$ before $(n - 1)P$that is, if we now measure all the qubits, we get one of the points from $0P$ before $(n - 1)P$ with probability $1 / n$.

I talked about this so that you understand the full power of superposition of states. Shore's algorithm does not work quite like that, in fact it is more complex. It is complicated by the fact that although we can "pretend"$n$ states at the same time, at some stage, we will have to reduce this number of states to several, because at the output we need one number, and not several (i.e., we need to know one logarithm, and not a lot of probably erroneous logarithms).


Now let's forget about quantum computing, which has not yet become a serious problem. I want to answer the following question: why bother with elliptical curves if RSA already works well?

NIST gave a simple answer by presenting a table comparing the RSA and ECC key sizes needed to get the same level of protection.
RSA key size (bits)ECC Key Size (bits)

Note that there is no linear relationship between RSA and ECC key sizes (in other words: if we double the RSA key size, we don’t need to double the ECC key size). The table tells us that ECC not only uses less memory, but generating keys with signing in it is much faster.

But why is this so? The answer is that the fastest algorithms for computing discrete algorithms over elliptic curves are the Pollard ρ-algorithm and baby-step giant-step, and in the case of RSA there are faster algorithms. In particular, one of them is the general method of sieve a number field : an algorithm for factoring integers, which can be used to calculate discrete logarithms. The general method of sieve a number field is by far the fastest algorithm for factoring integers.

All this applies to other cryptosystems based on modular arithmetic, including DSA, Diffie-Hellman and El-Gamal.

Hidden threats of the NSA

Now let's move on to the difficult part. Up to this point, we have discussed algorithms and mathematics. It is time to discuss people, and things are getting more complicated.

If you remember, in the third part we said that some classes of elliptic curves are weak, therefore, to solve the problem of obtaining reliable curves from doubtful sources, we add a random seed value to the parameters of the definition domain. And if you look at the standard NIST curves, you can see that they are verifiable random.

If you read the Wikipedia page about the principle “there is nothing in the sleeves ”, you will notice that:

  • Случайные числа для MD5 получаются из синуса целых чисел.
  • Случайные числа для Blowfish получаются из первых чисел $\pi$.
  • Случайные числа для RC5 получаются из $e$ и золотого сечения.

These numbers are random because their numbers are evenly distributed. And they do not raise suspicions, because they have a justification.

Now the following question arises: where do the random generating values ​​for the NIST curves come from? Answer: unfortunately, we do not know. These values ​​have no justification.

Is it possible that NIST discovered a “significantly large” class of weak elliptic curves, tried various possible variants of generating values ​​and found a vulnerable curve? I cannot answer this question, but it is a natural and important question. We know that NIST has at least successfully standardized a vulnerable random number generator(a generator, which, oddly enough, is based on elliptic curves). Perhaps he successfully standardized many weak elliptic curves as well? How to check it? No way.

It is important to understand that “verifiable random” and “protected” are not synonyms. And it doesn’t matter how complicated the logarithm task is or how long the keys are - if the algorithms are cracked, then we can do nothing.

In this regard, the RSA wins because it does not require special domain parameters that can be exploited. RSA (like other modular arithmetic systems) can be a good alternative if we cannot trust the authorities and if we cannot create our own parameters for the definition domain. And if you're curious: yes, TLS can use NIST curves. If you check in google, you will see that when connecting, ECDHE and ECDSA are used with a certificate based on prime256v1(it is secp256p1).

That's all!

I hope you enjoyed this article. I tried to introduce you to the basic information, terminology and assumptions necessary to understand the current state of cryptography on elliptic curves. If I succeeded, then now you can deal with existing ECC-based cryptosystems and expand your knowledge by reading deeper documentation. When writing an article, I skipped a lot of details and used simplified terminology, but I felt that otherwise you would not have understood the information presented on the Internet. I believe that I managed to find a good compromise between the simplicity and completeness of the information.

However, it is worth noting that after reading only this article, you will not be able to implement secure cryptosystems based on ECC: security requires knowledge of many subtle but important details. Remember the requirements for Smart attack and the Sony error - these are two examples of how you can create unsafe algorithms and how easy they can be exploited.

So, if you are interested in diving deeper into the ECC world, then where do you start?

First, while we saw the Weierstrass curves over simple fields, but you should know that there are other types of curves and fields, namely:

  • Koblitz curves over binary fields. These are elliptical shaped curves$y^2 + xy = x^3 + ax^2 + 1$ (Where $a$ - 0 or 1) over finite fields containing $2^m$ elements (where $m$ — простое число). Они обеспечивают особо эффективное сложение точек и скалярное умножение.

    Примерами стандартизированных кривых Коблица являются nistk163, nistk283 и nistk571 (три кривые, определённые над полем из 163, 283 и 571 бит).
  • Двоичные кривые. Они очень похожи на кривые Коблица и имеют форму $x^2 + xy = x^3 + x^2 + b$ (где $b$ — целое число, часто генерируемое из случайного порождающего значения). Как подсказывает название, двоичные кривые ограничены только двоичными полями. Примерами стандартизированных кривых являются nistb163, nistb283 и nistb571.

    Надо сказать, что возникает всё больше подозрений в том, что кривые Коблица и двоичные кривые могут быть не так безопасны, как простые кривые.
  • Кривые Эдвардса имеют вид $x^2 + y^2 = 1 + d x^2 y^2$ (где $d$ — это 0 или 1). Они особенно интересны не только потому, что для них быстро выполняются сложение точек и скалярное умножение, но и потому, что формула сложения точек всегда одинакова, в любом случае ($P \ne Q$, $P = Q$, $P = -Q$, ...). Эта особенность снижает возможность атак по сторонним каналам (side-channel attack), при которых атакующий измеряет время, использованное для скалярного умножения, и пытается подобрать скалярный коэффициент на основании времени для его вычисления.

    Кривые Эдвардса относительно новы (впервые они были представлены в 2007 году), поэтому ни один орган, такой как Certicom или NIST, пока не стандартизировал ни одну из них.
  • Curve25519 and Ed25519 are two special elliptical curves created for ECDH and the ECDSA variant respectively. Like the Edwards curves, these two curves are quick and help defend against attacks on third-party channels. Like Edwards curves, these two curves have not yet been standardized and are not used in popular software (with the exception of OpenSSH, which has supported Ed25519 key pairs since 2014).

If you are interested in the details of ECC implementation, I suggest you read the sources of OpenSSL and GnuTLS .

And finally, if you are interested in the mathematical details, and not the safety and efficiency of the algorithms, then you need to know the following:

  • Elliptic curves are algebraic varieties of genus 1 .
  • Infinitely distant points are studied in projective geometry . They can be represented using uniform coordinates (although most of the properties of projective geometry are not needed for cryptography on elliptic curves).

And don't forget to study finite fields along with field theory .

If you are interested in this topic, then it is worth looking for such keywords.

This article officially ends. Thank you for all the friendly comments, tweets and letters. Many asked if I would write other articles on related topics. My answer is: maybe. You can send your suggestions, but I do not promise anything.

Also popular now: