<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

GcmUtilities

static class GcmUtilities
using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; using System.Runtime.CompilerServices; namespace Org.BouncyCastle.Crypto.Modes.Gcm { internal static class GcmUtilities { internal struct FieldElement { internal ulong n0; internal ulong n1; } private const uint E1 = 3774873600; private const ulong E1UL = 16212958658533785600; internal static void One(out FieldElement x) { x.n0 = 9223372036854775808; x.n1 = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void AsBytes(ulong x0, ulong x1, byte[] z) { Pack.UInt64_To_BE(x0, z, 0); Pack.UInt64_To_BE(x1, z, 8); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void AsBytes(ref FieldElement x, byte[] z) { AsBytes(x.n0, x.n1, z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void AsFieldElement(byte[] x, out FieldElement z) { z.n0 = Pack.BE_To_UInt64(x, 0); z.n1 = Pack.BE_To_UInt64(x, 8); } internal static void DivideP(ref FieldElement x, out FieldElement z) { ulong n = x.n0; ulong n2 = x.n1; ulong num = (ulong)((long)n >> 63); n = (ulong)((long)n ^ ((long)num & -2233785415175766016)); z.n0 = ((n << 1) | (n2 >> 63)); z.n1 = ((n2 << 1) | (0 - num)); } internal static void Multiply(byte[] x, byte[] y) { AsFieldElement(x, out FieldElement z); AsFieldElement(y, out FieldElement z2); Multiply(ref z, ref z2); AsBytes(ref z, x); } internal static void Multiply(ref FieldElement x, ref FieldElement y) { ulong n = x.n0; ulong n2 = x.n1; ulong n3 = y.n0; ulong n4 = y.n1; ulong num = Longs.Reverse(n); ulong num2 = Longs.Reverse(n2); ulong num3 = Longs.Reverse(n3); ulong num4 = Longs.Reverse(n4); ulong num5 = Longs.Reverse(ImplMul64(num, num3)); ulong num6 = ImplMul64(n, n3) << 1; ulong num7 = Longs.Reverse(ImplMul64(num2, num4)); ulong num8 = ImplMul64(n2, n4) << 1; ulong num9 = Longs.Reverse(ImplMul64(num ^ num2, num3 ^ num4)); ulong num10 = ImplMul64(n ^ n2, n3 ^ n4) << 1; ulong num11 = num5; ulong num12 = num6 ^ num5 ^ num7 ^ num9; ulong num13 = num7 ^ num6 ^ num8 ^ num10; ulong num14 = num8; num12 ^= (num14 ^ (num14 >> 1) ^ (num14 >> 2) ^ (num14 >> 7)); num13 ^= ((num14 << 62) ^ (num14 << 57)); num11 ^= (num13 ^ (num13 >> 1) ^ (num13 >> 2) ^ (num13 >> 7)); num12 ^= ((num13 << 63) ^ (num13 << 62) ^ (num13 << 57)); x.n0 = num11; x.n1 = num12; } internal static void MultiplyP7(ref FieldElement x) { ulong n = x.n0; ulong n2 = x.n1; ulong num = n2 << 57; x.n0 = ((n >> 7) ^ num ^ (num >> 1) ^ (num >> 2) ^ (num >> 7)); x.n1 = ((n2 >> 7) | (n << 57)); } internal static void MultiplyP8(ref FieldElement x) { ulong n = x.n0; ulong n2 = x.n1; ulong num = n2 << 56; x.n0 = ((n >> 8) ^ num ^ (num >> 1) ^ (num >> 2) ^ (num >> 7)); x.n1 = ((n2 >> 8) | (n << 56)); } internal static void MultiplyP8(ref FieldElement x, out FieldElement y) { ulong n = x.n0; ulong n2 = x.n1; ulong num = n2 << 56; y.n0 = ((n >> 8) ^ num ^ (num >> 1) ^ (num >> 2) ^ (num >> 7)); y.n1 = ((n2 >> 8) | (n << 56)); } internal static void MultiplyP16(ref FieldElement x) { ulong n = x.n0; ulong n2 = x.n1; ulong num = n2 << 48; x.n0 = ((n >> 16) ^ num ^ (num >> 1) ^ (num >> 2) ^ (num >> 7)); x.n1 = ((n2 >> 16) | (n << 48)); } internal static void Square(ref FieldElement x) { ulong low; ulong num = Interleave.Expand64To128Rev(x.n0, out low); ulong low2; ulong num2 = Interleave.Expand64To128Rev(x.n1, out low2); ulong num3 = num ^ num2 ^ (num2 >> 1) ^ (num2 >> 2) ^ (num2 >> 7); ulong num4 = low2 ^ (num2 << 62) ^ (num2 << 57); x.n0 = (low ^ num4 ^ (num4 >> 1) ^ (num4 >> 2) ^ (num4 >> 7)); x.n1 = (num3 ^ (low2 << 62) ^ (low2 << 57)); } internal static void Xor(byte[] x, byte[] y) { int num = 0; do { x[num] ^= y[num]; num++; x[num] ^= y[num]; num++; x[num] ^= y[num]; num++; x[num] ^= y[num]; num++; } while (num < 16); } internal static void Xor(byte[] x, byte[] y, int yOff) { int num = 0; do { x[num] ^= y[yOff + num]; num++; x[num] ^= y[yOff + num]; num++; x[num] ^= y[yOff + num]; num++; x[num] ^= y[yOff + num]; num++; } while (num < 16); } internal static void Xor(byte[] x, byte[] y, int yOff, int yLen) { while (--yLen >= 0) { x[yLen] ^= y[yOff + yLen]; } } internal static void Xor(byte[] x, int xOff, byte[] y, int yOff, int len) { while (--len >= 0) { x[xOff + len] ^= y[yOff + len]; } } internal static void Xor(ref FieldElement x, ref FieldElement y) { x.n0 ^= y.n0; x.n1 ^= y.n1; } internal static void Xor(ref FieldElement x, ref FieldElement y, out FieldElement z) { z.n0 = (x.n0 ^ y.n0); z.n1 = (x.n1 ^ y.n1); } private static ulong ImplMul64(ulong x, ulong y) { ulong num = x & 1229782938247303441; ulong num2 = x & 2459565876494606882; ulong num3 = x & 4919131752989213764; ulong num4 = (ulong)((long)x & -8608480567731124088); ulong num5 = y & 1229782938247303441; ulong num6 = y & 2459565876494606882; ulong num7 = y & 4919131752989213764; ulong num8 = (ulong)((long)y & -8608480567731124088); ulong num9 = (num * num5) ^ (num2 * num8) ^ (num3 * num7) ^ (num4 * num6); ulong num10 = (num * num6) ^ (num2 * num5) ^ (num3 * num8) ^ (num4 * num7); ulong num11 = (num * num7) ^ (num2 * num6) ^ (num3 * num5) ^ (num4 * num8); ulong num12 = (num * num8) ^ (num2 * num7) ^ (num3 * num6) ^ (num4 * num5); num9 &= 1229782938247303441; num10 &= 2459565876494606882; num11 &= 4919131752989213764; num12 = (ulong)((long)num12 & -8608480567731124088); return num9 | num10 | num11 | num12; } } }