/// <summary> /// Galois Field 2(128) Multiplication of two Byte arrays with reducer (x128 + x7 + x2 + x + 1) /// Method is used in Galois Counter Mode (GCM) Authenticated Encryption with Authenticated Data (AEAD) /// Do not use branches, to avoid side channels /// Note: unlike the GMul method the multiplication is a shift right and overflow is on the least significant bit /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static byte[] GMul128(byte[] a, byte[] b) { byte[] z = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; byte[] v = new byte[a.Length]; Array.Copy(a, 0, v, 0, a.Length); for (int counter = 0; counter < 128; counter++) { byte mask = (byte)(-((b[counter / 8] >> (7 - (counter % 8))) & 1)); z.AddToFirst(v, mask); mask = (byte)(-(v[v.Length - 1] & 1)); v.ShiftRight(); v[0] ^= (byte)(0xe1 & mask); } return(z); }