Skip to content

Commit

Permalink
Update to ECDSA docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Legrandin committed Jan 20, 2022
1 parent b1cac0e commit fb31be7
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 84 deletions.
7 changes: 7 additions & 0 deletions Changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=========

In progress
++++++++++++++++++++++++++

Resolved issues
---------------
* GH#590: Fixed typing info for ``Crypto.PublicKey.ECC``.

3.12.0 (4 December 2021)
++++++++++++++++++++++++++

Expand Down
7 changes: 4 additions & 3 deletions Doc/src/signature/dsa.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
Digital Signature Algorithm (DSA and ECDSA)
===========================================

A variant of the ElGamal signature, specified in `FIPS PUB 186-4`__.
DSA and ECDSA are U.S. federal standards for digital signatures, specified in `FIPS PUB 186-4`__.

It is based on the discrete logarithm problem in a prime finite field (DSA) or
in an elliptic curve field (ECDSA).
Their security relies on the discrete logarithm problem in a prime finite field (the original DSA,
now deprecated) or in an elliptic curve field (ECDSA, faster and with smaller keys,
to be used in new applications).

A sender can use a *private* key (loaded from a file) to sign a message::

Expand Down
149 changes: 68 additions & 81 deletions lib/Crypto/Signature/DSS.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@
# POSSIBILITY OF SUCH DAMAGE.
# ===================================================================

__all__ = ['new']


from Crypto.Util.asn1 import DerSequence
from Crypto.Util.number import long_to_bytes
from Crypto.Math.Numbers import Integer
Expand All @@ -42,6 +39,8 @@
from Crypto.PublicKey.ECC import EccKey
from Crypto.PublicKey.DSA import DsaKey

__all__ = ['DssSigScheme', 'new']


class DssSigScheme(object):
"""A (EC)DSA signature object.
Expand Down Expand Up @@ -76,20 +75,19 @@ def _valid_hash(self, msg_hash):
raise NotImplementedError("To be provided by subclasses")

def sign(self, msg_hash):
"""Produce the DSA/ECDSA signature of a message.
"""Compute the DSA/ECDSA signature of a message.
:parameter msg_hash:
Args:
msg_hash (hash object):
The hash that was carried out over the message.
The object belongs to the :mod:`Crypto.Hash` package.
Under mode ``'fips-186-3'``, the hash must be a FIPS
approved secure hash (SHA-1 or a member of the SHA-2/SHA-3 families),
of cryptographic strength appropriate for the (EC)DSA key.
For instance, a P-521 ECC key can only be used
in combination with SHA2-512.
Under mode *'fips-186-3'*, the hash must be a FIPS
approved secure hash (SHA-1 or a member of the SHA-2 family),
of cryptographic strength appropriate for the DSA key.
For instance, a 3072/256 DSA key can only be used
in combination with SHA-512.
:type msg_hash: hash object
:return: The signature as a *byte string*
:return: The signature as ``bytes``
:raise ValueError: if the hash algorithm is incompatible to the (EC)DSA key
:raise TypeError: if the (EC)DSA key has no private half
"""
Expand All @@ -107,7 +105,7 @@ def sign(self, msg_hash):
# Encode the signature into a single byte string
if self._encoding == 'binary':
output = b"".join([long_to_bytes(x, self._order_bytes)
for x in sig_pair])
for x in sig_pair])
else:
# Dss-sig ::= SEQUENCE {
# r INTEGER,
Expand All @@ -124,20 +122,18 @@ def sign(self, msg_hash):
def verify(self, msg_hash, signature):
"""Check if a certain (EC)DSA signature is authentic.
:parameter msg_hash:
Args:
msg_hash (hash object):
The hash that was carried out over the message.
This is an object belonging to the :mod:`Crypto.Hash` module.
Under mode *'fips-186-3'*, the hash must be a FIPS
Under mode ``'fips-186-3'``, the hash must be a FIPS
approved secure hash (SHA-1 or a member of the SHA-2 family),
of cryptographic strength appropriate for the DSA key.
For instance, a 3072/256 DSA key can only be used in
combination with SHA-512.
:type msg_hash: hash object
of cryptographic strength appropriate for the (EC)DSA key.
For instance, a P-521 ECC key can only be used
in combination with SHA2-512.
:parameter signature:
The signature that needs to be validated
:type signature: byte string
signature (``bytes``):
The signature that needs to be validated.
:raise ValueError: if the signature is not authentic
"""
Expand Down Expand Up @@ -301,9 +297,9 @@ def _valid_hash(self, msg_hash):

modulus_bits = self._key.pointQ.size_in_bits()

sha256 = ( "2.16.840.1.101.3.4.2.1", "2.16.840.1.101.3.4.2.8" )
sha384 = ( "2.16.840.1.101.3.4.2.2", "2.16.840.1.101.3.4.2.9" )
sha512 = ( "2.16.840.1.101.3.4.2.3", "2.16.840.1.101.3.4.2.10")
sha256 = ("2.16.840.1.101.3.4.2.1", "2.16.840.1.101.3.4.2.8")
sha384 = ("2.16.840.1.101.3.4.2.2", "2.16.840.1.101.3.4.2.9")
sha512 = ("2.16.840.1.101.3.4.2.3", "2.16.840.1.101.3.4.2.10")

if msg_hash.oid in sha256:
return modulus_bits <= 256
Expand All @@ -314,66 +310,57 @@ def _valid_hash(self, msg_hash):


def new(key, mode, encoding='binary', randfunc=None):
"""Create a signature object :class:`DSS_SigScheme` that
"""Create a signature object :class:`DssSigScheme` that
can perform (EC)DSA signature or verification.
.. note::
Refer to `NIST SP 800 Part 1 Rev 4`_ (or newer release) for an
overview of the recommended key lengths.
:parameter key:
The key to use for computing the signature (*private* keys only)
or verifying one: it must be either
:class:`Crypto.PublicKey.DSA` or :class:`Crypto.PublicKey.ECC`.
For DSA keys, let ``L`` and ``N`` be the bit lengths of the modulus ``p``
and of ``q``: the pair ``(L,N)`` must appear in the following list,
in compliance to section 4.2 of `FIPS 186-4`_:
- (1024, 160) *legacy only; do not create new signatures with this*
- (2048, 224) *deprecated; do not create new signatures with this*
- (2048, 256)
- (3072, 256)
For ECC, only keys over P-256, P384, and P-521 are accepted.
:type key:
a key object
:parameter mode:
The parameter can take these values:
- *'fips-186-3'*. The signature generation is randomized and carried out
according to `FIPS 186-3`_: the nonce ``k`` is taken from the RNG.
- *'deterministic-rfc6979'*. The signature generation is not
randomized. See RFC6979_.
:type mode:
string
:parameter encoding:
How the signature is encoded. This value determines the output of
:meth:`sign` and the input to :meth:`verify`.
The following values are accepted:
- *'binary'* (default), the signature is the raw concatenation
of ``r`` and ``s``. It is defined in the IEEE P.1363 standard.
For DSA, the size in bytes of the signature is ``N/4`` bytes
(e.g. 64 for ``N=256``).
For ECDSA, the signature is always twice the length of a point
coordinate (e.g. 64 bytes for P-256).
- *'der'*, the signature is a ASN.1 DER SEQUENCE
with two INTEGERs (``r`` and ``s``). It is defined in RFC3279_.
The size of the signature is variable.
:type encoding: string
:parameter randfunc:
A function that returns random *byte strings*, of a given length.
If omitted, the internal RNG is used.
Only applicable for the *'fips-186-3'* mode.
:type randfunc: callable
Args:
key (:class:`Crypto.PublicKey.DSA` or :class:`Crypto.PublicKey.ECC`):
The key to use for computing the signature (*private* keys only)
or for verifying one.
For DSA keys, let ``L`` and ``N`` be the bit lengths of the modulus ``p``
and of ``q``: the pair ``(L,N)`` must appear in the following list,
in compliance to section 4.2 of `FIPS 186-4`_:
- (1024, 160) *legacy only; do not create new signatures with this*
- (2048, 224) *deprecated; do not create new signatures with this*
- (2048, 256)
- (3072, 256)
For ECC, only keys over P-256, P-384, and P-521 are accepted.
mode (string):
The parameter can take these values:
- ``'fips-186-3'``. The signature generation is randomized and carried out
according to `FIPS 186-3`_: the nonce ``k`` is taken from the RNG.
- ``'deterministic-rfc6979'``. The signature generation is not
randomized. See RFC6979_.
encoding (string):
How the signature is encoded. This value determines the output of
:meth:`sign` and the input to :meth:`verify`.
The following values are accepted:
- ``'binary'`` (default), the signature is the raw concatenation
of ``r`` and ``s``. It is defined in the IEEE P.1363 standard.
For DSA, the size in bytes of the signature is ``N/4`` bytes
(e.g. 64 for ``N=256``).
For ECDSA, the signature is always twice the length of a point
coordinate (e.g. 64 bytes for P-256).
- ``'der'``, the signature is a ASN.1 DER SEQUENCE
with two INTEGERs (``r`` and ``s``). It is defined in RFC3279_.
The size of the signature is variable.
randfunc (callable):
A function that returns random ``bytes``, of a given length.
If omitted, the internal RNG is used.
Only applicable for the *'fips-186-3'* mode.
.. _FIPS 186-3: http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
.. _FIPS 186-4: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
Expand Down

0 comments on commit fb31be7

Please sign in to comment.