diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go index 939e282ff0..77beb0992c 100644 --- a/src/cmd/cgo/main.go +++ b/src/cmd/cgo/main.go @@ -390,7 +390,7 @@ func main() { // We already put _cgo_ at the beginning, so the main // concern is other cgo wrappers for the same functions. // Use the beginning of the 16 bytes hash of the input to disambiguate. - h := hash.New16() + h := hash.New32() io.WriteString(h, *importPath) var once sync.Once var wg sync.WaitGroup diff --git a/src/cmd/compile/internal/liveness/plive.go b/src/cmd/compile/internal/liveness/plive.go index ac0c2dff0a..6c97858cf6 100644 --- a/src/cmd/compile/internal/liveness/plive.go +++ b/src/cmd/compile/internal/liveness/plive.go @@ -981,7 +981,7 @@ func (lv *Liveness) enableClobber() { // Clobber only functions where the hash of the function name matches a pattern. // Useful for binary searching for a miscompiled function. hstr := "" - for _, b := range hash.Sum20([]byte(lv.f.Name)) { + for _, b := range hash.Sum32([]byte(lv.f.Name)) { hstr += fmt.Sprintf("%08b", b) } if !strings.HasSuffix(hstr, h) { diff --git a/src/cmd/compile/internal/types/fmt.go b/src/cmd/compile/internal/types/fmt.go index 0dba510ac4..139defafe2 100644 --- a/src/cmd/compile/internal/types/fmt.go +++ b/src/cmd/compile/internal/types/fmt.go @@ -646,7 +646,7 @@ func SplitVargenSuffix(name string) (base, suffix string) { func TypeHash(t *Type) uint32 { p := t.LinkString() - // Using 16 bytes hash is overkill, but reduces accidental collisions. - h := hash.Sum16([]byte(p)) + // Using a cryptographic hash is overkill but minimizes accidental collisions. + h := hash.Sum32([]byte(p)) return binary.LittleEndian.Uint32(h[:4]) } diff --git a/src/cmd/internal/hash/hash.go b/src/cmd/internal/hash/hash.go index a37368f50e..cdb24a2645 100644 --- a/src/cmd/internal/hash/hash.go +++ b/src/cmd/internal/hash/hash.go @@ -5,69 +5,26 @@ // Package hash implements hash functions used in the compiler toolchain. package hash -// TODO(rsc): Delete the 16 and 20 forms and use 32 at all call sites. - import ( "crypto/sha256" "hash" ) -const ( - // Size32 is the size of the 32-byte hash checksum. - Size32 = 32 - // Size20 is the size of the 20-byte hash checksum. - Size20 = 20 - // Size16 is the size of the 16-byte hash checksum. - Size16 = 16 -) +// Size32 is the size of the 32-byte hash functions [New32] and [Sum32]. +const Size32 = 32 -type shortHash struct { - hash.Hash - n int -} - -func (h *shortHash) Sum(b []byte) []byte { - old := b - sum := h.Hash.Sum(b) - return sum[:len(old)+h.n] -} - -// New32 returns a new [hash.Hash] computing the 32 bytes hash checksum. +// New32 returns a new [hash.Hash] computing the 32-byte hash checksum. +// Note that New32 and [Sum32] compute different hashes. func New32() hash.Hash { h := sha256.New() _, _ = h.Write([]byte{1}) // make this hash different from sha256 return h } -// New20 returns a new [hash.Hash] computing the 20 bytes hash checksum. -func New20() hash.Hash { - return &shortHash{New32(), 20} -} - -// New16 returns a new [hash.Hash] computing the 16 bytes hash checksum. -func New16() hash.Hash { - return &shortHash{New32(), 16} -} - -// Sum32 returns the 32 bytes checksum of the data. -func Sum32(data []byte) [Size32]byte { +// Sum32 returns a 32-byte checksum of the data. +// Note that Sum32 and [New32] compute different hashes. +func Sum32(data []byte) [32]byte { sum := sha256.Sum256(data) - sum[0] ^= 1 // make this hash different from sha256 + sum[0] ^= 0xff // make this hash different from sha256 return sum } - -// Sum20 returns the 20 bytes checksum of the data. -func Sum20(data []byte) [Size20]byte { - sum := Sum32(data) - var short [Size20]byte - copy(short[:], sum[4:]) - return short -} - -// Sum16 returns the 16 bytes checksum of the data. -func Sum16(data []byte) [Size16]byte { - sum := Sum32(data) - var short [Size16]byte - copy(short[:], sum[8:]) - return short -} diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go index bc22765abc..3299fbf4e6 100644 --- a/src/cmd/internal/obj/objfile.go +++ b/src/cmd/internal/obj/objfile.go @@ -494,7 +494,7 @@ func contentHash64(s *LSym) goobj.Hash64Type { // For now, we assume there is no circular dependencies among // hashed symbols. func (w *writer) contentHash(s *LSym) goobj.HashType { - h := hash.New20() + h := hash.New32() var tmp [14]byte // Include the size of the symbol in the hash. diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go index 8872579050..08c50ec72b 100644 --- a/src/cmd/internal/obj/sym.go +++ b/src/cmd/internal/obj/sym.go @@ -216,7 +216,7 @@ func (ctxt *Link) Int128Sym(hi, lo int64) *LSym { // GCLocalsSym generates a content-addressable sym containing data. func (ctxt *Link) GCLocalsSym(data []byte) *LSym { - sum := hash.Sum16(data) + sum := hash.Sum32(data) str := base64.StdEncoding.EncodeToString(sum[:16]) return ctxt.LookupInit(fmt.Sprintf("gclocals·%s", str), func(lsym *LSym) { lsym.P = data diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go index e6a525198f..6ff1d94383 100644 --- a/src/cmd/link/internal/ld/elf.go +++ b/src/cmd/link/internal/ld/elf.go @@ -1690,11 +1690,11 @@ func (ctxt *Link) doelf() { sb.SetType(sym.SRODATA) ldr.SetAttrSpecial(s, true) sb.SetReachable(true) - sb.SetSize(hash.Size20) + sb.SetSize(hash.Size32) slices.SortFunc(ctxt.Library, func(a, b *sym.Library) int { return strings.Compare(a.Pkg, b.Pkg) }) - h := hash.New20() + h := hash.New32() for _, l := range ctxt.Library { h.Write(l.Fingerprint[:]) } diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 2d8f964f35..b114ca2a3d 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -1022,7 +1022,7 @@ func typeSymbolMangle(name string) string { return name } if isType { - hb := hash.Sum20([]byte(name[5:])) + hb := hash.Sum32([]byte(name[5:])) prefix := "type:" if name[5] == '.' { prefix = "type:." @@ -1035,7 +1035,7 @@ func typeSymbolMangle(name string) string { if j == -1 || j <= i { j = len(name) } - hb := hash.Sum20([]byte(name[i+1 : j])) + hb := hash.Sum32([]byte(name[i+1 : j])) return name[:i+1] + base64.StdEncoding.EncodeToString(hb[:6]) + name[j:] } diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go index 0f3a183c61..0d6f608a3f 100644 --- a/src/cmd/objdump/objdump_test.go +++ b/src/cmd/objdump/objdump_test.go @@ -134,9 +134,9 @@ func testDisasm(t *testing.T, srcfname string, printCode bool, printGnuAsm bool, goarch = f[1] } - hash := hash.Sum16([]byte(fmt.Sprintf("%v-%v-%v-%v", srcfname, flags, printCode, printGnuAsm))) + hash := hash.Sum32([]byte(fmt.Sprintf("%v-%v-%v-%v", srcfname, flags, printCode, printGnuAsm))) tmp := t.TempDir() - hello := filepath.Join(tmp, fmt.Sprintf("hello-%x.exe", hash)) + hello := filepath.Join(tmp, fmt.Sprintf("hello-%x.exe", hash[:16])) args := []string{"build", "-o", hello} args = append(args, flags...) args = append(args, srcfname)