summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Kario <hubert@kario.pl>2022-04-03 20:04:21 +0200
committerHubert Kario <hkario@redhat.com>2022-07-08 14:30:24 +0200
commitf61435adad78ed72b2604d01de4808e8a097a27f (patch)
tree70b05f4defa4a5499470a5821cf4047db0a394a0
parentc6612ca422c80015237ae3a0fa238cedb1899a29 (diff)
downloadecdsa-f61435adad78ed72b2604d01de4808e8a097a27f.tar.gz
start basics and quickstart modules
-rw-r--r--docs/source/basics.rst99
-rw-r--r--docs/source/index.rst20
-rw-r--r--docs/source/quickstart.rst21
3 files changed, 139 insertions, 1 deletions
diff --git a/docs/source/basics.rst b/docs/source/basics.rst
new file mode 100644
index 0000000..5f10970
--- /dev/null
+++ b/docs/source/basics.rst
@@ -0,0 +1,99 @@
+==========
+ECC basics
+==========
+
+The :term:`ECC`, as any asymmetric cryptography system, deals with private
+keys and public keys. Private keys are generally used to create signatures,
+and are kept, as the name suggest, private. That's because possession of a
+private key allows creating a signature that can be verified with a public key.
+If the public key is associated with an identity (like a person or an
+institution), possession of the private key will allow to impersonate
+that identity.
+
+The public keys on the other hand are widely distributed, and they don't
+have to be kept private. The primary purpose of them, is to allow
+checking if a given signature was made with the associated private key.
+
+On a more low level, the private key is a single number, usually the
+size of the curve size: a NIST P-256 private key will have a size of 256 bits,
+though as it needs to be selected randomly, it may be a slightly smaller
+number (255-bit, 248-bit, etc.).
+Public points are a pair of numbers. That pair specifies a point on an
+elliptic curve (a pair of points that satisfy the curve equation).
+Those two numbers are similarly close in size to the curve size, so both the
+``x`` and ``y`` coordinate of a NIST P-256 curve will also be around 256 bit in
+size.
+
+.. note::
+ To be more precise, the size of the private key is related to the
+ curve *order*, i.e. the number of points on a curve. The coordinates
+ of the curve depend on the *field* of the curve, which usually means the
+ size of the *prime* used for operations on points. While the *order* and
+ the *prime* size are related and fairly close in size, it's possible
+ to have a curve where either of them is larger by a bit (i.e.
+ it's possible to have a curve that uses a 256 bit prime that has a 257 bit
+ order).
+
+Since normally computers work with much smaller numbers, like 32 bit or 64 bit,
+we need to use special approaches to represent numbers that are hundreds of
+bits large.
+
+First is to decide if the numbers should be stored in a big
+endian format, or in little endian format. In big endian, the most
+significant bits are stored first, so a number like :math:`2^{16}` is saved
+as a three of byes: byte with value 1 and two bytes with value 0.
+In little endian format the least significant bits are stored first, so
+the number like :math:`2^{16}` would be stored as three bytes:
+first two bytes with value 0, than a byte with value 1.
+
+For :term:`ECDSA` big endian encoding is usually used, for :term:`EdDSA`
+little endian encoding is usually used.
+
+Secondly, we need to decide if the numbers need to be stored as fixed length
+strings (zero padded if necessary), or if they should be stored with
+minimal number of bytes necessary.
+That depends on the format and place it's used, some require strict
+sizes (so even if the number encoded is 1, but the curve used is 128 bit large,
+that number 1 still needs to be encoded with 16 bytes, with fifteen most
+significant bytes equal zero).
+
+Generally, public keys (i.e. points) are expressed as fixed size byte strings.
+
+While public keys can be saved as two integers, one to represent the
+``x`` coordinate and one to represent ``y`` coordinate, that actually
+provides a lot of redundancy. Because of the specifics of elliptic curves,
+for every valid ``x`` value there are only two valid ``y`` values.
+Moreover, if you have an ``x`` values, you can compute those two possible
+``y`` values (if they exist).
+As such, it's possible to save just the ``x`` coordinate and the sign
+of the ``y`` coordinate (as the two possible values are negatives of
+each-other: :math:`y_1 == -y_2`).
+
+That gives us few options to represent the public point, the most common are:
+
+1. As a concatenation of two fixed-length big-endian integers, so called
+ :term:`raw encoding`.
+2. As a concatenation of two fixed-length big-endian integers prefixed with
+ the type of the encoding, so called :term:`uncompressed` point
+ representation (the type is represented by a 0x04 byte).
+3. As a fixed-length big-endian integer representing the ``x`` coordinate
+ prefixed with the byte representing the combined type of the encoding
+ and the sign of the ``y`` coordinate, so called :term:`compressed`
+ point representation.
+
+Now, while we can save the byte strings as-is and "remember" which curve
+was used to generate those private and public keys, interoperability usually
+requires us to also save information about the curve together with the
+corresponding key. Here too there are many ways to do it:
+save the parameters of the used curve explicitly, use the name of the
+well-known curve as a string, use a numerical identifier of the well-known
+curve, etc.
+
+For public keys the most interoperable format is the one described
+in RFC5912 (look for SubjectPublicKeyInfo structure).
+For private keys, the RFC5915 format (also known as the ssleay format)
+and the PKCS#8 format (described in RFC5958) are the most popular.
+All of those specify a binary encoding, called DER, which can use
+bytes with any values. For some uses it's useful to limit byte use
+to printable characters, then the PEM formatting of the DER-encoded data
+can be used.
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 8b1d2a1..6917a86 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -19,17 +19,35 @@ in
or
`SSH <https://en.wikipedia.org/wiki/Secure_Shell_Protocol>`_.
+This library provides key generation, signing, verifying, and shared secret
+derivation for five
+popular NIST "Suite B" GF(p) (*prime field*) curves, with key lengths of 192,
+224, 256, 384, and 521 bits. The "short names" for these curves, as known by
+the OpenSSL tool (``openssl ecparam -list_curves``), are: ``prime192v1``,
+``secp224r1``, ``prime256v1``, ``secp384r1``, and ``secp521r1``. It includes
+the
+256-bit curve ``secp256k1`` used by Bitcoin. There is also support for the
+regular (non-twisted) variants of Brainpool curves from 160 to 512 bits. The
+"short names" of those curves are: ``brainpoolP160r1``, ``brainpoolP192r1``,
+``brainpoolP224r1``, ``brainpoolP256r1``, ``brainpoolP320r1``,
+``brainpoolP384r1``,
+``brainpoolP512r1``. Few of the small curves from SEC standard are also
+included (mainly to speed-up testing of the library), those are:
+``secp112r1``, ``secp112r2``, ``secp128r1``, and ``secp160r1``.
+No other curves are included, but it is not too hard to add support for more
+curves over prime fields.
.. toctree::
:maxdepth: 2
:caption: Contents:
:hidden:
+ quickstart
+ basics
glossary
modules
-
Indices and tables
==================
diff --git a/docs/source/quickstart.rst b/docs/source/quickstart.rst
new file mode 100644
index 0000000..8ae2cee
--- /dev/null
+++ b/docs/source/quickstart.rst
@@ -0,0 +1,21 @@
+===============
+Getting started
+===============
+
+The library has just one mandatory dependency: ``six``.
+If you install ``python-ecdsa`` through pip, it should automatically
+install ``six`` too.
+
+The high level API provided by the library is primarily in the
+:py:class:`~ecdsa.keys` module.
+There you will find the :py:class:`~ecdsa.keys.SigningKey` (the class
+that enables handling of the private keys) and the
+:py:class:`~ecdsa.keys.VerifyingKey` (the class that enables handling of
+the public keys).
+
+To handle shared key derivation, the :py:class:`~ecdsa.ecdh.ECDH` class
+is used.
+
+Finally, in case use of custom elliptic curves is necessary, the
+:py:class:`~ecdsa.curves.Curve` class may be needed.
+