Skip to content

Commit 2e83d0b

Browse files
committed
crypto/cipher: optimize safeXORBytes
Optimize safeXORBytes based on this conversation: #35381
1 parent 3b5eec9 commit 2e83d0b

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

src/crypto/cipher/xor_generic.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,22 @@ func fastXORBytes(dst, a, b []byte, n int) {
6363

6464
// n needs to be smaller or equal than the length of a and b.
6565
func safeXORBytes(dst, a, b []byte, n int) {
66-
for i := 0; i < n; i++ {
66+
// Load multiple bytes so the compiler can recognize
67+
// and optimize them into single multi-byte loads
68+
w := n / 8
69+
for i := 0; i < w; i++ {
70+
offset := i * 8
71+
first32 := uint32(a[offset]) | uint32(a[offset+1])<<8 | uint32(a[offset+2])<<16 | uint32(a[offset+3])<<24
72+
first32 ^= uint32(b[offset]) | uint32(b[offset+1])<<8 | uint32(b[offset+2])<<16 | uint32(b[offset+3])<<24
73+
second32 := uint32(a[offset+4]) | uint32(a[offset+5])<<8 | uint32(a[offset+6])<<16 | uint32(a[offset+7])<<24
74+
second32 ^= uint32(b[offset+4]) | uint32(b[offset+5])<<8 | uint32(b[offset+6])<<16 | uint32(b[offset+7])<<24
75+
for j := 0; j < 4; j++ {
76+
dst[offset+j] = byte(first32 >> (j * 8))
77+
dst[offset+j+4] = byte(second32 >> (j * 8))
78+
}
79+
}
80+
81+
for i := w * 8; i < n; i++ {
6782
dst[i] = a[i] ^ b[i]
6883
}
6984
}

0 commit comments

Comments
 (0)