Blake3Hash always produces a 32-byte digest. Go's BLAKE3 registration supports variable-length output (32, 64, 128 bytes, up to max 128). Calling sum(data, "blake3", length=64) raises TruncationError because the digest is only 32 bytes, even though BLAKE3 natively supports extended output.
Problem
In multihash/funcs.py:
class Blake3Hash:
digest_size: int = 32 # Always 32 bytes
def digest(self) -> bytes:
return self._hasher.digest() # Always returns 32 bytes
The blake3 Python library supports variable-length output:
import blake3
h = blake3.blake3()
h.update(b"foo")
h.digest(64) # Returns 64 bytes ✅
h.digest(128) # Returns 128 bytes ✅
But the wrapper doesn't use this capability. So:
from multihash import sum, Func
# This raises TruncationError:
mh = sum(b"foo", Func.blake3, length=64)
# TruncationError: truncation length 64 exceeds digest size 32
Go's implementation uses RegisterVariableSize:
multihash.RegisterVariableSize(multihash.BLAKE3, func(size int) (hash.Hash, bool) {
if size == -1 { size = 32 }
else if size > 128 || size <= 0 { return nil, false }
h := blake3.New(size, nil)
return h, true
})
Go test vectors include BLAKE3 at 32, 64, and 128 bytes.
Proposed Solution
Modify Blake3Hash to accept a length parameter:
class Blake3Hash:
MAX_SIZE = 128
def __init__(self, length: int = 32):
self._hasher = blake3.blake3()
self._length = length
self.name = "blake3"
self.digest_size = length
self.block_size = 64
def digest(self) -> bytes:
return self._hasher.digest(self._length)
def copy(self):
c = Blake3Hash(self._length)
c._hasher = self._hasher.copy()
return c
Update FuncReg.hash_from_func() to pass length for BLAKE3 (similar to SHAKE):
@classmethod
def hash_from_func(cls, func, length=None):
new = cls._func_hash[func].new
if new is None:
# Handle SHAKE and BLAKE3 with variable length
if func == Func.blake3:
blake3_len = length if length and length > 0 else 32
if blake3_len > Blake3Hash.MAX_SIZE:
return None
return Blake3Hash(blake3_len)
# ... existing SHAKE handling ...
return new()
Add tests matching Go's test vectors for BLAKE3 at 32, 64, and 128 bytes.
Related
Blake3Hashalways produces a 32-byte digest. Go's BLAKE3 registration supports variable-length output (32, 64, 128 bytes, up to max 128). Callingsum(data, "blake3", length=64)raisesTruncationErrorbecause the digest is only 32 bytes, even though BLAKE3 natively supports extended output.Problem
In
multihash/funcs.py:The
blake3Python library supports variable-length output:But the wrapper doesn't use this capability. So:
Go's implementation uses
RegisterVariableSize:Go test vectors include BLAKE3 at 32, 64, and 128 bytes.
Proposed Solution
Modify
Blake3Hashto accept a length parameter:Update
FuncReg.hash_from_func()to pass length for BLAKE3 (similar to SHAKE):Add tests matching Go's test vectors for BLAKE3 at 32, 64, and 128 bytes.
Related
register/blake3/multihash_blake3.gosum_test.go