Skip to content

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

Description

@sumanjeet0012

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions