mirror of
https://github.com/XTLS/REALITY.git
synced 2025-08-22 14:38:35 +00:00
For #69536 Change-Id: I2d7b6e7b9932d0f0f582a5ab0bb871395dc2a1e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/626675 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Daniel McCarney <daniel@binaryparadox.net> Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Filippo Valsorda <filippo@golang.org>
62 lines
1.6 KiB
Go
62 lines
1.6 KiB
Go
// Copyright 2013 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package subtle
|
|
|
|
import (
|
|
"runtime"
|
|
"unsafe"
|
|
)
|
|
|
|
const wordSize = unsafe.Sizeof(uintptr(0))
|
|
|
|
const supportsUnaligned = runtime.GOARCH == "386" ||
|
|
runtime.GOARCH == "amd64" ||
|
|
runtime.GOARCH == "ppc64" ||
|
|
runtime.GOARCH == "ppc64le" ||
|
|
runtime.GOARCH == "s390x"
|
|
|
|
func xorBytes(dstb, xb, yb *byte, n int) {
|
|
// xorBytes assembly is written using pointers and n. Back to slices.
|
|
dst := unsafe.Slice(dstb, n)
|
|
x := unsafe.Slice(xb, n)
|
|
y := unsafe.Slice(yb, n)
|
|
|
|
if supportsUnaligned || aligned(dstb, xb, yb) {
|
|
xorLoop(words(dst), words(x), words(y))
|
|
if uintptr(n)%wordSize == 0 {
|
|
return
|
|
}
|
|
done := n &^ int(wordSize-1)
|
|
dst = dst[done:]
|
|
x = x[done:]
|
|
y = y[done:]
|
|
}
|
|
xorLoop(dst, x, y)
|
|
}
|
|
|
|
// aligned reports whether dst, x, and y are all word-aligned pointers.
|
|
func aligned(dst, x, y *byte) bool {
|
|
return (uintptr(unsafe.Pointer(dst))|uintptr(unsafe.Pointer(x))|uintptr(unsafe.Pointer(y)))&(wordSize-1) == 0
|
|
}
|
|
|
|
// words returns a []uintptr pointing at the same data as x,
|
|
// with any trailing partial word removed.
|
|
func words(x []byte) []uintptr {
|
|
n := uintptr(len(x)) / wordSize
|
|
if n == 0 {
|
|
// Avoid creating a *uintptr that refers to data smaller than a uintptr;
|
|
// see issue 59334.
|
|
return nil
|
|
}
|
|
return unsafe.Slice((*uintptr)(unsafe.Pointer(&x[0])), n)
|
|
}
|
|
|
|
func xorLoop[T byte | uintptr](dst, x, y []T) {
|
|
x = x[:len(dst)] // remove bounds check in loop
|
|
y = y[:len(dst)] // remove bounds check in loop
|
|
for i := range dst {
|
|
dst[i] = x[i] ^ y[i]
|
|
}
|
|
} |