From 2d01fbc45c3a51cfd78ad37ffcec1aaa11930a41 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Tue, 23 Sep 2025 09:20:53 +0000 Subject: [PATCH] use hashlib `keccak256()` function if available Available if Python compiled with OpenSSL 3.2 or greater (Python >= 3.13) --- mmgen/util2.py | 13 ++++++++++--- test/gentest.py | 2 +- test/modtest_d/dep.py | 23 +++++++++++++---------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/mmgen/util2.py b/mmgen/util2.py index fb19a139..d97a37c3 100755 --- a/mmgen/util2.py +++ b/mmgen/util2.py @@ -55,6 +55,14 @@ def load_cryptodome(called=[]): sys.modules['Cryptodome'] = Crypto # Cryptodome == pycryptodomex called.append(True) +def get_hashlib_keccak(): + import hashlib + try: + hashlib.new('keccak-256') + except ValueError: + return False + return lambda data: hashlib.new('keccak-256', data) + # called with no arguments by proto.eth.tx.transaction: def get_keccak(cfg=None, cached_ret=[]): @@ -62,11 +70,10 @@ def get_keccak(cfg=None, cached_ret=[]): if cfg and cfg.use_internal_keccak_module: cfg._util.qmsg('Using internal keccak module by user request') from .contrib.keccak import keccak_256 - else: + elif not (keccak_256 := get_hashlib_keccak()): load_cryptodome() from Crypto.Hash import keccak - def keccak_256(data): - return keccak.new(data=data, digest_bytes=32) + keccak_256 = lambda data: keccak.new(data=data, digest_bytes=32) cached_ret.append(keccak_256) return cached_ret[0] diff --git a/test/gentest.py b/test/gentest.py index b2c04fa3..abcb70e9 100755 --- a/test/gentest.py +++ b/test/gentest.py @@ -593,7 +593,7 @@ vmsg = cfg._util.vmsg proto = cfg._proto -if proto.coin in ('XMR', 'ETH', 'ETC'): +if proto.coin == 'XMR': from mmgen.util2 import load_cryptodome load_cryptodome() diff --git a/test/modtest_d/dep.py b/test/modtest_d/dep.py index e5bde002..4667dc24 100755 --- a/test/modtest_d/dep.py +++ b/test/modtest_d/dep.py @@ -44,16 +44,19 @@ class unit_tests: gmsg('LED support found!') return True - def keccak(self, name, ut): # used by ETH, XMR - from mmgen.util2 import get_keccak - try: - keccak_256 = get_keccak() - keccak_256(b'abc') - except Exception as e: - rmsg(str(e)) - return False - else: - return True + def keccak(self, name, ut): # used by ETH, ETC, XMR + from mmgen.util2 import get_keccak, get_hashlib_keccak + if not (keccak_256 := get_hashlib_keccak()): + ymsg('Hashlib keccak_256() not available, falling back on cryptodome(x) package') + try: + keccak_256 = get_keccak() + except Exception as e: + rmsg(str(e)) + return False + + chk = 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' + assert keccak_256(b'').hexdigest() == chk, 'hash mismatch!' + return True def pysocks(self, name, ut): import requests, urllib3