Skip to content

Commit

Permalink
add description of low level elliptic curve operations
Browse files Browse the repository at this point in the history
  • Loading branch information
tomato42 committed Apr 25, 2022
1 parent f2178c1 commit ef53e9f
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 1 deletion.
125 changes: 125 additions & 0 deletions docs/source/ec_arithmetic.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
=========================
Elliptic Curve arithmetic
=========================

The python-ecdsa also provides generic API for performing operations on
elliptic curve points.

.. warning::

This is documentation of a very low-level API, if you want to
handle keys or signatures you should look at documentation of
the :py:mod:`~ecdsa.keys` module.

Short Weierstrass curves
========================

There are two low-level implementations for
:term:`short Weierstrass curves <short Weierstrass curve>`:
:py:class:`~ecdsa.ellipticcurve.Point` and
:py:class:`~ecdsa.ellipticcurve.PointJacobi`.

Both of them use the curves specified using the
:py:class:`~ecdsa.ellipticcurve.CurveFp` object.

You can either provide your own curve parameters or use one of the predefined
curves.
For example, to define a curve :math:`x^2 = x^3 + x + 4 \text{ mod } 5` use
code like this:

.. code:: python
from ecdsa.ellipticcurve import CurveFp
custom_curve = CurveFp(5, 1, 4)
The predefined curves are specified in the :py:mod:`~ecdsa.ecdsa` module,
but it's much easier to use the helper functions (and proper names)
from the :py:mod:`~ecdsa.curves` module.

For example, to get the curve parameters for the NIST P-256 curve use this
code:

.. code:: python
from ecdsa.curves import NIST256p
curve = NIST256p.curve
.. tip::

You can also use :py:class:`~ecdsa.curves.Curve` to get the curve
parameters from a PEM or DER file. Or use the
:py:func:`~ecdsa.curves.find_curve` to get a curve by specifying its
ASN.1 object identifier (OID).

After taking hold of curve parameters you can create a point on the
curve. The :py:class:`~ecdsa.ellipticcurve.Point` uses affine coordinates,
i.e. the :math:`x` and :math:`y` from the curve equation directly.

To specify a point (1, 1) on the ``custom_curve`` you can use this code:

.. code:: python
from ecdsa.ellipticcurve import Point
point_a = Point(custom_curve, 1, 1)
Then it's possible to either perform scalar multiplication:

.. code:: python
point_b = point_a * 3
Or specify other points and perform addition:

.. code:: python
point_b = Point(custom_curve, 3, 2)
point_c = point_a + point_b
To get the affine coordinates of the point, call the ``x()`` and ``y()``
methods of the object:

.. code:: python
print("x: {0}, y: {1}".format(point_c.x(), point_c.y()))
When using the Jacobi coordinates, the point is defined by 3 integers,
which are related to the :math:`x` and :math:`y` in the following way:

.. math::
x = X/Z^2 \\
y = Y/Z^3
That means that if you have point in affine coordinates, it's possible
to convert them to Jacobi by simply assuming :math:`Z = 1`.

So the same points can be specified as so:

.. code:: python
from ecdsa.ellipticcurve import PointJacobi
point_a = PointJacobi(custom_curve, 1, 1, 1)
point_b = PointJacobi(custom_curve, 3, 2, 1)
.. note::

Unlike the :py:class:`~ecdsa.ellipticcurve.Point`, the
:py:class:`~ecdsa.ellipticcurve.PointJacobi` does **not** check if the
coordinates specify a valid point on the curve as that operation is
computationally expensive for Jacobi coordinates.
If you want to verify if they specify a valid
point, you need to convert the point to affine coordinates and use the
:py:meth:`~ecdsa.ellipticcurve.CurveFp.contains_point` method.

Then all the operations work exactly the same as with regular
:py:class:`~ecdsa.ellipticcurve.Point` implementation.
While it's not possible to get the internal :math:`X`, :math:`Y`, and :math:`Z`
coordinates, it's possible to get the affine projection just like with
the regular implementation:

.. code:: python
point_c = point_a + point_b
print("x: {0}, y: {1}".format(point_c.x(), point_c.y()))
4 changes: 4 additions & 0 deletions docs/source/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,7 @@ Glossary
set-like object
All the types that support the ``in`` operator, like ``list``,
``tuple``, ``set``, ``frozenset``, etc.

short Weierstrass curve
A curve with the curve equation: :math:`x^2=y^3+ax+b`. Most popular
curves use equation of this format (e.g. NIST256p).
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ curves over prime fields.

quickstart
basics
ec_arithmetic
glossary
modules

Expand Down
5 changes: 4 additions & 1 deletion src/ecdsa/ellipticcurve.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@

@python_2_unicode_compatible
class CurveFp(object):
"""Short Weierstrass Elliptic Curve over a prime field."""
"""
:term:`Short Weierstrass Elliptic Curve <short Weierstrass curve>` over a
prime field.
"""

if GMPY: # pragma: no branch

Expand Down

0 comments on commit ef53e9f

Please sign in to comment.