diff --git a/crypto/src/crypto/modes/gcm/GcmUtilities.cs b/crypto/src/crypto/modes/gcm/GcmUtilities.cs
index 714e1fe49..cf21ace23 100644
--- a/crypto/src/crypto/modes/gcm/GcmUtilities.cs
+++ b/crypto/src/crypto/modes/gcm/GcmUtilities.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics;
#if NETCOREAPP3_0_OR_GREATER
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
@@ -219,12 +220,14 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm
z3 = h3;
}
- z1 ^= z3 ^ (z3 >> 1) ^ (z3 >> 2) ^ (z3 >> 7);
+ 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);
+ z2 ^= (z3 << 62) ^ (z3 << 57);
- z0 ^= z2 ^ (z2 >> 1) ^ (z2 >> 2) ^ (z2 >> 7);
- z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
+ z0 ^= z2 ^ (z2 >> 1) ^ (z2 >> 2) ^ (z2 >> 7);
+ z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
x.n0 = z0;
x.n1 = z1;
@@ -398,39 +401,22 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm
x.n1 = (x1 >> 16) | (x0 << 48);
}
- internal static void Square(ulong[] x, ulong[] z)
+ internal static void Square(ref FieldElement x)
{
- ulong[] t = new ulong[4];
- Interleave.Expand64To128Rev(x[0], t, 0);
- Interleave.Expand64To128Rev(x[1], t, 2);
+ ulong z1 = Interleave.Expand64To128Rev(x.n0, out ulong z0);
+ ulong z3 = Interleave.Expand64To128Rev(x.n1, out ulong z2);
- ulong z0 = t[0], z1 = t[1], z2 = t[2], z3 = t[3];
+ 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);
+ Debug.Assert(z2 << 63 == 0);
- z[0] = z0;
- z[1] = z1;
- }
-
- internal static void Square(ref FieldElement x)
- {
- ulong[] t = new ulong[4];
- Interleave.Expand64To128Rev(x.n0, t, 0);
- Interleave.Expand64To128Rev(x.n1, t, 2);
-
- ulong z0 = t[0], z1 = t[1], z2 = t[2], z3 = t[3];
-
- 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);
+ z0 ^= z2 ^ (z2 >> 1) ^ (z2 >> 2) ^ (z2 >> 7);
+// z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
+ z1 ^= (z2 << 62) ^ (z2 << 57);
x.n0 = z0;
x.n1 = z1;
diff --git a/crypto/src/math/raw/Interleave.cs b/crypto/src/math/raw/Interleave.cs
index a71b4a1b8..f22177fe8 100644
--- a/crypto/src/math/raw/Interleave.cs
+++ b/crypto/src/math/raw/Interleave.cs
@@ -90,14 +90,13 @@ namespace Org.BouncyCastle.Math.Raw
}
}
- internal static void Expand64To128Rev(ulong x, ulong[] z, int zOff)
+ internal static ulong Expand64To128Rev(ulong x, out ulong low)
{
#if NETCOREAPP3_0_OR_GREATER
if (Bmi2.X64.IsSupported)
{
- z[zOff ] = Bmi2.X64.ParallelBitDeposit(x >> 32, 0xAAAAAAAAAAAAAAAAUL);
- z[zOff + 1] = Bmi2.X64.ParallelBitDeposit(x , 0xAAAAAAAAAAAAAAAAUL);
- return;
+ low = Bmi2.X64.ParallelBitDeposit(x >> 32, 0xAAAAAAAAAAAAAAAAUL);
+ return Bmi2.X64.ParallelBitDeposit(x, 0xAAAAAAAAAAAAAAAAUL);
}
#endif
@@ -108,8 +107,8 @@ namespace Org.BouncyCastle.Math.Raw
x = Bits.BitPermuteStep(x, 0x0C0C0C0C0C0C0C0CUL, 2);
x = Bits.BitPermuteStep(x, 0x2222222222222222UL, 1);
- z[zOff ] = (x ) & M64R;
- z[zOff + 1] = (x << 1) & M64R;
+ low = (x ) & M64R;
+ return (x << 1) & M64R;
}
internal static uint Shuffle(uint x)
|