Background: Issue #69420 proposes a types.Hash function that provides a hash operator for types.Type values that is consistent with the equivalence relation for types defined by types.Identical. The only real question in that proposal is: what is to be Go's future convention for the signature of a custom hash function?
The naive answer is func(T) uint64, where T stands for types.Type. However, hash tables with only a single hash function are vulnerable to a "hash flooding" denial-of-service attack, in which an adversary provides many inputs that all hash to the same value, causing the table to degenerate into a linked list. The defense is for each process (or particular hash table) to select a different hash function at random so that the values cannot be predicted. The hash/maphash package embodies this approach: a random Seed value determines the hash functions (Hash.Strings and Hash.Bytes), which depend on the seed's opaque random value. (maphash does not provide a Seed-dependent way to hash integers.)
So, perhaps custom hash functions should accept a maphash.Seed parameter. And perhaps Seed should also provide methods for hashing integers.
Proposal: In the hash package, define function types HashFunc and EqFunc that document the conventions for Go hash tables.
Here is the minimal answer, without Seeds:
package hash
// HashFunc defines a hash function for values of type T.
// A conformant HashFunc and EqFunc pair (hash, eq) must observe the invariant
// that eq(x, y) => hash(x) == hash(y).
type HashFunc[T any] func(T) uint64
// EqFunc defines an equivalence relation for values of type T.
type EqFunc[T any] func(x, y T) bool
@ianlancetaylor @griesemer
Important
Updated proposal: #70471 (comment)
Background: Issue #69420 proposes a
types.Hashfunction that provides a hash operator fortypes.Typevalues that is consistent with the equivalence relation for types defined bytypes.Identical. The only real question in that proposal is: what is to be Go's future convention for the signature of a custom hash function?The naive answer is
func(T) uint64, where T stands fortypes.Type. However, hash tables with only a single hash function are vulnerable to a "hash flooding" denial-of-service attack, in which an adversary provides many inputs that all hash to the same value, causing the table to degenerate into a linked list. The defense is for each process (or particular hash table) to select a different hash function at random so that the values cannot be predicted. Thehash/maphashpackage embodies this approach: a random Seed value determines the hash functions (Hash.StringsandHash.Bytes), which depend on the seed's opaque random value. (maphash does not provide a Seed-dependent way to hash integers.)So, perhaps custom hash functions should accept a
maphash.Seedparameter. And perhaps Seed should also provide methods for hashing integers.Proposal: In the hash package, define function types HashFunc and EqFunc that document the conventions for Go hash tables.
Here is the minimal answer, without Seeds:
@ianlancetaylor @griesemer