From 20734cc7bbb2f7b1535379fb59cef32ee8a7d22c Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Fri, 26 Sep 2025 10:40:23 +0000 Subject: [PATCH] util2: new `load_fake_cryptodome()` function The eth-key and monero-python packages used in the test suite require the keccak256() function provided by the pycryptodome (pycryptodomex) package. pycryptodome is used in the MMGen code base only by these packages, and only for testing. This monkey-patch function eliminates dependency on pycryptodome on systems that provide keccak256() via hashlib (>=OpenSSL 3.2, >=Python 3.13, latest MSYS2). --- mmgen/util2.py | 42 ++++++++++++++++++++++++++++++++---------- test/gentest.py | 2 +- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/mmgen/util2.py b/mmgen/util2.py index ef16e3d1..3226d922 100755 --- a/mmgen/util2.py +++ b/mmgen/util2.py @@ -30,6 +30,23 @@ def die_pause(ev=0, s=''): input('Press ENTER to exit') sys.exit(ev) +def load_fake_cryptodome(): + import hashlib + try: + hashlib.new('keccak-256') + except ValueError: + return False + + class FakeHash: + class keccak: + def new(data=b'', digest_bits=256): + assert digest_bits == 256 + return hashlib.new('keccak-256', data=data) + + sys.modules['Cryptodome.Hash'] = FakeHash + sys.modules['Crypto.Hash'] = FakeHash + return True + def cffi_override_fixup(): from cffi import FFI class FFI_override: @@ -38,21 +55,26 @@ def cffi_override_fixup(): FFI.cdef = FFI_override.cdef # monkey-patch function: makes modules pycryptodome and pycryptodomex available to packages that -# expect them (monero-python, eth-keys), regardless of which one is installed on system +# expect them for the keccak256 function (monero-python, eth-keys), regardless of which one is +# installed on the system +# +# if the hashlib keccak256 function is available (>=OpenSSL 3.2, >=Python 3.13), it’s used instead +# and loaded as Crypto[dome].Hash via load_fake_cryptodome() def load_cryptodome(called=[]): if not called: - cffi_override_fixup() - try: - import Crypto # Crypto == pycryptodome - except ImportError: + if not load_fake_cryptodome(): + cffi_override_fixup() try: - import Cryptodome # Crypto == pycryptodome + import Crypto # Crypto == pycryptodome except ImportError: - die(2, 'Unable to import the ‘pycryptodome’ or ‘pycryptodomex’ package') + try: + import Cryptodome # Crypto == pycryptodome + except ImportError: + die(2, 'Unable to import the ‘pycryptodome’ or ‘pycryptodomex’ package') + else: + sys.modules['Crypto'] = Cryptodome # Crypto == pycryptodome else: - sys.modules['Crypto'] = Cryptodome # Crypto == pycryptodome - else: - sys.modules['Cryptodome'] = Crypto # Cryptodome == pycryptodomex + sys.modules['Cryptodome'] = Crypto # Cryptodome == pycryptodomex called.append(True) def get_hashlib_keccak(): diff --git a/test/gentest.py b/test/gentest.py index 7fcde099..2f9e5dad 100755 --- a/test/gentest.py +++ b/test/gentest.py @@ -582,7 +582,7 @@ vmsg = cfg._util.vmsg proto = cfg._proto -if proto.coin == 'XMR': +if proto.coin in ('ETH', 'ETC', 'XMR'): from mmgen.util2 import load_cryptodome load_cryptodome()