diff options
-rw-r--r-- | src/runtime/hash64.go | 14 | ||||
-rw-r--r-- | src/runtime/hash_test.go | 26 |
2 files changed, 33 insertions, 7 deletions
diff --git a/src/runtime/hash64.go b/src/runtime/hash64.go index 2864a4b963..bd16b7cd96 100644 --- a/src/runtime/hash64.go +++ b/src/runtime/hash64.go @@ -50,32 +50,32 @@ func memhashFallback(p unsafe.Pointer, seed, s uintptr) uintptr { seed1 := seed seed2 := seed for ; l > 48; l -= 48 { - seed = mix(r8(p)^m2, r8(add(p, 8))^seed) - seed1 = mix(r8(add(p, 16))^m3, r8(add(p, 24))^seed1) - seed2 = mix(r8(add(p, 32))^m4, r8(add(p, 40))^seed2) + seed = mix(r8(p)^hashkey[1]^m2, r8(add(p, 8))^seed) + seed1 = mix(r8(add(p, 16))^hashkey[2]^m3, r8(add(p, 24))^seed1) + seed2 = mix(r8(add(p, 32))^hashkey[3]^m4, r8(add(p, 40))^seed2) p = add(p, 48) } seed ^= seed1 ^ seed2 } for ; l > 16; l -= 16 { - seed = mix(r8(p)^m2, r8(add(p, 8))^seed) + seed = mix(r8(p)^hashkey[1]^m2, r8(add(p, 8))^seed) p = add(p, 16) } a = r8(add(p, l-16)) b = r8(add(p, l-8)) } - return mix(m5^s, mix(a^m2, b^seed)) + return mix(m5^s, mix(a^hashkey[1]^m2, b^seed)) } func memhash32Fallback(p unsafe.Pointer, seed uintptr) uintptr { a := r4(p) - return mix(m5^4, mix(a^m2, a^seed^hashkey[0]^m1)) + return mix(m5^4, mix(a^hashkey[1]^m2, a^seed^hashkey[0]^m1)) } func memhash64Fallback(p unsafe.Pointer, seed uintptr) uintptr { a := r8(p) - return mix(m5^8, mix(a^m2, a^seed^hashkey[0]^m1)) + return mix(m5^8, mix(a^hashkey[1]^m2, a^seed^hashkey[0]^m1)) } func mix(a, b uintptr) uintptr { diff --git a/src/runtime/hash_test.go b/src/runtime/hash_test.go index 77f916797f..36207e7ed0 100644 --- a/src/runtime/hash_test.go +++ b/src/runtime/hash_test.go @@ -5,10 +5,13 @@ package runtime_test import ( + "encoding/binary" "fmt" "internal/race" + "internal/testenv" "math" "math/rand" + "os" . "runtime" "slices" "strings" @@ -625,6 +628,29 @@ func TestSmhasherSeed(t *testing.T) { h.check(t) } +func TestIssue66841(t *testing.T) { + testenv.MustHaveExec(t) + if *UseAeshash && os.Getenv("TEST_ISSUE_66841") == "" { + // We want to test the backup hash, so if we're running on a machine + // that uses aeshash, exec ourselves while turning aes off. + cmd := testenv.CleanCmdEnv(testenv.Command(t, os.Args[0], "-test.run=^TestIssue66841$")) + cmd.Env = append(cmd.Env, "GODEBUG=cpu.aes=off", "TEST_ISSUE_66841=1") + out, err := cmd.CombinedOutput() + if err != nil { + t.Errorf("%s", string(out)) + } + // Fall through. Might as well run this test when aeshash is on also. + } + h := newHashSet() + var b [16]byte + binary.LittleEndian.PutUint64(b[:8], 0xe7037ed1a0b428db) // runtime.m2 + for i := 0; i < 1000; i++ { + binary.LittleEndian.PutUint64(b[8:], uint64(i)) + h.addB(b[:]) + } + h.check(t) +} + // size of the hash output (32 or 64 bits) const hashSize = 32 + int(^uintptr(0)>>63<<5) |