Skip to content

No FuncReg.RegisterVariableSize() or DefaultLengths map #55

Description

@sumanjeet0012

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:

  1. Custom variable-size hash functions can't be properly registered
  2. Users can't query the default output length for a hash code
  3. The SHAKE special case in hash_from_func() is a workaround, not a general solution

Proposed Solution

  1. 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.

  2. 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)
  3. 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

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