Skip to content

Commit

Permalink
Merge branch 'Legrandin:master' into resolve_redundantAssignment
Browse files Browse the repository at this point in the history
  • Loading branch information
vil02 authored Oct 26, 2024
2 parents 360d046 + dc92e70 commit 1c46bce
Show file tree
Hide file tree
Showing 14 changed files with 26,925 additions and 23 deletions.
15 changes: 8 additions & 7 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, windows-latest, macos-12]
os: [ubuntu-20.04, windows-2019, macos-12]

if: github.actor == 'Legrandin'

Expand All @@ -44,16 +44,17 @@ jobs:
echo 'CIBW_ARCHS=x86_64 universal2' >> $GITHUB_ENV
if: runner.os == 'macOS'

- uses: pypa/cibuildwheel@v2.15.0
- uses: pypa/cibuildwheel@v2.21.1
name: Build wheels
env:
# cibuildwheel will build wheel once and test it for each CPython version
# and for PyPy > 3.8.
CIBW_BUILD: "cp36-* cp37-* cp38-* cp39-* cp310-* cp311-* cp312-* pp39-* pp310-*"
CIBW_BUILD: "cp36-* cp37-* cp38-* cp39-* cp310-* cp311-* cp312-* cp313-* pp39-* pp310-*"
CIBW_MANYLINUX_X86_64_IMAGE: "manylinux2014"
CIBW_MANYLINUX_I686_IMAGE: "manylinux2014"
CIBW_MANYLINUX_PYPY_X86_64_IMAGE: "manylinux2014"
CIBW_MANYLINUX_PYPY_I686_IMAGE: "manylinux2014"
CIBW_FREE_THREADED_SUPPORT: "true"
CIBW_BEFORE_TEST_LINUX: "(ldd /bin/ls | grep -q musl && apk add gmp) || true"

# Set pycryptodome/x test command according to built package
Expand All @@ -78,16 +79,16 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-20.04, windows-latest, macos-12 ]
os: [ ubuntu-20.04, windows-2019, macos-12 ]
arch: [ multi-arch ]
# Python 2 on Windows requires manual toolchain setup (per-arch) due to newer MSVC used here
exclude:
- os: windows-latest
- os: windows-2019
arch: multi-arch
include:
- os: windows-latest
- os: windows-2019
arch: x86
- os: windows-latest
- os: windows-2019
arch: x64

if: github.actor == 'Legrandin'
Expand Down
21 changes: 15 additions & 6 deletions Changelog.rst
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
Changelog
=========

Under development
3.21.0 (30 September 2024)
++++++++++++++++++++++++++

New features
---------------
* By setting the PYCRYPTODOME_DISABLE_GMP environment variable,
the GMP library will not be used even if detected.
* 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
* Add support for Curve448 / X448
* Add support for Curve25519 / X25519.
* Add support for Curve448 / X448.
* Add attribute ``curve`` to EccPoint and EccXPoint classes,
with the canonical name of the curve.
* GH#781: the label for the SP800_108_Counter KDF may now
contain zero bytes. Thanks to Julien Rische.
* GH#814: RSA keys for PSS can be imported.

Resolved issues
---------------
* GH#810: fixed negation of Ed25519 points.
* GH#819: accept an RFC5916 ECPrivateKey even if it doesn't
contain any of the optional elements
(parameters [0] and publicKey[1]).

Other changes
-------------
* Remove support for Python 3.5.

3.20.0 (9 January 2024)
++++++++++++++++++++++++++

Expand Down
4 changes: 4 additions & 0 deletions Doc/src/protocol/dh.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ Specification
~~~~~~~~~~~~~

.. autofunction:: Crypto.Protocol.DH.key_agreement
.. autofunction:: Crypto.Protocol.DH.import_x25519_public_key
.. autofunction:: Crypto.Protocol.DH.import_x25519_private_key
.. autofunction:: Crypto.Protocol.DH.import_x448_public_key
.. autofunction:: Crypto.Protocol.DH.import_x448_private_key

Key Derivation Function
~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ prune Doc/_build
include .github/workflows/*.yml
recursive-include src *.h *.c
graft src/test
recursive-exclude src *.pyc
recursive-exclude src *.pyc *.swp
prune src/test/build
2 changes: 1 addition & 1 deletion lib/Crypto/IO/PKCS8.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def unwrap(p8_private_key, passphrase=None):
ValueError : if decoding fails
"""

if passphrase:
if passphrase is not None:
passphrase = tobytes(passphrase)

found = False
Expand Down
159 changes: 155 additions & 4 deletions lib/Crypto/SelfTest/Protocol/test_ecdh.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
from Crypto.Protocol import DH
from Crypto.Protocol.DH import (key_agreement,
import_x25519_public_key,
import_x25519_private_key)
import_x25519_private_key,
import_x448_public_key,
import_x448_private_key)


class FIPS_ECDH_Tests_KAT(unittest.TestCase):
Expand Down Expand Up @@ -455,9 +457,9 @@ def test_weak(self):
unhexlify(x))


class TestVectorsXECDHWycheproof(unittest.TestCase):
class TestVectorsX25519Wycheproof(unittest.TestCase):

desc = "Wycheproof XECDH tests"
desc = "Wycheproof X25519 tests"

def add_tests_hex(self, filename):

Expand Down Expand Up @@ -596,6 +598,154 @@ def runTest(self):
self.test_verify(tv)


class TestVectorsX448Wycheproof(unittest.TestCase):

desc = "Wycheproof X448 tests"

def add_tests_hex(self, filename):

def encoding(g):
return g['type']

def private(u):
return unhexlify(u['private'])

result = load_test_vectors_wycheproof(("Protocol", "wycheproof"),
filename,
"Wycheproof ECDH (%s)"
% filename,
group_tag={'encoding': encoding},
unit_tag={'private': private}
)
self.tv += result

def add_tests_ascii(self, filename):

def encoding(g):
return g['type']

def public(u):
return u['public']

def private(u):
return u['private']

result = load_test_vectors_wycheproof(("Protocol", "wycheproof"),
filename,
"Wycheproof ECDH (%s)"
% filename,
group_tag={'encoding': encoding},
unit_tag={'public': public,
'private': private}
)
self.tv += result

def setUp(self):
self.tv = []
self.desc = None

self.add_tests_hex("x448_test.json")
self.add_tests_hex("x448_asn_test.json")
self.add_tests_ascii("x448_pem_test.json")
self.add_tests_ascii("x448_jwk_test.json")

def shortDescription(self):
return self.desc

def test_verify(self, tv):

if tv.encoding == "XdhComp":
try:
public_key = import_x448_public_key(tv.public)
except ValueError as e:
assert tv.valid
assert tv.warning
if len(tv.public) == 56:
assert "LowOrderPublic" in tv.flags
assert "Invalid Curve448" in str(e)
else:
assert "Incorrect Curve448" in str(e)
return
private_key = import_x448_private_key(tv.private)
elif tv.encoding in ("XdhAsnComp", "XdhPemComp"):
try:
public_key = ECC.import_key(tv.public)
private_key = ECC.import_key(tv.private)
except ECC.UnsupportedEccFeature as e:
assert not tv.valid
assert "Unsupported ECC" in str(e)
return
except ValueError as e:
assert tv.valid
assert tv.warning
assert "LowOrderPublic" in tv.flags or "NonCanonicalPublic" in tv.flags
return
elif tv.encoding == "XdhJwkComp":

if 'y' in tv.public:
return
if 'x' not in tv.public:
return
if 'x' not in tv.private:
return
if tv.public.get('kty') != 'OKP':
return
if tv.public.get('crv') != 'X448':
return
if tv.private.get('crv') != 'X448':
return

def base64url_decode(input_str):
input_str = input_str.replace('-', '+').replace('_', '/')
padding = 4 - (len(input_str) % 4)
if padding != 4:
input_str += '=' * padding
decoded_bytes = base64.b64decode(input_str)
return decoded_bytes

jwk_public = base64url_decode(tv.public['x'])
jwk_private = base64url_decode(tv.private['d'])

try:
public_key = import_x448_public_key(jwk_public)
private_key = import_x448_private_key(jwk_private)
except ValueError as e:
if tv.valid:
assert tv.warning
if len(tv.public['x']) == 75:
assert "LowOrderPublic" in tv.flags or \
"NonCanonicalPublic" in tv.flags
assert "Invalid Curve448" in str(e)
else:
assert "Incorrect Curve448" in str(e)
return
else:
assert "Incorrect length" in str(e)
return
except ValueError:
assert tv.valid
else:
raise ValueError("Unknown encoding", tv.encoding)

try:
z = key_agreement(static_pub=public_key,
static_priv=private_key,
kdf=lambda x: x)
except ValueError:
assert not tv.valid
except TypeError as e:
assert not tv.valid
assert "incompatible curve" in str(e)
else:
self.assertEqual(z, tv.shared)
assert tv.valid

def runTest(self):
for tv in self.tv:
self.desc = "Wycheproof XECDH Verify Test #%d (%s, %s)" % (tv.id, tv.comment, tv.filename)
self.test_verify(tv)


def get_tests(config={}):

tests = []
Expand All @@ -604,7 +754,8 @@ def get_tests(config={}):
tests += list_test_cases(ECDH_Tests)
tests += list_test_cases(X25519_Tests)
tests += list_test_cases(X448_Tests)
tests += [TestVectorsXECDHWycheproof()]
tests += [TestVectorsX25519Wycheproof()]
tests += [TestVectorsX448Wycheproof()]

slow_tests = config.get('slow_tests')
if slow_tests:
Expand Down
2 changes: 1 addition & 1 deletion lib/Crypto/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__all__ = ['Cipher', 'Hash', 'Protocol', 'PublicKey', 'Util', 'Signature',
'IO', 'Math']

version_info = (3, 21, '0b0')
version_info = (3, 22, '0b0')

__version__ = ".".join([str(x) for x in version_info])
2 changes: 1 addition & 1 deletion requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pycryptodome-test-vectors==1.0.14
pycryptodome-test-vectors==1.0.20
2 changes: 1 addition & 1 deletion test_vectors/MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ include setup.py
include LICENSE.rst
recursive-include src *.h *.c *.cpp
graft pycryptodome_test_vectors
global-exclude __pycache__ *.pyc
global-exclude __pycache__ *.pyc *.swp
Loading

0 comments on commit 1c46bce

Please sign in to comment.