using Org.BouncyCastle.Crypto.Modes.Gcm;
using System.Collections;
public static void Main()
byte[] a = Convert.FromHexString("acbef20579b4b8ebce889bac8732dad7");
byte[] b = Convert.FromHexString("ed95f8e164bf3213febc740f0bd9c4af");
byte[] c = gf_mul_be_fixed(a, b);
Console.WriteLine(Convert.ToHexString(c));
byte[] aRev = ReverseAllBits(a);
byte[] bRev = ReverseAllBits(b);
byte[] cRev = ReverseAllBits(gf_mul_be(aRev, bRev));
Console.WriteLine(Convert.ToHexString(cRev));
byte[] cBC = gf_mul_be_BC(a, b.ToArray());
Console.WriteLine(Convert.ToHexString(cBC));
private static byte[] gf_mul_be_fixed(byte[] a, byte[] b)
var Z = Enumerable.Repeat((byte)0, 16).ToArray();
for (var i = 0; i < 128; i++)
var xi = (X[j] >> (8 - k - 1)) & 1;
Z = Z.Zip(V, (z, v) => (byte)(z ^ v)).ToArray();
private static byte[] gf_mul_be(byte[] a, byte[] b)
var Z = Enumerable.Repeat((byte)0, 16).ToArray();
for (var i = 127; i >= 0; i--)
var xi = (X[j] >> (8 - k - 1)) & 1;
Z = Z.Zip(V, (z, v) => (byte)(z ^ v)).ToArray();
private static byte[] gf_mul_be_BC(byte[] a, byte[] b)
BasicGcmMultiplier bgm = new BasicGcmMultiplier();
private static void LeftShiftByteArray(byte[] bytes)
for (var l = bytes.Length - 1; l >= 0; l--)
bytes[l] = (byte)(bytes[l] << 1);
bytes[l] = (byte)(bytes[l] | 0x01);
carry = (byteCopy & 0x80) >> 7;
private static void RightShiftByteArray(byte[] bytes)
for (var i = 0; i < bytes.Length; i++)
bytes[i] = (byte)(bytes[i] >> 1);
bytes[i] = (byte)(bytes[i] | 0x80);
carry = (byteCopy & 0x01);
private static byte[] ReverseAllBits(byte[] input)
BitArray bitArray = new BitArray(input);
byte[] reversed = new byte[input.Length];
bitArray.CopyTo(reversed, 0);
public static void Reverse(BitArray array)
int length = array.Length;
for (int i = 0; i < mid; i++)
array[i] = array[length - i - 1];
array[length - i - 1] = bit;