diff --git a/eth-requirements.txt b/eth-requirements.txt index 125498ee..82644a87 100644 --- a/eth-requirements.txt +++ b/eth-requirements.txt @@ -3,3 +3,4 @@ py_ecc==1.6.0 mypy_extensions==0.4.1 +pycryptodomex diff --git a/mmgen/exception.py b/mmgen/exception.py index 51596b8b..9e44e01c 100755 --- a/mmgen/exception.py +++ b/mmgen/exception.py @@ -68,6 +68,7 @@ class ClassFlagsError(Exception): mmcode = 2 class ExtensionModuleError(Exception): mmcode = 2 class MoneroMMGenTXFileParseError(Exception): mmcode = 2 class AutosignTXError(Exception): mmcode = 2 +class MMGenImportError(Exception): mmcode = 2 # 3: yellow hl, 'MMGen Error' + exception + message class RPCFailure(Exception): mmcode = 3 diff --git a/mmgen/util.py b/mmgen/util.py index 539188dd..7a9fbd23 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -431,15 +431,6 @@ def async_run(coro): import asyncio return asyncio.run(coro) -def load_cryptodomex(called=[]): - if not called: - try: - import Cryptodome - except ImportError: - import Crypto - sys.modules['Cryptodome'] = sys.modules['Crypto'] - called.append(True) - def wrap_ripemd160(called=[]): if not called: try: diff --git a/mmgen/util2.py b/mmgen/util2.py index 6fe474b8..372556b5 100755 --- a/mmgen/util2.py +++ b/mmgen/util2.py @@ -45,9 +45,16 @@ def get_keccak(cfg=None,cached_ret=[]): from .contrib.keccak import keccak_256 else: try: - from sha3 import keccak_256 - except: - from .contrib.keccak import keccak_256 + from Cryptodome.Hash import keccak + except ImportError as e: + try: + from Crypto.Hash import keccak + except ImportError as e2: + msg(f'{e2} and {e}') + die('MMGenImportError', + 'Please install the ‘pycryptodome’ or ‘pycryptodomex’ package on your system') + def keccak_256(data): + return keccak.new(data=data,digest_bytes=32) cached_ret.append(keccak_256) return cached_ret[0] diff --git a/setup.cfg b/setup.cfg index 673a1241..3def017a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,9 +30,6 @@ classifiers = python_requires = >=3.7 include_package_data = True -# pysha3 is used by XMR and ETH for the keccak hash function only. If the -# module is unavailable, the native Python implementation in contrib.keccak -# will be used instead. install_requires = importlib-resources; python_version < "3.9" gmpy2 @@ -45,7 +42,6 @@ install_requires = pexpect scrypt; platform_system != "Windows" # must be installed by hand on MSYS2 semantic-version; platform_system != "Windows" # scripts/create-token.py - pysha3; platform_system != "Windows" and python_version < "3.11" packages = mmgen diff --git a/test/gentest.py b/test/gentest.py index 809abf81..8f667354 100755 --- a/test/gentest.py +++ b/test/gentest.py @@ -231,8 +231,6 @@ class GenToolMonero_python(GenTool): def __init__(self,*args,**kwargs): super().__init__(*args,**kwargs) - from mmgen.util import load_cryptodomex - load_cryptodomex() try: from monero.seed import Seed except Exception as e: diff --git a/test/hashfunc.py b/test/hashfunc.py index cd6fc3ec..c62492ae 100755 --- a/test/hashfunc.py +++ b/test/hashfunc.py @@ -107,23 +107,11 @@ class TestKeccak(TestHashFunc): def __init__(self): from mmgen.contrib.keccak import keccak_256 + from mmgen.util2 import get_keccak self.t_cls = keccak_256 - from mmgen.pyversion import python_version - if python_version >= '3.11' or sys.platform == 'win32': - class hashlib: - @staticmethod - def keccak_256(data): - return keccak.new(data=data,digest_bytes=32) - from mmgen.util import load_cryptodomex - load_cryptodomex() - from Cryptodome.Hash import keccak - self.hashlib = hashlib - else: - try: - import sha3 - except ImportError as e: - die(2,str(e)) - self.hashlib = sha3 + class hashlib: + keccak_256 = get_keccak() + self.hashlib = hashlib def test_constants(self): pass diff --git a/test/unit_tests_d/ut_dep.py b/test/unit_tests_d/ut_dep.py index 3cdd2fc1..49662b1b 100755 --- a/test/unit_tests_d/ut_dep.py +++ b/test/unit_tests_d/ut_dep.py @@ -10,15 +10,15 @@ test.unit_tests_d.ut_dep: dependency unit tests for the MMGen suite import sys from subprocess import run,PIPE -from mmgen.util import msg,ymsg,gmsg +from mmgen.util import msg,rmsg,ymsg,gmsg from mmgen.exception import NoLEDSupport from ..include.common import cfg,vmsg,check_solc_ver class unit_tests: - altcoin_deps = ('pysha3','py_ecc','solc','pycryptodomex') - win_skip = ('pysha3','led') + altcoin_deps = ('py_ecc','solc','keccak','pysocks') + win_skip = ('led',) def led(self,name,ut): from mmgen.led import LEDControl @@ -30,32 +30,15 @@ class unit_tests: gmsg('LED support found!') return True - def pysha3(self,name,ut): # ETH,XMR - from mmgen.pyversion import python_version - if python_version >= '3.11': - ut.skip_msg(f'Python version {python_version}') + def keccak(self,name,ut): # used by ETH, XMR + from mmgen.util2 import get_keccak + try: + get_keccak() + except Exception as e: + rmsg(str(e)) + return False else: - try: - from sha3 import keccak_256 - except ImportError as e: - ymsg(str(e)) - return False - return True - - def pycryptodomex(self,name,ut): # ETH,XMR (keccak) - from mmgen.pyversion import python_version - if python_version >= '3.11' or sys.platform == 'win32': - try: - from mmgen.util import load_cryptodomex - except Exception as e: - msg(str(e)) - ymsg('Please install the ‘pycryptodome’ or ‘pycryptodomex’ package on your system') - return False - elif sys.platform != 'win32': - ut.skip_msg(f'platform {sys.platform!r}') - else: - ut.skip_msg(f'Python version {python_version}') - return True + return True def py_ecc(self,name,ut): # ETH from py_ecc.secp256k1 import privtopub