diff options
author | Hubert Kario <hubert@kario.pl> | 2022-04-03 20:04:21 +0200 |
---|---|---|
committer | Hubert Kario <hkario@redhat.com> | 2022-07-08 14:30:24 +0200 |
commit | f61435adad78ed72b2604d01de4808e8a097a27f (patch) | |
tree | 70b05f4defa4a5499470a5821cf4047db0a394a0 | |
parent | c6612ca422c80015237ae3a0fa238cedb1899a29 (diff) | |
download | ecdsa-f61435adad78ed72b2604d01de4808e8a097a27f.tar.gz |
start basics and quickstart modules
-rw-r--r-- | docs/source/basics.rst | 99 | ||||
-rw-r--r-- | docs/source/index.rst | 20 | ||||
-rw-r--r-- | docs/source/quickstart.rst | 21 |
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. + |