summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Kario <hkario@redhat.com>2022-04-20 17:48:52 +0200
committerHubert Kario <hkario@redhat.com>2022-07-08 14:30:24 +0200
commit3a85d220cc460534326b2e50f6213af4bd16ee4d (patch)
treeae452e569b620caafca910915b47bbeee992bda8
parent4ae9955be3ce5596d1a30d21a340152a692fd449 (diff)
downloadecdsa-3a85d220cc460534326b2e50f6213af4bd16ee4d.tar.gz
add description of low level elliptic curve operations
-rw-r--r--docs/source/ec_arithmetic.rst125
-rw-r--r--docs/source/glossary.rst4
-rw-r--r--docs/source/index.rst1
-rw-r--r--src/ecdsa/ellipticcurve.py5
4 files changed, 134 insertions, 1 deletions
diff --git a/docs/source/ec_arithmetic.rst b/docs/source/ec_arithmetic.rst
new file mode 100644
index 0000000..b7abaaf
--- /dev/null
+++ b/docs/source/ec_arithmetic.rst
@@ -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()))
diff --git a/docs/source/glossary.rst b/docs/source/glossary.rst
index cbeede8..5486673 100644
--- a/docs/source/glossary.rst
+++ b/docs/source/glossary.rst
@@ -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).
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 6917a86..f69893f 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -44,6 +44,7 @@ curves over prime fields.
quickstart
basics
+ ec_arithmetic
glossary
modules
diff --git a/src/ecdsa/ellipticcurve.py b/src/ecdsa/ellipticcurve.py
index f358fbd..d6f7146 100644
--- a/src/ecdsa/ellipticcurve.py
+++ b/src/ecdsa/ellipticcurve.py
@@ -56,7 +56,10 @@ from .util import orderlen, string_to_number, number_to_string
@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