multiformats / multiformats/py-multihash

Keccak hash functions defined in `Func` enum but not registered with implementations

Open
#48 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
17
Forks
17
Avg merge
1h 5m
Merged PRs (30d)
3

Description

keccak_224, keccak_256, keccak_384, and keccak_512 are defined in the Func IntEnum but have no corresponding hash implementation registered in FuncReg. Calling sum(data, "keccak-256") raises HashComputationError even though the function code is recognized.

Problem

In multihash/funcs.py, the Func enum includes Keccak variants:

class Func(IntEnum):
    keccak_224 = HASH_CODES["keccak-224"]  # 0x1A
    keccak_256 = HASH_CODES["keccak-256"]  # 0x1B
    keccak_384 = HASH_CODES["keccak-384"]  # 0x1C
    keccak_512 = HASH_CODES["keccak-512"]  # 0x1D

But neither _std_func_data nor _optional_func_data includes any Keccak entry. So:

from multihash import sum, Func

# This raises HashComputationError:
mh = sum(b"hello", Func.keccak_256)
# HashComputationError: no available hash function for Func.keccak_256

Go's implementation registers Keccak-256 and Keccak-512 via the register/sha3 package:

multihash.Register(multihash.KECCAK_256, sha3.NewLegacyKeccak256)
multihash.Register(multihash.KECCAK_512, sha3.NewLegacyKeccak512)
Proposed Solution

Add Keccak hash wrappers using pycryptodome or pysha3:

# In funcs.py, add to _optional_func_data:
try:
    from Crypto.Hash import keccak as _keccak_mod

    class Keccak256Hash:
        name = "keccak-256"
        digest_size = 32
        block_size = 136
        def __init__(self):
            self._hasher = _keccak_mod.new(digest_bits=256)
        def update(self, data): self._hasher.update(data)
        def digest(self): return self._hasher.digest()
        def hexdigest(self): return self._hasher.hexdigest()
        def copy(self):
            c = Keccak256Hash()
            c._hasher = self._hasher.copy()
            return c

    # Similar for Keccak224, Keccak384, Keccak512
    _optional_func_data.extend([
        (Func.keccak_224, "keccak-224", Keccak224Hash),
        (Func.keccak_256, "keccak-256", Keccak256Hash),
        (Func.keccak_384, "keccak-384", Keccak384Hash),
        (Func.keccak_512, "keccak-512", Keccak512Hash),
    ])
except ImportError:
    pass  # pycryptodome not available

Alternatively, use pysha3 or safe-pysha3 which provide sha3.keccak_256() etc.

Add pycryptodome (or pysha3) as an optional dependency in pyproject.toml.

Add tests verifying Keccak output matches known test vectors.

Related

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in multihash/funcs.py by examining Func, _std_func_data, and _optional_func_data, then check pyproject.toml for optional dependency conventions. Register the four Keccak variants with an available implementation and add tests comparing their digests with the referenced known vectors; done means sum() works for each function when the optional dependency is installed.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cryptography
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.