Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable support for keccak again #16

Merged
merged 1 commit into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,11 @@ The following are mandatory dependencies for this module:

The following are optional dependencies for this module:

- `pysha3 <https://github.com/tiran/pysha3>`_, for the ``keccak`` hash functions.
- `blake3 <https://github.com/oconnor663/blake3-py>`_, for the ``blake3`` hash function.
- `pyskein <https://pythonhosted.org/pyskein/>`_, for the ``skein`` hash functions.
- `mmh3 <https://github.com/hajimes/mmh3>`_, for the ``murmur3`` hash functions.
- `pycryptodomex <https://github.com/Legrandin/pycryptodome/>`_, for the ``ripemd-160`` hash function, \
the ``kangarootwelve`` hash function and the ``sha2-512-224``/``sha2-512-256`` hash functions.
the ``kangarootwelve`` hash function, the ``keccak`` hash functions and the ``sha2-512-224``/``sha2-512-256`` hash functions.

You can install the latest release together with all optional dependencies as follows:

Expand Down
3 changes: 1 addition & 2 deletions docs/getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,11 @@ The following are mandatory dependencies for this module:

The following are optional dependencies for this module:

- `pysha3 <https://github.com/tiran/pysha3>`_, for the ``keccak`` hash functions.
- `blake3 <https://github.com/oconnor663/blake3-py>`_, for the ``blake3`` hash function.
- `pyskein <https://pythonhosted.org/pyskein/>`_, for the ``skein`` hash functions.
- `mmh3 <https://github.com/hajimes/mmh3>`_, for the ``murmur3`` hash functions.
- `pycryptodomex <https://github.com/Legrandin/pycryptodome/>`_, for the ``ripemd-160`` hash function, \
the ``kangarootwelve`` hash function and the ``sha2-512-224``/``sha2-512-256`` hash functions.
the ``kangarootwelve`` hash function, the ``keccak`` hash functions and the ``sha2-512-224``/``sha2-512-256`` hash functions.

You can install the latest release together with all optional dependencies as follows:

Expand Down
17 changes: 5 additions & 12 deletions multiformats/multihash/_hashfuns/keccak.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,29 @@
"""
Implementation for the ``keccak`` hash functions, using the optional dependency `pysha3 <https://github.com/tiran/pysha3>`_.
Implementation for the ``keccak`` hash functions, using the optional dependency `pycryptodomex <https://github.com/Legrandin/pycryptodome/>`_.
"""

from __future__ import annotations

import hashlib
from typing import Optional

from multiformats.varint import BytesLike
from .utils import Hashfun, validate_hashfun_args

def _keccak(digest_bits: int) -> Hashfun:
# FIXME: pysha3 is not longer available
raise NotImplementedError("keccak hashes are not currently supported.")
# pylint: disable = unreachable
try:
import sha3 # type: ignore # pylint: disable = import-outside-toplevel
from Cryptodome.Hash import keccak # pylint: disable = import-outside-toplevel
except ImportError as e:
raise ImportError("Module 'sha3' must be installed to use 'keccak' hash functions. Consider running 'pip install pysha3'.") from e
h = getattr(sha3, f"keccak_{digest_bits}")
raise ImportError("Module 'pycryptodome' must be installed to use 'keccak' hash functions. Consider running 'pip install pycryptodome'.") from e

def hashfun(data: BytesLike, size: Optional[int] = None) -> bytes:
validate_hashfun_args(data, size, digest_bits//8)
m: hashlib._Hash = h() # pylint: disable = no-member
m = keccak.new(digest_bits=digest_bits)
m.update(data)
d = m.digest()
return d if size is None else d[:size]
return hashfun

def _jit_register_keccak(m, register) -> bool: # type: ignore
# FIXME: pysha3 is not longer available
raise NotImplementedError("keccak hashes are not currently supported.")
# pylint: disable = unreachable
digest_bits = int(m[1])
if register is not None:
register(f"keccak-{digest_bits}", _keccak(digest_bits), digest_bits//8)
Expand Down
5 changes: 2 additions & 3 deletions multiformats/multihash/raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
Hash functions are implemented using the following modules:

- `hashlib <https://docs.python.org/3/library/hashlib.html>`_, for the ``sha``/``shake`` hash functions and the ``blake2`` hash functions.
- `pysha3 <https://github.com/tiran/pysha3>`_, for the ``keccak`` hash functions.
- `blake3 <https://github.com/oconnor663/blake3-py>`_, for the ``blake3`` hash function.
- `pyskein <https://pythonhosted.org/pyskein/>`_, for the ``skein`` hash functions.
- `mmh3 <https://github.com/hajimes/mmh3>`_, for the ``murmur3`` hash functions.
- `pycryptodomex <https://github.com/Legrandin/pycryptodome/>`_, for the ``ripemd-160`` hash function, \
the ``kangarootwelve`` hash function and the ``sha2-512-224``/``sha2-512-256`` hash functions.
the ``kangarootwelve`` hash function, the ``keccak`` hash functions and the ``sha2-512-224``/``sha2-512-256`` hash functions.

All modules other than `hashlib <https://docs.python.org/3/library/hashlib.html>`_ are optional dependencies.
The :func:`get` function attempts to dynamically import any optional dependencies required by desired multihash
Expand Down Expand Up @@ -276,7 +275,7 @@ def _jit_register_hashfun_dbl(name: str, check_only: bool = False) -> bool:
_jit_register_hashfun_dir = {
"sha": _jit_register_hashfun_sha,
"bla": _jit_register_hashfun_bla,
# "kec": _jit_register_hashfun_kec, # kec is currently unavailable
"kec": _jit_register_hashfun_kec,
"ske": _jit_register_hashfun_ske,
"mur": _jit_register_hashfun_mur,
"md5": _jit_register_hashfun_md5,
Expand Down
2 changes: 0 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,12 @@ dev =
pylint
pytest
pytest-cov
; pysha3
blake3
pyskein
mmh3
pycryptodomex
rich # optional dependency of typing_validation
full =
; pysha3
blake3
pyskein
mmh3
Expand Down
28 changes: 12 additions & 16 deletions test/test_03_multihash.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
import pytest
import skein # type: ignore
from blake3 import blake3 # type: ignore
# import sha3 # type: ignore
# FIXME: find an alternative implementation for keccak
import mmh3 # type: ignore
from Cryptodome.Hash import RIPEMD160, KangarooTwelve, SHA512
from Cryptodome.Hash import RIPEMD160, KangarooTwelve, SHA512, keccak

from multiformats import multihash
from multiformats.multihash import wrap, digest, unwrap
Expand Down Expand Up @@ -79,12 +77,11 @@ def skein_digest(data: bytes, variant: int, digest_bits: int, size: Optional[int
d = m.digest()
return d if size is None else d[:size]

# def keccak_digest(data: bytes, digest_bits: int, size: Optional[int]) -> bytes:
# m: hashlib._Hash = getattr(sha3, f"keccak_{digest_bits}")()
# m.update(data)
# d = m.digest()
# return d if size is None else d[:size]
# FIXME: find an alternative implementation for keccak
def keccak_digest(data: bytes, digest_bits: int, size: Optional[int]) -> bytes:
m: hashlib._Hash = keccak.new(digest_bits=digest_bits)
m.update(data)
d = m.digest()
return d if size is None else d[:size]

# def murmur3_digest(data: bytes, variant: str, digest_bits: int, size: Optional[int]) -> bytes:
# assert variant in ("32", "x64")
Expand Down Expand Up @@ -218,13 +215,12 @@ def test_skein(data: bytes, version: int, size: Optional[int]) -> None:
hash_fn = f"skein{version}-{digest_bits}"
_test(hash_fn, data, skein_digest(data, version, digest_bits, size), size)

# @pytest.mark.parametrize("digest_bits", (224, 256, 384, 512))
# @pytest.mark.parametrize("data", data_samples)
# @pytest.mark.parametrize("size", (None, 16, 28))
# def test_keccak(data: bytes, digest_bits: int, size: Optional[int]) -> None:
# hash_fn = f"keccak-{digest_bits}"
# _test(hash_fn, data, keccak_digest(data, digest_bits, size), size)
# FIXME: find an alternative implementation for keccak
@pytest.mark.parametrize("digest_bits", (224, 256, 384, 512))
@pytest.mark.parametrize("data", data_samples)
@pytest.mark.parametrize("size", (None, 16, 28))
def test_keccak(data: bytes, digest_bits: int, size: Optional[int]) -> None:
hash_fn = f"keccak-{digest_bits}"
_test(hash_fn, data, keccak_digest(data, digest_bits, size), size)

# @pytest.mark.parametrize("version", ("32", "x64"))
# @pytest.mark.parametrize("data", data_samples)
Expand Down
1 change: 0 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ deps =
pylint
pytest
pytest-cov
; pysha3
blake3
pyskein
mmh3
Expand Down