diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-02-16 22:38:56 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-02-16 22:38:56 +0700 |
commit | 2dbbba4f577c3cd687f67d6ede1d62ea40a7fe1d (patch) | |
tree | e782a95d11c17291592d101a87a2c621f75e3c30 /crypto/src/crypto/modes/gcm/GcmUtilities.cs | |
parent | CMS support for key ID + public key recipients in key agreement (diff) | |
download | BouncyCastle.NET-ed25519-2dbbba4f577c3cd687f67d6ede1d62ea40a7fe1d.tar.xz |
GCM perf. opts.
Diffstat (limited to '')
-rw-r--r-- | crypto/src/crypto/modes/gcm/GcmUtilities.cs | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/crypto/src/crypto/modes/gcm/GcmUtilities.cs b/crypto/src/crypto/modes/gcm/GcmUtilities.cs index a239e9ec0..b2c74d7d0 100644 --- a/crypto/src/crypto/modes/gcm/GcmUtilities.cs +++ b/crypto/src/crypto/modes/gcm/GcmUtilities.cs @@ -140,6 +140,108 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm x.n1 = z1; } +#if NETCOREAPP3_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Vector128<ulong> Load(byte[] x) + { + AsFieldElement(x, out FieldElement X); + return Vector128.Create(X.n1, X.n0); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Vector128<ulong> Multiply(Vector128<ulong> X, Vector128<ulong> Y) + { + MultiplyExt(X, Y, out var Z0, out var Z1, out var Z2); + return Reduce3(Z0, Z1, Z2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void MultiplyExt(Vector128<ulong> X, Vector128<ulong> Y, out Vector128<ulong> Z0, + out Vector128<ulong> Z1, out Vector128<ulong> Z2) + { + if (!Pclmulqdq.IsSupported) + throw new PlatformNotSupportedException(nameof(GcmUtilities.MultiplyExt)); + + Z0 = Pclmulqdq.CarrylessMultiply(X, Y, 0x00); + Z1 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X, Y, 0x01), + Pclmulqdq.CarrylessMultiply(X, Y, 0x10)); + Z2 = Pclmulqdq.CarrylessMultiply(X, Y, 0x11); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Vector128<ulong> Reduce2(Vector128<ulong> Z0, Vector128<ulong> Z2) + { + ulong t3 = Z0.GetElement(0); + ulong t2 = Z0.GetElement(1); + ulong t1 = Z2.GetElement(0); + ulong t0 = Z2.GetElement(1); + + ulong z0 = (t0 << 1) | (t1 >> 63); + ulong z1 = (t1 << 1) | (t2 >> 63); + ulong z2 = (t2 << 1) | (t3 >> 63); + ulong z3 = (t3 << 1); + + Debug.Assert(z3 << 63 == 0); + + z1 ^= z3 ^ (z3 >> 1) ^ (z3 >> 2) ^ (z3 >> 7); +// z2 ^= (z3 << 63) ^ (z3 << 62) ^ (z3 << 57); + z2 ^= (z3 << 62) ^ (z3 << 57); + + z0 ^= z2 ^ (z2 >> 1) ^ (z2 >> 2) ^ (z2 >> 7); + z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57); + + return Vector128.Create(z1, z0); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Vector128<ulong> Reduce3(Vector128<ulong> Z0, Vector128<ulong> Z1, Vector128<ulong> Z2) + { + ulong t3 = Z0.GetElement(0); + ulong t2 = Z0.GetElement(1) ^ Z1.GetElement(0); + ulong t1 = Z2.GetElement(0) ^ Z1.GetElement(1); + ulong t0 = Z2.GetElement(1); + + ulong z0 = (t0 << 1) | (t1 >> 63); + ulong z1 = (t1 << 1) | (t2 >> 63); + ulong z2 = (t2 << 1) | (t3 >> 63); + ulong z3 = (t3 << 1); + + Debug.Assert(z3 << 63 == 0); + + z1 ^= z3 ^ (z3 >> 1) ^ (z3 >> 2) ^ (z3 >> 7); +// z2 ^= (z3 << 63) ^ (z3 << 62) ^ (z3 << 57); + z2 ^= (z3 << 62) ^ (z3 << 57); + + z0 ^= z2 ^ (z2 >> 1) ^ (z2 >> 2) ^ (z2 >> 7); + z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57); + + return Vector128.Create(z1, z0); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void Store(Vector128<ulong> X, byte[] z) + { + AsBytes(X.GetElement(1), X.GetElement(0), z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Vector128<ulong> Square(Vector128<ulong> X) + { + SquareExt(X, out var Z0, out var Z2); + return Reduce2(Z0, Z2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void SquareExt(Vector128<ulong> X, out Vector128<ulong> Z0, out Vector128<ulong> Z2) + { + if (!Pclmulqdq.IsSupported) + throw new PlatformNotSupportedException(nameof(GcmUtilities.SquareExt)); + + Z0 = Pclmulqdq.CarrylessMultiply(X, X, 0x00); + Z2 = Pclmulqdq.CarrylessMultiply(X, X, 0x11); + } +#endif + internal static void MultiplyP7(ref FieldElement x) { ulong x0 = x.n0, x1 = x.n1; |