aboutsummaryrefslogtreecommitdiff
path: root/frozen_deps/Cryptodome/Signature
diff options
context:
space:
mode:
authorDeterminant <[email protected]>2022-11-17 18:08:59 -0800
committerDeterminant <[email protected]>2022-11-17 18:08:59 -0800
commit8154806fe2fccacdc3dafaa68181a07bcf8d6c4c (patch)
treef477e6a005599bb88c18db142c267b9297c6060b /frozen_deps/Cryptodome/Signature
parentbe4dc086591c9bced04a507d127c83811c5700c4 (diff)
v0.1.7
Diffstat (limited to 'frozen_deps/Cryptodome/Signature')
-rw-r--r--frozen_deps/Cryptodome/Signature/DSS.py158
-rw-r--r--frozen_deps/Cryptodome/Signature/__init__.py2
-rw-r--r--frozen_deps/Cryptodome/Signature/eddsa.py341
-rw-r--r--frozen_deps/Cryptodome/Signature/eddsa.pyi21
-rw-r--r--frozen_deps/Cryptodome/Signature/pkcs1_15.py2
5 files changed, 438 insertions, 86 deletions
diff --git a/frozen_deps/Cryptodome/Signature/DSS.py b/frozen_deps/Cryptodome/Signature/DSS.py
index 3dcbeb4..67f23ac 100644
--- a/frozen_deps/Cryptodome/Signature/DSS.py
+++ b/frozen_deps/Cryptodome/Signature/DSS.py
@@ -31,15 +31,15 @@
# POSSIBILITY OF SUCH DAMAGE.
# ===================================================================
-__all__ = ['new']
-
-
from Cryptodome.Util.asn1 import DerSequence
from Cryptodome.Util.number import long_to_bytes
from Cryptodome.Math.Numbers import Integer
from Cryptodome.Hash import HMAC
from Cryptodome.PublicKey.ECC import EccKey
+from Cryptodome.PublicKey.DSA import DsaKey
+
+__all__ = ['DssSigScheme', 'new']
class DssSigScheme(object):
@@ -75,24 +75,23 @@ class DssSigScheme(object):
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:`Cryptodome.Hash` package.
+ Under mode ``'fips-186-3'``, the hash must be a FIPS
+ approved secure hash (SHA-2 or SHA-3).
- 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
"""
+ if not self._key.has_private():
+ raise TypeError("Private key is needed to sign")
+
if not self._valid_hash(msg_hash):
raise ValueError("Hash is not sufficiently strong")
@@ -106,7 +105,7 @@ class DssSigScheme(object):
# 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,
@@ -123,20 +122,15 @@ class DssSigScheme(object):
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:`Cryptodome.Hash` module.
+ Under mode ``'fips-186-3'``, the hash must be a FIPS
+ approved secure hash (SHA-2 or SHA-3).
- 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
-
- :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
"""
@@ -294,85 +288,77 @@ class FipsEcDsaSigScheme(DssSigScheme):
randfunc=self._randfunc)
def _valid_hash(self, msg_hash):
- """Verify that SHA-[23] (256|384|512) bits are used to
- match the security of P-256 (128 bits), P-384 (192 bits)
- or P-521 (256 bits)"""
+ """Verify that the strength of the hash matches or exceeds
+ the strength of the EC. We fail if the hash is too weak."""
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")
-
- if msg_hash.oid in sha256:
- return modulus_bits <= 256
- elif msg_hash.oid in sha384:
- return modulus_bits <= 384
- else:
- return msg_hash.oid in sha512
+ # SHS: SHA-2, SHA-3, truncated SHA-512
+ sha224 = ("2.16.840.1.101.3.4.2.4", "2.16.840.1.101.3.4.2.7", "2.16.840.1.101.3.4.2.5")
+ sha256 = ("2.16.840.1.101.3.4.2.1", "2.16.840.1.101.3.4.2.8", "2.16.840.1.101.3.4.2.6")
+ 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")
+ shs = sha224 + sha256 + sha384 + sha512
+
+ try:
+ result = msg_hash.oid in shs
+ except AttributeError:
+ result = False
+ return result
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:`Cryptodome.PublicKey.DSA` or :class:`Cryptodome.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)
+ Args:
+ key (:class:`Cryptodome.PublicKey.DSA` or :class:`Cryptodome.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`_:
- For ECC, only keys over P-256, P384, and P-521 are accepted.
- :type key:
- a key object
+ - (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)
- :parameter mode:
- The parameter can take these values:
+ For ECC, only keys over P-224, P-256, P-384, and P-521 are accepted.
- - *'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
+ mode (string):
+ The parameter can take these values:
- :parameter encoding:
- How the signature is encoded. This value determines the output of
- :meth:`sign` and the input to :meth:`verify`.
+ - ``'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_.
- The following values are accepted:
+ encoding (string):
+ How the signature is encoded. This value determines the output of
+ :meth:`sign` and the input to :meth:`verify`.
- - *'binary'* (default), the signature is the raw concatenation
- of ``r`` and ``s``. It is defined in the IEEE P.1363 standard.
+ The following values are accepted:
- For DSA, the size in bytes of the signature is ``N/4`` bytes
- (e.g. 64 for ``N=256``).
+ - ``'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).
- 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.
- - *'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
+ 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
@@ -393,9 +379,13 @@ def new(key, mode, encoding='binary', randfunc=None):
if isinstance(key, EccKey):
order = key._curve.order
private_key_attr = 'd'
- else:
+ if key._curve.name == "ed25519":
+ raise ValueError("ECC key is not on a NIST P curve")
+ elif isinstance(key, DsaKey):
order = Integer(key.q)
private_key_attr = 'x'
+ else:
+ raise ValueError("Unsupported key type " + str(type(key)))
if key.has_private():
private_key = getattr(key, private_key_attr)
diff --git a/frozen_deps/Cryptodome/Signature/__init__.py b/frozen_deps/Cryptodome/Signature/__init__.py
index da028a5..11ca64c 100644
--- a/frozen_deps/Cryptodome/Signature/__init__.py
+++ b/frozen_deps/Cryptodome/Signature/__init__.py
@@ -33,4 +33,4 @@
A collection of standardized protocols to carry out digital signatures.
"""
-__all__ = ['PKCS1_v1_5', 'PKCS1_PSS', 'DSS', 'pkcs1_15', 'pss']
+__all__ = ['PKCS1_v1_5', 'PKCS1_PSS', 'DSS', 'pkcs1_15', 'pss', 'eddsa']
diff --git a/frozen_deps/Cryptodome/Signature/eddsa.py b/frozen_deps/Cryptodome/Signature/eddsa.py
new file mode 100644
index 0000000..e80a866
--- /dev/null
+++ b/frozen_deps/Cryptodome/Signature/eddsa.py
@@ -0,0 +1,341 @@
+# ===================================================================
+#
+# Copyright (c) 2022, Legrandin <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ===================================================================
+
+from Cryptodome.Math.Numbers import Integer
+
+from Cryptodome.Hash import SHA512, SHAKE256
+from Cryptodome.Util.py3compat import bchr, is_bytes
+from Cryptodome.PublicKey.ECC import (EccKey,
+ construct,
+ _import_ed25519_public_key,
+ _import_ed448_public_key)
+
+
+def import_public_key(encoded):
+ """Import an EdDSA ECC public key, when encoded as raw ``bytes`` as described
+ in RFC8032.
+
+ Args:
+ encoded (bytes):
+ The EdDSA public key to import.
+ It must be 32 bytes for Ed25519, and 57 bytes for Ed448.
+
+ Returns:
+ :class:`Cryptodome.PublicKey.EccKey` : a new ECC key object.
+
+ Raises:
+ ValueError: when the given key cannot be parsed.
+ """
+
+ if len(encoded) == 32:
+ x, y = _import_ed25519_public_key(encoded)
+ curve_name = "Ed25519"
+ elif len(encoded) == 57:
+ x, y = _import_ed448_public_key(encoded)
+ curve_name = "Ed448"
+ else:
+ raise ValueError("Not an EdDSA key (%d bytes)" % len(encoded))
+ return construct(curve=curve_name, point_x=x, point_y=y)
+
+
+def import_private_key(encoded):
+ """Import an EdDSA ECC private key, when encoded as raw ``bytes`` as described
+ in RFC8032.
+
+ Args:
+ encoded (bytes):
+ The EdDSA private key to import.
+ It must be 32 bytes for Ed25519, and 57 bytes for Ed448.
+
+ Returns:
+ :class:`Cryptodome.PublicKey.EccKey` : a new ECC key object.
+
+ Raises:
+ ValueError: when the given key cannot be parsed.
+ """
+
+ if len(encoded) == 32:
+ curve_name = "ed25519"
+ elif len(encoded) == 57:
+ curve_name = "ed448"
+ else:
+ raise ValueError("Incorrect length. Only EdDSA private keys are supported.")
+
+ # Note that the private key is truly a sequence of random bytes,
+ # so we cannot check its correctness in any way.
+
+ return construct(seed=encoded, curve=curve_name)
+
+
+class EdDSASigScheme(object):
+ """An EdDSA signature object.
+ Do not instantiate directly.
+ Use :func:`Cryptodome.Signature.eddsa.new`.
+ """
+
+ def __init__(self, key, context):
+ """Create a new EdDSA object.
+
+ Do not instantiate this object directly,
+ use `Cryptodome.Signature.DSS.new` instead.
+ """
+
+ self._key = key
+ self._context = context
+ self._A = key._export_eddsa()
+ self._order = key._curve.order
+
+ def can_sign(self):
+ """Return ``True`` if this signature object can be used
+ for signing messages."""
+
+ return self._key.has_private()
+
+ def sign(self, msg_or_hash):
+ """Compute the EdDSA signature of a message.
+
+ Args:
+ msg_or_hash (bytes or a hash object):
+ The message to sign (``bytes``, in case of *PureEdDSA*) or
+ the hash that was carried out over the message (hash object, for *HashEdDSA*).
+
+ The hash object must be :class:`Cryptodome.Hash.SHA512` for Ed25519,
+ and :class:`Cryptodome.Hash.SHAKE256` object for Ed448.
+
+ :return: The signature as ``bytes``. It is always 64 bytes for Ed25519, and 114 bytes for Ed448.
+ :raise TypeError: if the EdDSA key has no private half
+ """
+
+ if not self._key.has_private():
+ raise TypeError("Private key is needed to sign")
+
+ if self._key._curve.name == "ed25519":
+ ph = isinstance(msg_or_hash, SHA512.SHA512Hash)
+ if not (ph or is_bytes(msg_or_hash)):
+ raise TypeError("'msg_or_hash' must be bytes of a SHA-512 hash")
+ eddsa_sign_method = self._sign_ed25519
+
+ elif self._key._curve.name == "ed448":
+ ph = isinstance(msg_or_hash, SHAKE256.SHAKE256_XOF)
+ if not (ph or is_bytes(msg_or_hash)):
+ raise TypeError("'msg_or_hash' must be bytes of a SHAKE256 hash")
+ eddsa_sign_method = self._sign_ed448
+
+ else:
+ raise ValueError("Incorrect curve for EdDSA")
+
+ return eddsa_sign_method(msg_or_hash, ph)
+
+ def _sign_ed25519(self, msg_or_hash, ph):
+
+ if self._context or ph:
+ flag = int(ph)
+ # dom2(flag, self._context)
+ dom2 = b'SigEd25519 no Ed25519 collisions' + bchr(flag) + \
+ bchr(len(self._context)) + self._context
+ else:
+ dom2 = b''
+
+ PHM = msg_or_hash.digest() if ph else msg_or_hash
+
+ # See RFC 8032, section 5.1.6
+
+ # Step 2
+ r_hash = SHA512.new(dom2 + self._key._prefix + PHM).digest()
+ r = Integer.from_bytes(r_hash, 'little') % self._order
+ # Step 3
+ R_pk = EccKey(point=r * self._key._curve.G)._export_eddsa()
+ # Step 4
+ k_hash = SHA512.new(dom2 + R_pk + self._A + PHM).digest()
+ k = Integer.from_bytes(k_hash, 'little') % self._order
+ # Step 5
+ s = (r + k * self._key.d) % self._order
+
+ return R_pk + s.to_bytes(32, 'little')
+
+ def _sign_ed448(self, msg_or_hash, ph):
+
+ flag = int(ph)
+ # dom4(flag, self._context)
+ dom4 = b'SigEd448' + bchr(flag) + \
+ bchr(len(self._context)) + self._context
+
+ PHM = msg_or_hash.read(64) if ph else msg_or_hash
+
+ # See RFC 8032, section 5.2.6
+
+ # Step 2
+ r_hash = SHAKE256.new(dom4 + self._key._prefix + PHM).read(114)
+ r = Integer.from_bytes(r_hash, 'little') % self._order
+ # Step 3
+ R_pk = EccKey(point=r * self._key._curve.G)._export_eddsa()
+ # Step 4
+ k_hash = SHAKE256.new(dom4 + R_pk + self._A + PHM).read(114)
+ k = Integer.from_bytes(k_hash, 'little') % self._order
+ # Step 5
+ s = (r + k * self._key.d) % self._order
+
+ return R_pk + s.to_bytes(57, 'little')
+
+ def verify(self, msg_or_hash, signature):
+ """Check if an EdDSA signature is authentic.
+
+ Args:
+ msg_or_hash (bytes or a hash object):
+ The message to verify (``bytes``, in case of *PureEdDSA*) or
+ the hash that was carried out over the message (hash object, for *HashEdDSA*).
+
+ The hash object must be :class:`Cryptodome.Hash.SHA512` object for Ed25519,
+ and :class:`Cryptodome.Hash.SHAKE256` for Ed448.
+
+ signature (``bytes``):
+ The signature that needs to be validated.
+ It must be 64 bytes for Ed25519, and 114 bytes for Ed448.
+
+ :raise ValueError: if the signature is not authentic
+ """
+
+ if self._key._curve.name == "ed25519":
+ ph = isinstance(msg_or_hash, SHA512.SHA512Hash)
+ if not (ph or is_bytes(msg_or_hash)):
+ raise TypeError("'msg_or_hash' must be bytes of a SHA-512 hash")
+ eddsa_verify_method = self._verify_ed25519
+
+ elif self._key._curve.name == "ed448":
+ ph = isinstance(msg_or_hash, SHAKE256.SHAKE256_XOF)
+ if not (ph or is_bytes(msg_or_hash)):
+ raise TypeError("'msg_or_hash' must be bytes of a SHAKE256 hash")
+ eddsa_verify_method = self._verify_ed448
+
+ else:
+ raise ValueError("Incorrect curve for EdDSA")
+
+ return eddsa_verify_method(msg_or_hash, signature, ph)
+
+ def _verify_ed25519(self, msg_or_hash, signature, ph):
+
+ if len(signature) != 64:
+ raise ValueError("The signature is not authentic (length)")
+
+ if self._context or ph:
+ flag = int(ph)
+ dom2 = b'SigEd25519 no Ed25519 collisions' + bchr(flag) + \
+ bchr(len(self._context)) + self._context
+ else:
+ dom2 = b''
+
+ PHM = msg_or_hash.digest() if ph else msg_or_hash
+
+ # Section 5.1.7
+
+ # Step 1
+ try:
+ R = import_public_key(signature[:32]).pointQ
+ except ValueError:
+ raise ValueError("The signature is not authentic (R)")
+ s = Integer.from_bytes(signature[32:], 'little')
+ if s > self._order:
+ raise ValueError("The signature is not authentic (S)")
+ # Step 2
+ k_hash = SHA512.new(dom2 + signature[:32] + self._A + PHM).digest()
+ k = Integer.from_bytes(k_hash, 'little') % self._order
+ # Step 3
+ point1 = s * 8 * self._key._curve.G
+ # OPTIMIZE: with double-scalar multiplication, with no SCA
+ # countermeasures because it is public values
+ point2 = 8 * R + k * 8 * self._key.pointQ
+ if point1 != point2:
+ raise ValueError("The signature is not authentic")
+
+ def _verify_ed448(self, msg_or_hash, signature, ph):
+
+ if len(signature) != 114:
+ raise ValueError("The signature is not authentic (length)")
+
+ flag = int(ph)
+ # dom4(flag, self._context)
+ dom4 = b'SigEd448' + bchr(flag) + \
+ bchr(len(self._context)) + self._context
+
+ PHM = msg_or_hash.read(64) if ph else msg_or_hash
+
+ # Section 5.2.7
+
+ # Step 1
+ try:
+ R = import_public_key(signature[:57]).pointQ
+ except ValueError:
+ raise ValueError("The signature is not authentic (R)")
+ s = Integer.from_bytes(signature[57:], 'little')
+ if s > self._order:
+ raise ValueError("The signature is not authentic (S)")
+ # Step 2
+ k_hash = SHAKE256.new(dom4 + signature[:57] + self._A + PHM).read(114)
+ k = Integer.from_bytes(k_hash, 'little') % self._order
+ # Step 3
+ point1 = s * 8 * self._key._curve.G
+ # OPTIMIZE: with double-scalar multiplication, with no SCA
+ # countermeasures because it is public values
+ point2 = 8 * R + k * 8 * self._key.pointQ
+ if point1 != point2:
+ raise ValueError("The signature is not authentic")
+
+
+def new(key, mode, context=None):
+ """Create a signature object :class:`EdDSASigScheme` that
+ can perform or verify an EdDSA signature.
+
+ Args:
+ key (:class:`Cryptodome.PublicKey.ECC` object:
+ The key to use for computing the signature (*private* keys only)
+ or for verifying one.
+ The key must be on the curve ``Ed25519`` or ``Ed448``.
+
+ mode (string):
+ This parameter must be ``'rfc8032'``.
+
+ context (bytes):
+ Up to 255 bytes of `context <https://datatracker.ietf.org/doc/html/rfc8032#page-41>`_,
+ which is a constant byte string to segregate different protocols or
+ different applications of the same key.
+ """
+
+ if not isinstance(key, EccKey) or not key._is_eddsa():
+ raise ValueError("EdDSA can only be used with EdDSA keys")
+
+ if mode != 'rfc8032':
+ raise ValueError("Mode must be 'rfc8032'")
+
+ if context is None:
+ context = b''
+ elif len(context) > 255:
+ raise ValueError("Context for EdDSA must not be longer than 255 bytes")
+
+ return EdDSASigScheme(key, context)
diff --git a/frozen_deps/Cryptodome/Signature/eddsa.pyi b/frozen_deps/Cryptodome/Signature/eddsa.pyi
new file mode 100644
index 0000000..bf985c4
--- /dev/null
+++ b/frozen_deps/Cryptodome/Signature/eddsa.pyi
@@ -0,0 +1,21 @@
+from typing import Union, Optional
+from typing_extensions import Protocol
+from Cryptodome.PublicKey.ECC import EccKey
+
+class Hash(Protocol):
+ def digest(self) -> bytes: ...
+
+class XOF(Protocol):
+ def read(self, len: int) -> bytes: ...
+
+def import_public_key(encoded: bytes) -> EccKey: ...
+def import_private_key(encoded: bytes) -> EccKey: ...
+
+class EdDSASigScheme(object):
+
+ def __init__(self, key: EccKey, context: bytes) -> None: ...
+ def can_sign(self) -> bool: ...
+ def sign(self, msg_or_hash: Union[bytes, Hash, XOF]) -> bytes: ...
+ def verify(self, msg_or_hash: Union[bytes, Hash, XOF], signature: bytes) -> None: ...
+
+def new(key: EccKey, mode: bytes, context: Optional[bytes]=None) -> EdDSASigScheme: ...
diff --git a/frozen_deps/Cryptodome/Signature/pkcs1_15.py b/frozen_deps/Cryptodome/Signature/pkcs1_15.py
index f572f85..ae9257e 100644
--- a/frozen_deps/Cryptodome/Signature/pkcs1_15.py
+++ b/frozen_deps/Cryptodome/Signature/pkcs1_15.py
@@ -202,7 +202,7 @@ def _EMSA_PKCS1_V1_5_ENCODE(msg_hash, emLen, with_hash_parameters=True):
# We need at least 11 bytes for the remaining data: 3 fixed bytes and
# at least 8 bytes of padding).
if emLen<len(digestInfo)+11:
- raise TypeError("Selected hash algorith has a too long digest (%d bytes)." % len(digest))
+ raise TypeError("Selected hash algorithm has a too long digest (%d bytes)." % len(digest))
PS = b'\xFF' * (emLen - len(digestInfo) - 3)
return b'\x00\x01' + PS + b'\x00' + digestInfo