summary refs log tree commit diff
path: root/Crypto/src/crypto/modes/gcm/GcmUtilities.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/crypto/modes/gcm/GcmUtilities.cs')
-rw-r--r--Crypto/src/crypto/modes/gcm/GcmUtilities.cs149
1 files changed, 149 insertions, 0 deletions
diff --git a/Crypto/src/crypto/modes/gcm/GcmUtilities.cs b/Crypto/src/crypto/modes/gcm/GcmUtilities.cs
new file mode 100644

index 000000000..8da125641 --- /dev/null +++ b/Crypto/src/crypto/modes/gcm/GcmUtilities.cs
@@ -0,0 +1,149 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + internal abstract class GcmUtilities + { + internal static byte[] OneAsBytes() + { + byte[] tmp = new byte[16]; + tmp[0] = 0x80; + return tmp; + } + + internal static uint[] OneAsUints() + { + uint[] tmp = new uint[4]; + tmp[0] = 0x80000000; + return tmp; + } + + internal static uint[] AsUints(byte[] bs) + { + uint[] us = new uint[4]; + us[0] = Pack.BE_To_UInt32(bs, 0); + us[1] = Pack.BE_To_UInt32(bs, 4); + us[2] = Pack.BE_To_UInt32(bs, 8); + us[3] = Pack.BE_To_UInt32(bs, 12); + return us; + } + + internal static void Multiply(byte[] block, byte[] val) + { + byte[] tmp = Arrays.Clone(block); + byte[] c = new byte[16]; + + for (int i = 0; i < 16; ++i) + { + byte bits = val[i]; + for (int j = 7; j >= 0; --j) + { + if ((bits & (1 << j)) != 0) + { + Xor(c, tmp); + } + + bool lsb = (tmp[15] & 1) != 0; + ShiftRight(tmp); + if (lsb) + { + // R = new byte[]{ 0xe1, ... }; + //GCMUtilities.Xor(tmp, R); + tmp[0] ^= (byte)0xe1; + } + } + } + + Array.Copy(c, 0, block, 0, 16); + } + + // P is the value with only bit i=1 set + internal static void MultiplyP(uint[] x) + { + bool lsb = (x[3] & 1) != 0; + ShiftRight(x); + if (lsb) + { + // R = new uint[]{ 0xe1000000, 0, 0, 0 }; + //Xor(v, R); + x[0] ^= 0xe1000000; + } + } + + internal static void MultiplyP8(uint[] x) + { +// for (int i = 8; i != 0; --i) +// { +// MultiplyP(x); +// } + + uint lsw = x[3]; + ShiftRightN(x, 8); + for (int i = 7; i >= 0; --i) + { + if ((lsw & (1 << i)) != 0) + { + x[0] ^= (0xe1000000 >> (7 - i)); + } + } + } + + internal static void ShiftRight(byte[] block) + { + int i = 0; + byte bit = 0; + for (;;) + { + byte b = block[i]; + block[i] = (byte)((b >> 1) | bit); + if (++i == 16) break; + bit = (byte)(b << 7); + } + } + + internal static void ShiftRight(uint[] block) + { + int i = 0; + uint bit = 0; + for (;;) + { + uint b = block[i]; + block[i] = (b >> 1) | bit; + if (++i == 4) break; + bit = b << 31; + } + } + + internal static void ShiftRightN(uint[] block, int n) + { + int i = 0; + uint bit = 0; + for (;;) + { + uint b = block[i]; + block[i] = (b >> n) | bit; + if (++i == 4) break; + bit = b << (32 - n); + } + } + + internal static void Xor(byte[] block, byte[] val) + { + for (int i = 15; i >= 0; --i) + { + block[i] ^= val[i]; + } + } + + internal static void Xor(uint[] block, uint[] val) + { + for (int i = 3; i >= 0; --i) + { + block[i] ^= val[i]; + } + } + } +}