From e62d789086dcc8f340fc9c0b8c7b84e9ca88ddc5 Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Fri, 20 Sep 2024 11:20:26 +0200 Subject: [PATCH] Deprecate XorBytes Now that we no longer support Go 1.19, we might as well deprecate XorBytes and use the stdlib version instead. --- go.mod | 2 +- utils/xor/{xor_generic.go => xor.go} | 4 +- utils/xor/xor_arm.go | 60 -------------- utils/xor/xor_arm.s | 116 --------------------------- utils/xor/xor_old.go | 77 ------------------ 5 files changed, 3 insertions(+), 256 deletions(-) rename utils/xor/{xor_generic.go => xor.go} (87%) delete mode 100644 utils/xor/xor_arm.go delete mode 100644 utils/xor/xor_arm.s delete mode 100644 utils/xor/xor_old.go diff --git a/go.mod b/go.mod index bb691d8..0ddaff7 100644 --- a/go.mod +++ b/go.mod @@ -7,11 +7,11 @@ require ( github.com/stretchr/testify v1.9.0 github.com/wlynxg/anet v0.0.4 golang.org/x/net v0.28.0 - golang.org/x/sys v0.24.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/sys v0.24.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/utils/xor/xor_generic.go b/utils/xor/xor.go similarity index 87% rename from utils/xor/xor_generic.go rename to utils/xor/xor.go index 690549a..6eb64f0 100644 --- a/utils/xor/xor_generic.go +++ b/utils/xor/xor.go @@ -3,8 +3,6 @@ // SPDX-FileCopyrightText: 2024 The Pion community // SPDX-License-Identifier: MIT -//go:build go1.20 && !arm && !gccgo - // Package xor provides the XorBytes function. package xor @@ -14,6 +12,8 @@ import ( // XorBytes calls [crypto/suble.XORBytes]. // +// Deprecated: please call [crypto/subtle.XORBytes] instead. +// //revive:disable-next-line func XorBytes(dst, a, b []byte) int { return subtle.XORBytes(dst, a, b) diff --git a/utils/xor/xor_arm.go b/utils/xor/xor_arm.go deleted file mode 100644 index 25d6b72..0000000 --- a/utils/xor/xor_arm.go +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-FileCopyrightText: 2022 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !gccgo -// +build !gccgo - -// Package xor provides utility functions used by other Pion -// packages. ARM arch. -package xor - -import ( - "unsafe" - - "golang.org/x/sys/cpu" -) - -const wordSize = int(unsafe.Sizeof(uintptr(0))) // nolint:gosec -var hasNEON = cpu.ARM.HasNEON // nolint:gochecknoglobals - -func isAligned(a *byte) bool { - return uintptr(unsafe.Pointer(a))%uintptr(wordSize) == 0 -} - -// XorBytes xors the bytes in a and b. The destination should have enough -// space, otherwise xorBytes will panic. Returns the number of bytes xor'd. -// -//revive:disable-next-line -func XorBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - if n == 0 { - return 0 - } - // make sure dst has enough space - _ = dst[n-1] - - if hasNEON { - xorBytesNEON32(&dst[0], &a[0], &b[0], n) - } else if isAligned(&dst[0]) && isAligned(&a[0]) && isAligned(&b[0]) { - xorBytesARM32(&dst[0], &a[0], &b[0], n) - } else { - safeXORBytes(dst, a, b, n) - } - return n -} - -// n needs to be smaller or equal than the length of a and b. -func safeXORBytes(dst, a, b []byte, n int) { - for i := 0; i < n; i++ { - dst[i] = a[i] ^ b[i] - } -} - -//go:noescape -func xorBytesARM32(dst, a, b *byte, n int) - -//go:noescape -func xorBytesNEON32(dst, a, b *byte, n int) diff --git a/utils/xor/xor_arm.s b/utils/xor/xor_arm.s deleted file mode 100644 index 5e52a2d..0000000 --- a/utils/xor/xor_arm.s +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-FileCopyrightText: 2022 The Pion community -// SPDX-License-Identifier: MIT - -// go:build !gccgo -// +build !gccgo - -#include "textflag.h" - -// func xorBytesARM32(dst, a, b *byte, n int) -TEXT ·xorBytesARM32(SB), NOSPLIT|NOFRAME, $0 - MOVW dst+0(FP), R0 - MOVW a+4(FP), R1 - MOVW b+8(FP), R2 - MOVW n+12(FP), R3 - CMP $4, R3 - BLT less_than4 - -loop_4: - MOVW.P 4(R1), R4 - MOVW.P 4(R2), R5 - EOR R4, R5, R5 - MOVW.P R5, 4(R0) - - SUB $4, R3 - CMP $4, R3 - BGE loop_4 - -less_than4: - CMP $2, R3 - BLT less_than2 - MOVH.P 2(R1), R4 - MOVH.P 2(R2), R5 - EOR R4, R5, R5 - MOVH.P R5, 2(R0) - - SUB $2, R3 - -less_than2: - CMP $0, R3 - BEQ end - MOVB (R1), R4 - MOVB (R2), R5 - EOR R4, R5, R5 - MOVB R5, (R0) -end: - RET - -// func xorBytesNEON32(dst, a, b *byte, n int) -TEXT ·xorBytesNEON32(SB), NOSPLIT|NOFRAME, $0 - MOVW dst+0(FP), R0 - MOVW a+4(FP), R1 - MOVW b+8(FP), R2 - MOVW n+12(FP), R3 - CMP $32, R3 - BLT less_than32 - -loop_32: - WORD $0xF421020D // vld1.u8 {q0, q1}, [r1]! - WORD $0xF422420D // vld1.u8 {q2, q3}, [r2]! - WORD $0xF3004154 // veor q2, q0, q2 - WORD $0xF3026156 // veor q3, q1, q3 - WORD $0xF400420D // vst1.u8 {q2, q3}, [r0]! - - SUB $32, R3 - CMP $32, R3 - BGE loop_32 - -less_than32: - CMP $16, R3 - BLT less_than16 - WORD $0xF4210A0D // vld1.u8 q0, [r1]! - WORD $0xF4222A0D // vld1.u8 q1, [r2]! - WORD $0xF3002152 // veor q1, q0, q1 - WORD $0xF4002A0D // vst1.u8 {q1}, [r0]! - - SUB $16, R3 - -less_than16: - CMP $8, R3 - BLT less_than8 - WORD $0xF421070D // vld1.u8 d0, [r1]! - WORD $0xF422170D // vld1.u8 d1, [r2]! - WORD $0xF3001111 // veor d1, d0, d1 - WORD $0xF400170D // vst1.u8 {d1}, [r0]! - - SUB $8, R3 - -less_than8: - CMP $4, R3 - BLT less_than4 - MOVW.P 4(R1), R4 - MOVW.P 4(R2), R5 - EOR R4, R5, R5 - MOVW.P R5, 4(R0) - - SUB $4, R3 - -less_than4: - CMP $2, R3 - BLT less_than2 - MOVH.P 2(R1), R4 - MOVH.P 2(R2), R5 - EOR R4, R5, R5 - MOVH.P R5, 2(R0) - - SUB $2, R3 - -less_than2: - CMP $0, R3 - BEQ end - MOVB (R1), R4 - MOVB (R2), R5 - EOR R4, R5, R5 - MOVB R5, (R0) -end: - RET diff --git a/utils/xor/xor_old.go b/utils/xor/xor_old.go deleted file mode 100644 index f46f4d9..0000000 --- a/utils/xor/xor_old.go +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-FileCopyrightText: 2013 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause -// SPDX-FileCopyrightText: 2022 The Pion community -// SPDX-License-Identifier: MIT - -//go:build (!go1.20 && !arm) || gccgo - -// Package xor provides the XorBytes function. -// This version is only used on Go up to version 1.19. -package xor - -import ( - "runtime" - "unsafe" -) - -const ( - wordSize = int(unsafe.Sizeof(uintptr(0))) // nolint:gosec - supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x" // nolint:gochecknoglobals -) - -func isAligned(a *byte) bool { - return uintptr(unsafe.Pointer(a))%uintptr(wordSize) == 0 -} - -// XorBytes xors the bytes in a and b. The destination should have enough -// space, otherwise xorBytes will panic. Returns the number of bytes xor'd. -// -//revive:disable-next-line -func XorBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - if n == 0 { - return 0 - } - - switch { - case supportsUnaligned: - fastXORBytes(dst, a, b, n) - case isAligned(&dst[0]) && isAligned(&a[0]) && isAligned(&b[0]): - fastXORBytes(dst, a, b, n) - default: - safeXORBytes(dst, a, b, n) - } - return n -} - -// fastXORBytes xors in bulk. It only works on architectures that -// support unaligned read/writes. -// n needs to be smaller or equal than the length of a and b. -func fastXORBytes(dst, a, b []byte, n int) { - // Assert dst has enough space - _ = dst[n-1] - - w := n / wordSize - if w > 0 { - dw := *(*[]uintptr)(unsafe.Pointer(&dst)) // nolint:gosec - aw := *(*[]uintptr)(unsafe.Pointer(&a)) // nolint:gosec - bw := *(*[]uintptr)(unsafe.Pointer(&b)) // nolint:gosec - for i := 0; i < w; i++ { - dw[i] = aw[i] ^ bw[i] - } - } - - for i := (n - n%wordSize); i < n; i++ { - dst[i] = a[i] ^ b[i] - } -} - -// n needs to be smaller or equal than the length of a and b. -func safeXORBytes(dst, a, b []byte, n int) { - for i := 0; i < n; i++ { - dst[i] = a[i] ^ b[i] - } -}