diff --git a/crypto/src/crypto/modes/gcm/GcmUtilities.cs b/crypto/src/crypto/modes/gcm/GcmUtilities.cs
index de41d88f4..d8ab2ca73 100644
--- a/crypto/src/crypto/modes/gcm/GcmUtilities.cs
+++ b/crypto/src/crypto/modes/gcm/GcmUtilities.cs
@@ -46,6 +46,13 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm
return tmp;
}
+ internal static ulong[] OneAsUlongs()
+ {
+ ulong[] tmp = new ulong[2];
+ tmp[0] = 1UL << 63;
+ return tmp;
+ }
+
internal static byte[] AsBytes(uint[] x)
{
return Pack.UInt32_To_BE(x);
@@ -56,6 +63,18 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm
Pack.UInt32_To_BE(x, z, 0);
}
+ internal static byte[] AsBytes(ulong[] x)
+ {
+ byte[] z = new byte[16];
+ Pack.UInt64_To_BE(x, z, 0);
+ return z;
+ }
+
+ internal static void AsBytes(ulong[] x, byte[] z)
+ {
+ Pack.UInt64_To_BE(x, z, 0);
+ }
+
internal static uint[] AsUints(byte[] bs)
{
uint[] output = new uint[4];
@@ -68,6 +87,18 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm
Pack.BE_To_UInt32(bs, 0, output);
}
+ internal static ulong[] AsUlongs(byte[] x)
+ {
+ ulong[] z = new ulong[2];
+ Pack.BE_To_UInt64(x, 0, z);
+ return z;
+ }
+
+ public static void AsUlongs(byte[] x, ulong[] z)
+ {
+ Pack.BE_To_UInt64(x, 0, z);
+ }
+
internal static void Multiply(byte[] x, byte[] y)
{
uint[] t1 = GcmUtilities.AsUints(x);
@@ -80,7 +111,7 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm
{
uint r00 = x[0], r01 = x[1], r02 = x[2], r03 = x[3];
uint r10 = 0, r11 = 0, r12 = 0, r13 = 0;
-
+
for (int i = 0; i < 4; ++i)
{
int bits = (int)y[i];
@@ -93,9 +124,9 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm
r13 ^= (r03 & m1);
uint m2 = (uint)((int)(r03 << 31) >> 8);
- r03 = (r03 >> 1) | (r02 << 63);
- r02 = (r02 >> 1) | (r01 << 63);
- r01 = (r01 >> 1) | (r00 << 63);
+ r03 = (r03 >> 1) | (r02 << 31);
+ r02 = (r02 >> 1) | (r01 << 31);
+ r01 = (r01 >> 1) | (r00 << 31);
r00 = (r00 >> 1) ^ (m2 & E1);
}
}
@@ -119,7 +150,7 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm
r10 ^= (r00 & m1);
r11 ^= (r01 & m1);
- ulong m2 = (r01 << 63) >> 8;
+ ulong m2 = (ulong)((long)(r01 << 63) >> 8);
r01 = (r01 >> 1) | (r00 << 63);
r00 = (r00 >> 1) ^ (m2 & E1L);
}
@@ -272,5 +303,17 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm
z[2] = x[2] ^ y[2];
z[3] = x[3] ^ y[3];
}
+
+ internal static void Xor(ulong[] x, ulong[] y)
+ {
+ x[0] ^= y[0];
+ x[1] ^= y[1];
+ }
+
+ internal static void Xor(ulong[] x, ulong[] y, ulong[] z)
+ {
+ z[0] = x[0] ^ y[0];
+ z[1] = x[1] ^ y[1];
+ }
}
}
diff --git a/crypto/src/crypto/util/Pack.cs b/crypto/src/crypto/util/Pack.cs
index 087cb7cea..dc00ab450 100644
--- a/crypto/src/crypto/util/Pack.cs
+++ b/crypto/src/crypto/util/Pack.cs
@@ -117,6 +117,22 @@ namespace Org.BouncyCastle.Crypto.Utilities
UInt32_To_BE((uint)(n), bs, off + 4);
}
+ internal static byte[] UInt64_To_BE(ulong[] ns)
+ {
+ byte[] bs = new byte[8 * ns.Length];
+ UInt64_To_BE(ns, bs, 0);
+ return bs;
+ }
+
+ internal static void UInt64_To_BE(ulong[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.Length; ++i)
+ {
+ UInt64_To_BE(ns[i], bs, off);
+ off += 8;
+ }
+ }
+
internal static ulong BE_To_UInt64(byte[] bs)
{
uint hi = BE_To_UInt32(bs);
@@ -131,6 +147,15 @@ namespace Org.BouncyCastle.Crypto.Utilities
return ((ulong)hi << 32) | (ulong)lo;
}
+ internal static void BE_To_UInt64(byte[] bs, int off, ulong[] ns)
+ {
+ for (int i = 0; i < ns.Length; ++i)
+ {
+ ns[i] = BE_To_UInt64(bs, off);
+ off += 8;
+ }
+ }
+
internal static void UInt16_To_LE(ushort n, byte[] bs)
{
bs[0] = (byte)(n);
|