ethsnarks icon indicating copy to clipboard operation
ethsnarks copied to clipboard

Crypto.Hash.keccak not compatible with pysha3 or hashlib

Open HarryR opened this issue 5 years ago • 0 comments

I tried to make Crypto.Hash.keccak available as a fallback when pysha3 isn't installed.

However, one person ran into an issue: https://github.com/HarryR/ethsnarks-miximus/issues/4#issuecomment-480538504

It seems that the interface for keccak provided by Crypto.Hash.keccak isn't compatible with pysha3, it doesn't seem to allow you to pass-in data to be hashed as part of the constructor.

As per the documentation the keccak.new function should accept the data kwarg, however it doesn't accept it as the first parameter which would be compatible with the Python hashlib standard interface and pysha3.

Offending code from: https://github.com/HarryR/ethsnarks/blob/master/ethsnarks/mimc.py

try:
    # pysha3
    from sha3 import keccak_256
except ImportError:
    # pycryptodome
    from Crypto.Hash import keccak
    keccak_256 = lambda *args: keccak.new(*args, digest_bits=256)

Error:

ERROR: test_miximus (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_miximus
Traceback (most recent call last):
  File "/usr/lib/python3.6/unittest/loader.py", line 428, in _find_test_path
    module = self._get_module_from_name(name)
  File "/usr/lib/python3.6/unittest/loader.py", line 369, in _get_module_from_name
    __import__(name)
  File "/home/fnatic/ethsnarks-miximus/python/test/test_miximus.py", line 4, in <module>
    from ethsnarks.mimc import mimc_hash
  File "/home/fnatic/ethsnarks-miximus/ethsnarks/ethsnarks/mimc.py", line 38, in <module>
    assert H(123) == 38632140595220392354280998614525578145353818029287874088356304829962854601866
  File "/home/fnatic/ethsnarks-miximus/ethsnarks/ethsnarks/mimc.py", line 35, in H
    hashed = keccak_256(data).digest()
  File "/home/fnatic/ethsnarks-miximus/ethsnarks/ethsnarks/mimc.py", line 10, in <lambda>
    keccak_256 = lambda *args: keccak.new(*args, digest_bits=256)
TypeError: new() takes 0 positional arguments but 1 was given

Suggested fix:

# ...
except ImportError:
    # pycryptodome
    from Crypto.Hash import keccak
    keccak_256 = lambda data=None: keccak.new(data=data, digest_bits=256)

Documentation: https://pycryptodome.readthedocs.io/en/latest/src/hash/keccak.html

Example usage:

>>> from Crypto.Hash import keccak
>>>
>>> keccak_hash = keccak.new(digest_bits=512)
>>> keccak_hash.update(b'Some data')
>>> print keccak_hash.hexdigest()

HarryR avatar Apr 11 '19 14:04 HarryR