From 6318dab4e0ae3a1e4d1f6c8a1c4cc38b012954ae Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Mon, 14 Oct 2024 13:08:58 +0100 Subject: [PATCH] xts: avoid redundant bounds checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Small changes to improve performance of xts by about 6%. This removes all bounds checks, which can be verified by running: go build -gcflags="-d=ssa/check_bce/debug=1" . Before this would show mutiple Found IsInBounds/IsSliceInBounds in the inner loops of Encrypt and Decrypt. Tweaked the benchmark to use a larger buffer to make the improvement more visible. XTS is often used with disk sector sizes, so larger values are appropriate. goos: linux goarch: amd64 pkg: golang.org/x/crypto/xts cpu: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz │ before.txt │ after.txt │ │ sec/op │ sec/op vs base │ XTS-12 1.720µ ± 2% 1.619µ ± 2% -5.87% (p=0.000 n=10) │ before.txt │ after.txt │ │ B/s │ B/s vs base │ XTS-12 177.4Mi ± 2% 188.5Mi ± 2% +6.24% (p=0.000 n=10) │ before.txt │ after.txt │ │ B/op │ B/op vs base │ XTS-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ ¹ all samples are equal │ before.txt │ after.txt │ │ allocs/op │ allocs/op vs base │ XTS-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ ¹ all samples are equal --- xts/xts.go | 4 ++-- xts/xts_test.go | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/xts/xts.go b/xts/xts.go index d64f536f9d..65972a181d 100644 --- a/xts/xts.go +++ b/xts/xts.go @@ -87,7 +87,7 @@ func (c *Cipher) Encrypt(ciphertext, plaintext []byte, sectorNum uint64) { c.k2.Encrypt(tweak[:], tweak[:]) - for len(plaintext) > 0 { + for len(plaintext) >= blockSize && len(ciphertext) >= blockSize { for j := range tweak { ciphertext[j] = plaintext[j] ^ tweak[j] } @@ -126,7 +126,7 @@ func (c *Cipher) Decrypt(plaintext, ciphertext []byte, sectorNum uint64) { c.k2.Encrypt(tweak[:], tweak[:]) - for len(ciphertext) > 0 { + for len(ciphertext) >= blockSize && len(plaintext) >= blockSize { for j := range tweak { plaintext[j] = ciphertext[j] ^ tweak[j] } diff --git a/xts/xts_test.go b/xts/xts_test.go index 75db1c509b..cb6d26e866 100644 --- a/xts/xts_test.go +++ b/xts/xts_test.go @@ -106,13 +106,14 @@ func TestShorterCiphertext(t *testing.T) { func BenchmarkXTS(b *testing.B) { b.ReportAllocs() + b.SetBytes(320) c, err := NewCipher(aes.NewCipher, make([]byte, 32)) if err != nil { b.Fatalf("NewCipher failed: %s", err) } - plaintext := make([]byte, 32) - encrypted := make([]byte, 48) - decrypted := make([]byte, 48) + plaintext := make([]byte, 320) + encrypted := make([]byte, 336) + decrypted := make([]byte, 336) for i := 0; i < b.N; i++ { c.Encrypt(encrypted, plaintext, 0)