Skip to content
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
10 changes: 10 additions & 0 deletions multihash/multihash.py
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,11 @@ def _do_digest(data, func, length: int | None = None):
raise TruncationError(f"truncation length must be non-negative, got {length}")
if length == 0:
raise TruncationError("truncation length cannot be zero")
if func == Func.identity and length != len(digest_bytes):
raise TruncationError(
f"the length of the identity hash ({length}) must be equal "
f"to the length of the data ({len(digest_bytes)})"
)
if length > len(digest_bytes):
raise TruncationError(f"truncation length {length} exceeds digest size {len(digest_bytes)}")
digest_bytes = digest_bytes[:length]
Expand Down Expand Up @@ -935,6 +940,11 @@ def sum_stream(
raise TruncationError(f"truncation length must be non-negative, got {length}")
if length == 0:
raise TruncationError("truncation length cannot be zero")
if func == Func.identity and length != len(digest_bytes):
raise TruncationError(
f"the length of the identity hash ({length}) must be equal "
f"to the length of the data ({len(digest_bytes)})"
)
if length > len(digest_bytes):
raise TruncationError(f"truncation length {length} exceeds digest size {len(digest_bytes)}")
digest_bytes = digest_bytes[:length]
Expand Down
1 change: 1 addition & 0 deletions newsfragments/50.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reject identity multihashes when a truncation ``length`` is provided that does not equal the input data length, matching go-multihash behavior.
13 changes: 13 additions & 0 deletions tests/test_new_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,19 @@ def test_verify_with_truncated_digest(self):
assert mh.verify(b"hello") is True
assert mh.verify(b"world") is False

def test_identity_hash_length_must_match(self):
"""Identity hash length must equal data length when length is set."""
mh = sum(b"hello", Func.identity, length=5)
assert mh.digest == b"hello"

with pytest.raises(TruncationError, match="identity hash"):
sum(b"hello", Func.identity, length=3)

def test_identity_hash_length_must_match_sum_stream(self):
"""sum_stream rejects mismatched identity truncation length."""
with pytest.raises(TruncationError, match="identity hash"):
sum_stream(BytesIO(b"hello"), Func.identity, length=3)


class TestShakeFunctionsTestCase:
"""Tests for SHAKE variable-length hash functions."""
Expand Down
Loading