Go's registry provides RegisterVariableSize() for hash functions that accept a size hint (like SHAKE, BLAKE3), and exposes a DefaultLengths map mapping code → default output size. Python's FuncReg has neither.
Problem
Go's core/registry.go:
// RegisterVariableSize adds a variable-sized hasher factory that takes a size hint.
func RegisterVariableSize(indicator uint64,
hasherFactory func(sizeHint int) (hash.Hash, bool)) { ... }
// DefaultLengths maps code → default output size in bytes.
var DefaultLengths = map[uint64]int{}
Python's FuncReg only has:
register(code, name, hash_name, hash_new) — fixed-size only
hash_from_func(func, length=None) — special-cases SHAKE internally
- No
DefaultLengths equivalent
This means:
- Custom variable-size hash functions can't be properly registered
- Users can't query the default output length for a hash code
- The SHAKE special case in
hash_from_func() is a workaround, not a general solution
Proposed Solution
-
Add DefaultLengths dict to FuncReg:
class FuncReg:
default_lengths: ClassVar[dict[int, int]] = {}
Populate it during reset() by calling hash_new().digest_size for each registered function.
-
Add register_variable_size() classmethod:
@classmethod
def register_variable_size(cls, code, name, factory):
"""Register a variable-size hash function.
factory(length: int) -> hash_obj
When length is -1, return default-length hasher.
When length is >= 0, return hasher producing at least that many bytes.
"""
# Get default length
default_hasher = factory(-1)
cls.default_lengths[code] = default_hasher.digest_size
# Store factory
cls._func_hash[code] = cls._hash(name, factory)
-
Update hash_from_func() to use the factory's size hint:
@classmethod
def hash_from_func(cls, func, length=None):
entry = cls._func_hash[func]
if callable(entry.new) and func in cls.default_lengths:
# Variable-size: pass length hint
return entry.new(length or -1)
# Fixed-size
return entry.new()
Related
Go's registry provides
RegisterVariableSize()for hash functions that accept a size hint (like SHAKE, BLAKE3), and exposes aDefaultLengthsmap mapping code → default output size. Python'sFuncReghas neither.Problem
Go's
core/registry.go:Python's
FuncRegonly has:register(code, name, hash_name, hash_new)— fixed-size onlyhash_from_func(func, length=None)— special-cases SHAKE internallyDefaultLengthsequivalentThis means:
hash_from_func()is a workaround, not a general solutionProposed Solution
Add
DefaultLengthsdict toFuncReg:Populate it during
reset()by callinghash_new().digest_sizefor each registered function.Add
register_variable_size()classmethod:Update
hash_from_func()to use the factory's size hint:Related
core/registry.go