diff options
-rw-r--r-- | crypto/src/crypto/modes/gcm/GcmUtilities.cs | 8 | ||||
-rw-r--r-- | crypto/src/crypto/modes/gcm/Tables8kGcmMultiplier.cs | 41 |
2 files changed, 32 insertions, 17 deletions
diff --git a/crypto/src/crypto/modes/gcm/GcmUtilities.cs b/crypto/src/crypto/modes/gcm/GcmUtilities.cs index 1dd4cd612..ed88240f2 100644 --- a/crypto/src/crypto/modes/gcm/GcmUtilities.cs +++ b/crypto/src/crypto/modes/gcm/GcmUtilities.cs @@ -349,6 +349,14 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm y[yOff + 1] = (x1 >> 8) | (x0 << 56); } + internal static void MultiplyP16(ulong[] x) + { + ulong x0 = x[0], x1 = x[1]; + ulong c = x1 << 48; + x[0] = (x0 >> 16) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + x[1] = (x1 >> 16) | (x0 << 48); + } + internal static void Square(ulong[] x, ulong[] z) { ulong[] t = new ulong[4]; diff --git a/crypto/src/crypto/modes/gcm/Tables8kGcmMultiplier.cs b/crypto/src/crypto/modes/gcm/Tables8kGcmMultiplier.cs index 81f60bb2f..8921c8621 100644 --- a/crypto/src/crypto/modes/gcm/Tables8kGcmMultiplier.cs +++ b/crypto/src/crypto/modes/gcm/Tables8kGcmMultiplier.cs @@ -15,7 +15,7 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm { if (T == null) { - T = new ulong[32][]; + T = new ulong[2][]; } else if (Arrays.AreEqual(this.H, H)) { @@ -24,25 +24,25 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm this.H = Arrays.Clone(H); - for (int i = 0; i < 32; ++i) + for (int i = 0; i < 2; ++i) { - ulong[] t = T[i] = new ulong[32]; + ulong[] t = T[i] = new ulong[512]; // t[0] = 0 if (i == 0) { - // t[1] = H.p^3 + // t[1] = H.p^7 GcmUtilities.AsUlongs(this.H, t, 2); - GcmUtilities.MultiplyP3(t, 2, t, 2); + GcmUtilities.MultiplyP7(t, 2, t, 2); } else { - // t[1] = T[i-1][1].p^4 - GcmUtilities.MultiplyP4(T[i - 1], 2, t, 2); + // t[1] = T[i-1][1].p^8 + GcmUtilities.MultiplyP8(T[i - 1], 2, t, 2); } - for (int n = 2; n < 16; n += 2) + for (int n = 2; n < 256; n += 2) { // t[2.n] = t[n].p^-1 GcmUtilities.DivideP(t, n, t, n << 1); @@ -55,23 +55,30 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm public void MultiplyH(byte[] x) { + ulong[] T0 = T[0], T1 = T[1]; + //ulong[] z = new ulong[2]; - //for (int i = 15; i >= 0; --i) + //for (int i = 14; i >= 0; i -= 2) //{ - // GcmUtilities.Xor(z, 0, T[i + i + 1], (x[i] & 0x0F) << 1); - // GcmUtilities.Xor(z, 0, T[i + i], (x[i] & 0xF0) >> 3); + // GcmUtilities.MultiplyP16(z); + // GcmUtilities.Xor(z, 0, T0, x[i] << 1); + // GcmUtilities.Xor(z, 0, T1, x[i + 1] << 1); //} //Pack.UInt64_To_BE(z, x, 0); - ulong z0 = 0, z1 = 0; + int vPos = x[15] << 1; + int uPos = x[14] << 1; + ulong z1 = T0[uPos + 1] ^ T1[vPos + 1]; + ulong z0 = T0[uPos] ^ T1[vPos]; - for (int i = 15; i >= 0; --i) + for (int i = 12; i >= 0; i -= 2) { - ulong[] tu = T[i + i + 1], tv = T[i + i]; - int uPos = (x[i] & 0x0F) << 1, vPos = (x[i] & 0xF0) >> 3; + vPos = x[i + 1] << 1; + uPos = x[i] << 1; - z0 ^= tu[uPos + 0] ^ tv[vPos + 0]; - z1 ^= tu[uPos + 1] ^ tv[vPos + 1]; + ulong c = z1 << 48; + z1 = T0[uPos + 1] ^ T1[vPos + 1] ^ ((z1 >> 16) | (z0 << 48)); + z0 = T0[uPos] ^ T1[vPos] ^ (z0 >> 16) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); } Pack.UInt64_To_BE(z0, x, 0); |