Skip to content

Commit

Permalink
Merge branch 'x25519_curve25519'
Browse files Browse the repository at this point in the history
  • Loading branch information
Legrandin committed Jun 24, 2024
2 parents 39b5a62 + fe83288 commit 70a6d9d
Show file tree
Hide file tree
Showing 48 changed files with 29,127 additions and 266 deletions.
1 change: 1 addition & 0 deletions Changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Under development
* Remove support for Python 3.5
* GH#814: RSA keys for PSS can be imported.
* GH#810: fixed negation of Ed25519 points
* Add support for Curve25519 / X25519

3.20.0 (9 January 2024)
++++++++++++++++++++++++++
Expand Down
6 changes: 5 additions & 1 deletion Doc/src/public_key/ecc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,22 @@ You can also export the public key, which is not sensitive::
"NIST P-521", "``'NIST P-521'``, ``'p521'``, ``'P-521'``, ``'prime521v1'``, ``'secp521r1'``"
"Ed25519", "``'ed25519'``, ``'Ed25519'``"
"Ed448", "``'ed448'``, ``'Ed448'``"
"Curve25519", "``'curve25519'``, ``'Curve25519'``"

For more information about each NIST curve see `FIPS 186-4`_, Section D.1.2.

The Ed25519 and the Ed448 curves are defined in RFC8032_.

The ECC key can be used to perform or verify signatures, using the modules
The Curve25519 curve is defined in RFC7748_.

The ECC keys can be used to perform or verify signatures, using the modules
:mod:`Crypto.Signature.DSS` (ECDSA; NIST curves only)
or :mod:`Crypto.Signature.eddsa` (EdDSA; Ed25519 and Ed448 curve only).

.. _ECC: http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/
.. _`FIPS 186-4`: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
.. _RFC8032: https://datatracker.ietf.org/doc/html/rfc8032
.. _RFC7748: https://datatracker.ietf.org/doc/html/rfc7748

.. automodule:: Crypto.PublicKey.ECC
:members:
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ with respect to the last official version of PyCrypto (2.6.1):
* Authenticated encryption modes (GCM, CCM, EAX, SIV, OCB)
* Accelerated AES on Intel platforms via AES-NI
* First class support for PyPy
* Elliptic curves cryptography (NIST P-curves; Ed25519, Ed448)
* Elliptic curves cryptography (NIST P-curves; Ed25519, Ed448, Curve25519)
* Better and more compact API (`nonce` and `iv` attributes for ciphers,
automatic generation of random nonces and IVs, simplified CTR cipher mode,
and more)
Expand Down
55 changes: 51 additions & 4 deletions lib/Crypto/Protocol/DH.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,63 @@
from Crypto.Util.number import long_to_bytes
from Crypto.PublicKey.ECC import EccKey
from Crypto.PublicKey.ECC import (EccKey,
construct,
_import_curve25519_public_key)


def _compute_ecdh(key_priv, key_pub):
# See Section 5.7.1.2 in NIST SP 800-56Ar3
pointP = key_pub.pointQ * key_priv.d
if pointP.is_point_at_infinity():
raise ValueError("Invalid ECDH point")
z = long_to_bytes(pointP.x, pointP.size_in_bytes())
raise ValueError("Invalid ECDH point")

if key_priv.curve == "Curve25519":
z = bytearray(pointP.x.to_bytes(32, byteorder='little'))
else:
# See Section 5.7.1.2 in NIST SP 800-56Ar3
z = long_to_bytes(pointP.x, pointP.size_in_bytes())
return z


def import_x25519_public_key(encoded):
"""Create a new X25519 public key object,
starting from the key encoded as raw ``bytes``,
in the format described in RFC7748.
Args:
encoded (bytes):
The x25519 public key to import.
It must be 32 bytes.
Returns:
:class:`Crypto.PublicKey.EccKey` : a new ECC key object.
Raises:
ValueError: when the given key cannot be parsed.
"""

x = _import_curve25519_public_key(encoded)
return construct(curve='Curve25519', point_x=x)


def import_x25519_private_key(encoded):
"""Create a new X25519 private key object,
starting from the key encoded as raw ``bytes``,
in the format described in RFC7748.
Args:
encoded (bytes):
The X25519 private key to import.
It must be 32 bytes.
Returns:
:class:`Crypto.PublicKey.EccKey` : a new ECC key object.
Raises:
ValueError: when the given key cannot be parsed.
"""

return construct(seed=encoded, curve="Curve25519")


def key_agreement(**kwargs):
"""Perform a Diffie-Hellman key agreement.
Expand Down
2 changes: 2 additions & 0 deletions lib/Crypto/Protocol/DH.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ class RequestParams(TypedDict, Generic[T]):
eph_priv: NotRequired[EccKey]
eph_pub: NotRequired[EccKey]

def import_x25519_public_key(encoded: bytes) -> EccKey: ...
def import_x25519_private_key(encoded: bytes) -> EccKey: ...
def key_agreement(**kwargs: Unpack[RequestParams[T]]) -> T: ...
Loading

0 comments on commit 70a6d9d

Please sign in to comment.