diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-08-14 17:14:02 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-08-14 17:14:02 +0700 |
commit | d825278c75f0b0a3cb6741a9a0bed911da9ce6d8 (patch) | |
tree | 3433a02b6e67f9817b39092714bd0ad4faa704ef | |
parent | Use Itoh-Tsujii inversion (with extended bases for some cases) (diff) | |
download | BouncyCastle.NET-ed25519-d825278c75f0b0a3cb6741a9a0bed911da9ce6d8.tar.xz |
Fix 64-bit multiply (not used)
- correct weird shift lengths in 32-bit multiply (no bug)
-rw-r--r-- | crypto/src/crypto/modes/gcm/GcmUtilities.cs | 53 | ||||
-rw-r--r-- | crypto/src/crypto/util/Pack.cs | 25 |
2 files changed, 73 insertions, 5 deletions
diff --git a/crypto/src/crypto/modes/gcm/GcmUtilities.cs b/crypto/src/crypto/modes/gcm/GcmUtilities.cs index de41d88f4..d8ab2ca73 100644 --- a/crypto/src/crypto/modes/gcm/GcmUtilities.cs +++ b/crypto/src/crypto/modes/gcm/GcmUtilities.cs @@ -46,6 +46,13 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm return tmp; } + internal static ulong[] OneAsUlongs() + { + ulong[] tmp = new ulong[2]; + tmp[0] = 1UL << 63; + return tmp; + } + internal static byte[] AsBytes(uint[] x) { return Pack.UInt32_To_BE(x); @@ -56,6 +63,18 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm Pack.UInt32_To_BE(x, z, 0); } + internal static byte[] AsBytes(ulong[] x) + { + byte[] z = new byte[16]; + Pack.UInt64_To_BE(x, z, 0); + return z; + } + + internal static void AsBytes(ulong[] x, byte[] z) + { + Pack.UInt64_To_BE(x, z, 0); + } + internal static uint[] AsUints(byte[] bs) { uint[] output = new uint[4]; @@ -68,6 +87,18 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm Pack.BE_To_UInt32(bs, 0, output); } + internal static ulong[] AsUlongs(byte[] x) + { + ulong[] z = new ulong[2]; + Pack.BE_To_UInt64(x, 0, z); + return z; + } + + public static void AsUlongs(byte[] x, ulong[] z) + { + Pack.BE_To_UInt64(x, 0, z); + } + internal static void Multiply(byte[] x, byte[] y) { uint[] t1 = GcmUtilities.AsUints(x); @@ -80,7 +111,7 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm { uint r00 = x[0], r01 = x[1], r02 = x[2], r03 = x[3]; uint r10 = 0, r11 = 0, r12 = 0, r13 = 0; - + for (int i = 0; i < 4; ++i) { int bits = (int)y[i]; @@ -93,9 +124,9 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm r13 ^= (r03 & m1); uint m2 = (uint)((int)(r03 << 31) >> 8); - r03 = (r03 >> 1) | (r02 << 63); - r02 = (r02 >> 1) | (r01 << 63); - r01 = (r01 >> 1) | (r00 << 63); + r03 = (r03 >> 1) | (r02 << 31); + r02 = (r02 >> 1) | (r01 << 31); + r01 = (r01 >> 1) | (r00 << 31); r00 = (r00 >> 1) ^ (m2 & E1); } } @@ -119,7 +150,7 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm r10 ^= (r00 & m1); r11 ^= (r01 & m1); - ulong m2 = (r01 << 63) >> 8; + ulong m2 = (ulong)((long)(r01 << 63) >> 8); r01 = (r01 >> 1) | (r00 << 63); r00 = (r00 >> 1) ^ (m2 & E1L); } @@ -272,5 +303,17 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm z[2] = x[2] ^ y[2]; z[3] = x[3] ^ y[3]; } + + internal static void Xor(ulong[] x, ulong[] y) + { + x[0] ^= y[0]; + x[1] ^= y[1]; + } + + internal static void Xor(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + } } } diff --git a/crypto/src/crypto/util/Pack.cs b/crypto/src/crypto/util/Pack.cs index 087cb7cea..dc00ab450 100644 --- a/crypto/src/crypto/util/Pack.cs +++ b/crypto/src/crypto/util/Pack.cs @@ -117,6 +117,22 @@ namespace Org.BouncyCastle.Crypto.Utilities UInt32_To_BE((uint)(n), bs, off + 4); } + internal static byte[] UInt64_To_BE(ulong[] ns) + { + byte[] bs = new byte[8 * ns.Length]; + UInt64_To_BE(ns, bs, 0); + return bs; + } + + internal static void UInt64_To_BE(ulong[] ns, byte[] bs, int off) + { + for (int i = 0; i < ns.Length; ++i) + { + UInt64_To_BE(ns[i], bs, off); + off += 8; + } + } + internal static ulong BE_To_UInt64(byte[] bs) { uint hi = BE_To_UInt32(bs); @@ -131,6 +147,15 @@ namespace Org.BouncyCastle.Crypto.Utilities return ((ulong)hi << 32) | (ulong)lo; } + internal static void BE_To_UInt64(byte[] bs, int off, ulong[] ns) + { + for (int i = 0; i < ns.Length; ++i) + { + ns[i] = BE_To_UInt64(bs, off); + off += 8; + } + } + internal static void UInt16_To_LE(ushort n, byte[] bs) { bs[0] = (byte)(n); |