Skip to content

Commit 1c6a838

Browse files
committed
add description of low level elliptic curve operations
1 parent 3bb5305 commit 1c6a838

File tree

4 files changed

+134
-1
lines changed

4 files changed

+134
-1
lines changed

docs/source/ec_arithmetic.rst

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
=========================
2+
Elliptic Curve arithmetic
3+
=========================
4+
5+
The python-ecdsa also provides generic API for performing operations on
6+
elliptic curve points.
7+
8+
.. warning::
9+
10+
This is documentation of a very low-level API, if you want to
11+
handle keys or signatures you should look at documentation of
12+
the :py:mod:`~ecdsa.keys` module.
13+
14+
Short Weierstrass curves
15+
========================
16+
17+
There are two low-level implementations for
18+
:term:`short Weierstrass curves <short Weierstrass curve>`:
19+
:py:class:`~ecdsa.ellipticcurve.Point` and
20+
:py:class:`~ecdsa.ellipticcurve.PointJacobi`.
21+
22+
Both of them use the curves specified using the
23+
:py:class:`~ecdsa.ellipticcurve.CurveFp` object.
24+
25+
You can either provide your own curve parameters or use one of the predefined
26+
curves.
27+
For example, to define a curve :math:`x^2 = x^3 + x + 4 \text{ mod } 5` use
28+
code like this:
29+
30+
.. code:: python
31+
32+
from ecdsa.ellipticcurve import CurveFp
33+
custom_curve = CurveFp(5, 1, 4)
34+
35+
The predefined curves are specified in the :py:mod:`~ecdsa.ecdsa` module,
36+
but it's much easier to use the helper functions (and proper names)
37+
from the :py:mod:`~ecdsa.curves` module.
38+
39+
For example, to get the curve parameters for the NIST P-256 curve use this
40+
code:
41+
42+
.. code:: python
43+
44+
from ecdsa.curves import NIST256p
45+
curve = NIST256p.curve
46+
47+
.. tip::
48+
49+
You can also use :py:class:`~ecdsa.curves.Curve` to get the curve
50+
parameters from a PEM or DER file. Or use the
51+
:py:func:`~ecdsa.curves.find_curve` to get a curve by specifying its
52+
ASN.1 object identifier (OID).
53+
54+
After taking hold of curve parameters you can create a point on the
55+
curve. The :py:class:`~ecdsa.ellipticcurve.Point` uses affine coordinates,
56+
i.e. the :math:`x` and :math:`y` from the curve equation directly.
57+
58+
To specify a point (1, 1) on the ``custom_curve`` you can use this code:
59+
60+
.. code:: python
61+
62+
from ecdsa.ellipticcurve import Point
63+
point_a = Point(custom_curve, 1, 1)
64+
65+
Then it's possible to either perform scalar multiplication:
66+
67+
.. code:: python
68+
69+
point_b = point_a * 3
70+
71+
Or specify other points and perform addition:
72+
73+
.. code:: python
74+
75+
point_b = Point(custom_curve, 3, 2)
76+
point_c = point_a + point_b
77+
78+
To get the affine coordinates of the point, call the ``x()`` and ``y()``
79+
methods of the object:
80+
81+
.. code:: python
82+
83+
print("x: {0}, y: {1}".format(point_c.x(), point_c.y()))
84+
85+
86+
When using the Jacobi coordinates, the point is defined by 3 integers,
87+
which are related to the :math:`x` and :math:`y` in the following way:
88+
89+
.. math::
90+
91+
x = X/Z^2 \\
92+
y = Y/Z^3
93+
94+
That means that if you have point in affine coordinates, it's possible
95+
to convert them to Jacobi by simply assuming :math:`Z = 1`.
96+
97+
So the same points can be specified as so:
98+
99+
.. code:: python
100+
101+
from ecdsa.ellipticcurve import PointJacobi
102+
point_a = PointJacobi(custom_curve, 1, 1, 1)
103+
point_b = PointJacobi(custom_curve, 3, 2, 1)
104+
105+
106+
.. note::
107+
108+
Unlike the :py:class:`~ecdsa.ellipticcurve.Point`, the
109+
:py:class:`~ecdsa.ellipticcurve.PointJacobi` does **not** check if the
110+
coordinates specify a valid point on the curve as that operation is
111+
computationally expensive for Jacobi coordinates.
112+
If you want to verify if they specify a valid
113+
point, you need to convert the point to affine coordinates and use the
114+
:py:meth:`~ecdsa.ellipticcurve.CurveFp.contains_point` method.
115+
116+
Then all the operations work exactly the same as with regular
117+
:py:class:`~ecdsa.ellipticcurve.Point` implementation.
118+
While it's not possible to get the internal :math:`X`, :math:`Y`, and :math:`Z`
119+
coordinates, it's possible to get the affine projection just like with
120+
the regular implementation:
121+
122+
.. code:: python
123+
124+
point_c = point_a + point_b
125+
print("x: {0}, y: {1}".format(point_c.x(), point_c.y()))

docs/source/glossary.rst

+4
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,7 @@ Glossary
8686
set-like object
8787
All the types that support the ``in`` operator, like ``list``,
8888
``tuple``, ``set``, ``frozenset``, etc.
89+
90+
short Weierstrass curve
91+
A curve with the curve equation: :math:`x^2=y^3+ax+b`. Most popular
92+
curves use equation of this format (e.g. NIST256p).

docs/source/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ curves over prime fields.
4444

4545
quickstart
4646
basics
47+
ec_arithmetic
4748
glossary
4849
modules
4950

src/ecdsa/ellipticcurve.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@
5656

5757
@python_2_unicode_compatible
5858
class CurveFp(object):
59-
"""Short Weierstrass Elliptic Curve over a prime field."""
59+
"""
60+
:term:`Short Weierstrass Elliptic Curve <short Weierstrass curve>` over a
61+
prime field.
62+
"""
6063

6164
if GMPY: # pragma: no branch
6265

0 commit comments

Comments
 (0)