sha3: mark xorInUnaligned with go:nocheckptr

It is unclear whether unaligned reads should be allowed, or if they
are even actually a good idea here. However, while we figure that out,
we should un-break 'go test -race' for users of this package.

Updates golang/go#37644
Updates golang/go#37298
Updates golang/go#37715
Updates golang/go#34972
Updates golang/go#35128

Change-Id: I088f5703023e4f05ee274a6753e925973f12ac1b
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/222855
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
diff --git a/sha3/sha3_test.go b/sha3/sha3_test.go
index 005a242..83bd619 100644
--- a/sha3/sha3_test.go
+++ b/sha3/sha3_test.go
@@ -17,6 +17,7 @@
 	"encoding/json"
 	"fmt"
 	"hash"
+	"math/rand"
 	"os"
 	"strings"
 	"testing"
@@ -306,8 +307,14 @@
 }
 
 // sequentialBytes produces a buffer of size consecutive bytes 0x00, 0x01, ..., used for testing.
+//
+// The alignment of each slice is intentionally randomized to detect alignment
+// issues in the implementation. See https://golang.org/issue/37644.
+// Ideally, the compiler should fuzz the alignment itself.
+// (See https://golang.org/issue/35128.)
 func sequentialBytes(size int) []byte {
-	result := make([]byte, size)
+	alignmentOffset := rand.Intn(8)
+	result := make([]byte, size+alignmentOffset)[alignmentOffset:]
 	for i := range result {
 		result[i] = byte(i)
 	}
diff --git a/sha3/xor_unaligned.go b/sha3/xor_unaligned.go
index a3d0686..5ede2c6 100644
--- a/sha3/xor_unaligned.go
+++ b/sha3/xor_unaligned.go
@@ -16,6 +16,17 @@
 	return (*[maxRate]byte)(unsafe.Pointer(b))
 }
 
+//go:nocheckptr
+//
+// xorInUnaligned intentionally reads the input buffer as an unaligned slice of
+// integers. The language spec is not clear on whether that is allowed.
+// See:
+// 	https://golang.org/issue/37644
+// 	https://golang.org/issue/37298
+// 	https://golang.org/issue/35381
+
+// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
+// XOR buf.
 func xorInUnaligned(d *state, buf []byte) {
 	n := len(buf)
 	bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]