xor.go (1274B)
1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found src the LICENSE file. 4 5 package chacha20 6 7 import "runtime" 8 9 // Platforms that have fast unaligned 32-bit little endian accesses. 10 const unaligned = runtime.GOARCH == "386" || 11 runtime.GOARCH == "amd64" || 12 runtime.GOARCH == "arm64" || 13 runtime.GOARCH == "ppc64le" || 14 runtime.GOARCH == "s390x" 15 16 // addXor reads a little endian uint32 from src, XORs it with (a + b) and 17 // places the result in little endian byte order in dst. 18 func addXor(dst, src []byte, a, b uint32) { 19 _, _ = src[3], dst[3] // bounds check elimination hint 20 if unaligned { 21 // The compiler should optimize this code into 22 // 32-bit unaligned little endian loads and stores. 23 // TODO: delete once the compiler does a reliably 24 // good job with the generic code below. 25 // See issue #25111 for more details. 26 v := uint32(src[0]) 27 v |= uint32(src[1]) << 8 28 v |= uint32(src[2]) << 16 29 v |= uint32(src[3]) << 24 30 v ^= a + b 31 dst[0] = byte(v) 32 dst[1] = byte(v >> 8) 33 dst[2] = byte(v >> 16) 34 dst[3] = byte(v >> 24) 35 } else { 36 a += b 37 dst[0] = src[0] ^ byte(a) 38 dst[1] = src[1] ^ byte(a>>8) 39 dst[2] = src[2] ^ byte(a>>16) 40 dst[3] = src[3] ^ byte(a>>24) 41 } 42 }