From 7e534f4865582102a5df26de9390888a6559904b Mon Sep 17 00:00:00 2001 From: SomberNight Date: Mon, 7 Sep 2020 18:07:41 +0200 Subject: [PATCH] dependencies: rm pyaes from requirements Since #6014, pyaes is not really needed anymore. As we currently require either one of pycryptodomex or cryptography, even if pyaes is available, it will not be used. We could strip it out completely from crypto.py... In any case, pyaes is still pulled in by some hw wallet dependencies indirectly; but the core library no longer depends on it. --- contrib/requirements/requirements.txt | 1 - electrum/crypto.py | 18 ++++++++++++++---- electrum/tests/test_bitcoin.py | 15 +++++++++++---- run_electrum | 1 - setup.py | 2 +- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/contrib/requirements/requirements.txt b/contrib/requirements/requirements.txt index a419b0bfd..312d955a1 100644 --- a/contrib/requirements/requirements.txt +++ b/contrib/requirements/requirements.txt @@ -1,4 +1,3 @@ -pyaes>=0.1a1 ecdsa>=0.14 qrcode protobuf>=3.12 diff --git a/electrum/crypto.py b/electrum/crypto.py index 7fda99aaa..3a0678535 100644 --- a/electrum/crypto.py +++ b/electrum/crypto.py @@ -30,12 +30,18 @@ import hashlib import hmac from typing import Union -import pyaes - from .util import assert_bytes, InvalidPassword, to_bytes, to_string, WalletFileException from .i18n import _ +HAS_PYAES = False +try: + import pyaes +except: + pass +else: + HAS_PYAES = True + HAS_CRYPTODOME = False try: from Cryptodome.Cipher import ChaCha20_Poly1305 as CD_ChaCha20_Poly1305 @@ -97,10 +103,12 @@ def aes_encrypt_with_iv(key: bytes, iv: bytes, data: bytes) -> bytes: cipher = CG_Cipher(CG_algorithms.AES(key), CG_modes.CBC(iv), backend=CG_default_backend()) encryptor = cipher.encryptor() e = encryptor.update(data) + encryptor.finalize() - else: + elif HAS_PYAES: aes_cbc = pyaes.AESModeOfOperationCBC(key, iv=iv) aes = pyaes.Encrypter(aes_cbc, padding=pyaes.PADDING_NONE) e = aes.feed(data) + aes.feed() # empty aes.feed() flushes buffer + else: + raise Exception("no AES backend found") return e @@ -113,10 +121,12 @@ def aes_decrypt_with_iv(key: bytes, iv: bytes, data: bytes) -> bytes: cipher = CG_Cipher(CG_algorithms.AES(key), CG_modes.CBC(iv), backend=CG_default_backend()) decryptor = cipher.decryptor() data = decryptor.update(data) + decryptor.finalize() - else: + elif HAS_PYAES: aes_cbc = pyaes.AESModeOfOperationCBC(key, iv=iv) aes = pyaes.Decrypter(aes_cbc, padding=pyaes.PADDING_NONE) data = aes.feed(data) + aes.feed() # empty aes.feed() flushes buffer + else: + raise Exception("no AES backend found") try: return strip_PKCS7_padding(data) except InvalidPadding: diff --git a/electrum/tests/test_bitcoin.py b/electrum/tests/test_bitcoin.py index a22fc6b16..9d5ed59ef 100644 --- a/electrum/tests/test_bitcoin.py +++ b/electrum/tests/test_bitcoin.py @@ -46,18 +46,21 @@ def needs_test_with_all_aes_implementations(func): return has_cryptodome = crypto.HAS_CRYPTODOME has_cryptography = crypto.HAS_CRYPTOGRAPHY + has_pyaes = crypto.HAS_PYAES try: - (crypto.HAS_CRYPTODOME, crypto.HAS_CRYPTOGRAPHY) = False, False - func(*args, **kwargs) # pyaes + if has_pyaes: + (crypto.HAS_CRYPTODOME, crypto.HAS_CRYPTOGRAPHY, crypto.HAS_PYAES) = False, False, True + func(*args, **kwargs) # pyaes if has_cryptodome: - (crypto.HAS_CRYPTODOME, crypto.HAS_CRYPTOGRAPHY) = True, False + (crypto.HAS_CRYPTODOME, crypto.HAS_CRYPTOGRAPHY, crypto.HAS_PYAES) = True, False, False func(*args, **kwargs) # cryptodome if has_cryptography: - (crypto.HAS_CRYPTODOME, crypto.HAS_CRYPTOGRAPHY) = False, True + (crypto.HAS_CRYPTODOME, crypto.HAS_CRYPTOGRAPHY, crypto.HAS_PYAES) = False, True, False func(*args, **kwargs) # cryptography finally: crypto.HAS_CRYPTODOME = has_cryptodome crypto.HAS_CRYPTOGRAPHY = has_cryptography + crypto.HAS_PYAES = has_pyaes return run_test @@ -101,6 +104,10 @@ class Test_bitcoin(ElectrumTestCase): # we want the unit testing framework to test with cryptography available. self.assertTrue(bool(crypto.HAS_CRYPTOGRAPHY)) + def test_pyaes_is_available(self): + # we want the unit testing framework to test with pyaes available. + self.assertTrue(bool(crypto.HAS_PYAES)) + @needs_test_with_all_aes_implementations def test_crypto(self): for message in [b"Chancellor on brink of second bailout for banks", b'\xff'*512]: diff --git a/run_electrum b/run_electrum index 7102725fb..67776d94f 100755 --- a/run_electrum +++ b/run_electrum @@ -60,7 +60,6 @@ def check_imports(): # pure-python dependencies need to be imported here for pyinstaller try: import dns - import pyaes import ecdsa import certifi import qrcode diff --git a/setup.py b/setup.py index 53701e690..68fac9e69 100755 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ extras_require = { 'hardware': requirements_hw, 'gui': ['pyqt5'], 'crypto': ['cryptography>=2.1'], - 'tests': ['pycryptodomex>=3.7', 'cryptography>=2.1'], + 'tests': ['pycryptodomex>=3.7', 'cryptography>=2.1', 'pyaes>=0.1a1'], } # 'full' extra that tries to grab everything an enduser would need (except for libsecp256k1...) extras_require['full'] = [pkg for sublist in