#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) using System; using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Modes.Gcm { public sealed class Tables8kGcmMultiplier : IGcmMultiplier { private byte[] H; private uint[][][] M; public void Init(byte[] H) { if (M == null) { M = new uint[32][][]; } else if (Arrays.AreEqual(this.H, H)) { return; } this.H = Arrays.Clone(H); M[0] = new uint[16][]; M[1] = new uint[16][]; M[0][0] = new uint[4]; M[1][0] = new uint[4]; M[1][8] = GcmUtilities.AsUints(H); for (int j = 4; j >= 1; j >>= 1) { uint[] tmp = (uint[])M[1][j + j].Clone(); GcmUtilities.MultiplyP(tmp); M[1][j] = tmp; } { uint[] tmp = (uint[])M[1][1].Clone(); GcmUtilities.MultiplyP(tmp); M[0][8] = tmp; } for (int j = 4; j >= 1; j >>= 1) { uint[] tmp = (uint[])M[0][j + j].Clone(); GcmUtilities.MultiplyP(tmp); M[0][j] = tmp; } for (int i = 0; ; ) { for (int j = 2; j < 16; j += j) { for (int k = 1; k < j; ++k) { uint[] tmp = (uint[])M[i][j].Clone(); GcmUtilities.Xor(tmp, M[i][k]); M[i][j + k] = tmp; } } if (++i == 32) return; if (i > 1) { M[i] = new uint[16][]; M[i][0] = new uint[4]; for (int j = 8; j > 0; j >>= 1) { uint[] tmp = (uint[])M[i - 2][j].Clone(); GcmUtilities.MultiplyP8(tmp); M[i][j] = tmp; } } } } #if true //!ENABLE_IL2CPP || UNITY_WEBGL public void MultiplyH(byte[] x) { uint[] z = new uint[4]; for (int i = 15; i >= 0; --i) { //GcmUtilities.Xor(z, M[i + i][x[i] & 0x0f]); uint[] m = M[i + i][x[i] & 0x0f]; z[0] ^= m[0]; z[1] ^= m[1]; z[2] ^= m[2]; z[3] ^= m[3]; //GcmUtilities.Xor(z, M[i + i + 1][(x[i] & 0xf0) >> 4]); m = M[i + i + 1][(x[i] & 0xf0) >> 4]; z[0] ^= m[0]; z[1] ^= m[1]; z[2] ^= m[2]; z[3] ^= m[3]; } Pack.UInt32_To_BE(z, x, 0); } #else uint[] z = new uint[4]; public unsafe void MultiplyH(byte[] x) { //Array.Clear(z, 0, z.Length); fixed (byte* px = x) fixed (uint* pz = z) { pz[0] = pz[1] = pz[2] = pz[3] = 0; for (int i = 15; i >= 0; --i) { //GcmUtilities.Xor(z, M[i + i][x[i] & 0x0f]); //uint[] m = M[i + i][x[i] & 0x0f]; //z[0] ^= m[0]; //z[1] ^= m[1]; //z[2] ^= m[2]; //z[3] ^= m[3]; fixed (uint* pm = M[i + i][px[i] & 0x0f]) { pz[0] ^= pm[0]; pz[1] ^= pm[1]; pz[2] ^= pm[2]; pz[3] ^= pm[3]; } //GcmUtilities.Xor(z, M[i + i + 1][(x[i] & 0xf0) >> 4]); //m = M[i + i + 1][(x[i] & 0xf0) >> 4]; //z[0] ^= m[0]; //z[1] ^= m[1]; //z[2] ^= m[2]; //z[3] ^= m[3]; fixed (uint* pm = M[i + i + 1][(px[i] & 0xf0) >> 4]) { pz[0] ^= pm[0]; pz[1] ^= pm[1]; pz[2] ^= pm[2]; pz[3] ^= pm[3]; } } //int off = 0; //for (int i = 0; i < 4; ++i) //{ // uint n = pz[i]; // // px[off + 0] = (byte)(n >> 24); // px[off + 1] = (byte)(n >> 16); // px[off + 2] = (byte)(n >> 8); // px[off + 3] = (byte)(n); // // off += 4; //} // i = 0 uint n = pz[0]; px[0] = (byte)(n >> 24); px[1] = (byte)(n >> 16); px[2] = (byte)(n >> 8); px[3] = (byte)(n); // i = 1 n = pz[1]; px[4] = (byte)(n >> 24); px[5] = (byte)(n >> 16); px[6] = (byte)(n >> 8); px[7] = (byte)(n); // i = 2 n = pz[2]; px[8] = (byte)(n >> 24); px[9] = (byte)(n >> 16); px[10] = (byte)(n >> 8); px[11] = (byte)(n); // i = 3 n = pz[3]; px[12] = (byte)(n >> 24); px[13] = (byte)(n >> 16); px[14] = (byte)(n >> 8); px[15] = (byte)(n); } //Pack.UInt32_To_BE(z, x, 0); } #endif } } #endif