From dd6a63a7d029be8a6371aa53f879ff78a95545e2 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 14 Feb 2023 23:21:55 +0700 Subject: GCM perf. tweak --- crypto/src/crypto/modes/GCMBlockCipher.cs | 41 +++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/crypto/src/crypto/modes/GCMBlockCipher.cs b/crypto/src/crypto/modes/GCMBlockCipher.cs index 9ab3a8e8c..26b590ef9 100644 --- a/crypto/src/crypto/modes/GCMBlockCipher.cs +++ b/crypto/src/crypto/modes/GCMBlockCipher.cs @@ -1084,14 +1084,14 @@ namespace Org.BouncyCastle.Crypto.Modes InitCipher(); } - Span ctrBlock = stackalloc byte[BlockSize]; + Span ctrBlocks = stackalloc byte[BlockSize * 2]; + GetNextCtrBlocks2(ctrBlocks); - GetNextCtrBlock(ctrBlock); #if NETCOREAPP3_0_OR_GREATER if (Sse2.IsSupported && Unsafe.SizeOf>() == BlockSize) { var t0 = MemoryMarshal.Read>(input); - var t1 = MemoryMarshal.Read>(ctrBlock); + var t1 = MemoryMarshal.Read>(ctrBlocks); var t2 = MemoryMarshal.Read>(S.AsSpan()); t1 = Sse2.Xor(t1, t0); @@ -1105,10 +1105,10 @@ namespace Org.BouncyCastle.Crypto.Modes { for (int i = 0; i < BlockSize; i += 4) { - byte c0 = (byte)(ctrBlock[i + 0] ^ input[i + 0]); - byte c1 = (byte)(ctrBlock[i + 1] ^ input[i + 1]); - byte c2 = (byte)(ctrBlock[i + 2] ^ input[i + 2]); - byte c3 = (byte)(ctrBlock[i + 3] ^ input[i + 3]); + byte c0 = (byte)(ctrBlocks[i + 0] ^ input[i + 0]); + byte c1 = (byte)(ctrBlocks[i + 1] ^ input[i + 1]); + byte c2 = (byte)(ctrBlocks[i + 2] ^ input[i + 2]); + byte c3 = (byte)(ctrBlocks[i + 3] ^ input[i + 3]); S[i + 0] ^= c0; S[i + 1] ^= c1; @@ -1125,13 +1125,13 @@ namespace Org.BouncyCastle.Crypto.Modes input = input[BlockSize..]; output = output[BlockSize..]; + ctrBlocks = ctrBlocks[BlockSize..]; - GetNextCtrBlock(ctrBlock); #if NETCOREAPP3_0_OR_GREATER if (Sse2.IsSupported && Unsafe.SizeOf>() == BlockSize) { var t0 = MemoryMarshal.Read>(input); - var t1 = MemoryMarshal.Read>(ctrBlock); + var t1 = MemoryMarshal.Read>(ctrBlocks); var t2 = MemoryMarshal.Read>(S.AsSpan()); t1 = Sse2.Xor(t1, t0); @@ -1145,10 +1145,10 @@ namespace Org.BouncyCastle.Crypto.Modes { for (int i = 0; i < BlockSize; i += 4) { - byte c0 = (byte)(ctrBlock[i + 0] ^ input[i + 0]); - byte c1 = (byte)(ctrBlock[i + 1] ^ input[i + 1]); - byte c2 = (byte)(ctrBlock[i + 2] ^ input[i + 2]); - byte c3 = (byte)(ctrBlock[i + 3] ^ input[i + 3]); + byte c0 = (byte)(ctrBlocks[i + 0] ^ input[i + 0]); + byte c1 = (byte)(ctrBlocks[i + 1] ^ input[i + 1]); + byte c2 = (byte)(ctrBlocks[i + 2] ^ input[i + 2]); + byte c3 = (byte)(ctrBlocks[i + 3] ^ input[i + 3]); S[i + 0] ^= c0; S[i + 1] ^= c1; @@ -1179,6 +1179,21 @@ namespace Org.BouncyCastle.Crypto.Modes cipher.ProcessBlock(counter, block); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void GetNextCtrBlocks2(Span blocks) + { + if (blocksRemaining < 2) + throw new InvalidOperationException("Attempt to process too many blocks"); + + blocksRemaining -= 2; + + Pack.UInt32_To_BE(++counter32, counter, 12); + cipher.ProcessBlock(counter, blocks); + + Pack.UInt32_To_BE(++counter32, counter, 12); + cipher.ProcessBlock(counter, blocks[BlockSize..]); + } + private void ProcessPartial(Span partialBlock, Span output) { Span ctrBlock = stackalloc byte[BlockSize]; -- cgit 1.4.1