Core/PacketIO: Updated packet structures to 9.2.7

Port From (https://github.com/TrinityCore/TrinityCore/commit/20f38369f30309e2c0cd53eca9cfe9c49376ed8c)
This commit is contained in:
hondacrx
2022-08-17 14:37:34 -04:00
parent 6efbe4b00e
commit cacfc06088
66 changed files with 6038 additions and 23 deletions
@@ -0,0 +1,273 @@
using System;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Diagnostics.Contracts;
namespace Framework.Cryptography.Ed25519
{
public static class CryptoBytes
{
/// <summary>
/// Comparison of two arrays.
///
/// The runtime of this method does not depend on the contents of the arrays. Using constant time
/// prevents timing attacks that allow an attacker to learn if the arrays have a common prefix.
///
/// It is important to use such a constant time comparison when verifying MACs.
/// </summary>
/// <param name="x">Byte array</param>
/// <param name="y">Byte array</param>
/// <returns>True if arrays are equal</returns>
public static bool ConstantTimeEquals(byte[] x, byte[] y)
{
if (x.Length != y.Length)
return false;
return InternalConstantTimeEquals(x, 0, y, 0, x.Length) != 0;
}
/// <summary>
/// Comparison of two array segments.
///
/// The runtime of this method does not depend on the contents of the arrays. Using constant time
/// prevents timing attacks that allow an attacker to learn if the arrays have a common prefix.
///
/// It is important to use such a constant time comparison when verifying MACs.
/// </summary>
/// <param name="x">Byte array segment</param>
/// <param name="y">Byte array segment</param>
/// <returns>True if contents of x and y are equal</returns>
public static bool ConstantTimeEquals(ArraySegment<byte> x, ArraySegment<byte> y)
{
if (x.Count != y.Count)
return false;
return InternalConstantTimeEquals(x.Array, x.Offset, y.Array, y.Offset, x.Count) != 0;
}
/// <summary>
/// Comparison of two byte sequences.
///
/// The runtime of this method does not depend on the contents of the arrays. Using constant time
/// prevents timing attacks that allow an attacker to learn if the arrays have a common prefix.
///
/// It is important to use such a constant time comparison when verifying MACs.
/// </summary>
/// <param name="x">Byte array</param>
/// <param name="xOffset">Offset of byte sequence in the x array</param>
/// <param name="y">Byte array</param>
/// <param name="yOffset">Offset of byte sequence in the y array</param>
/// <param name="length">Lengh of byte sequence</param>
/// <returns>True if sequences are equal</returns>
public static bool ConstantTimeEquals(byte[] x, int xOffset, byte[] y, int yOffset, int length)
{
return InternalConstantTimeEquals(x, xOffset, y, yOffset, length) != 0;
}
private static uint InternalConstantTimeEquals(byte[] x, int xOffset, byte[] y, int yOffset, int length)
{
int differentbits = 0;
for (int i = 0; i < length; i++)
differentbits |= x[xOffset + i] ^ y[yOffset + i];
return (1 & (unchecked((uint)differentbits - 1) >> 8));
}
/// <summary>
/// Overwrites the contents of the array, wiping the previous content.
/// </summary>
/// <param name="data">Byte array</param>
public static void Wipe(byte[] data)
{
InternalWipe(data, 0, data.Length);
}
/// <summary>
/// Overwrites the contents of the array, wiping the previous content.
/// </summary>
/// <param name="data">Byte array</param>
/// <param name="offset">Index of byte sequence</param>
/// <param name="length">Length of byte sequence</param>
public static void Wipe(byte[] data, int offset, int length)
{
InternalWipe(data, offset, length);
}
/// <summary>
/// Overwrites the contents of the array segment, wiping the previous content.
/// </summary>
/// <param name="data">Byte array segment</param>
public static void Wipe(ArraySegment<byte> data)
{
InternalWipe(data.Array, data.Offset, data.Count);
}
// Secure wiping is hard
// * the GC can move around and copy memory
// Perhaps this can be avoided by using unmanaged memory or by fixing the position of the array in memory
// * Swap files and error dumps can contain secret information
// It seems possible to lock memory in RAM, no idea about error dumps
// * Compiler could optimize out the wiping if it knows that data won't be read back
// I hope this is enough, suppressing inlining
// but perhaps `RtlSecureZeroMemory` is needed
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void InternalWipe(byte[] data, int offset, int count)
{
Array.Clear(data, offset, count);
}
// shallow wipe of structs
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void InternalWipe<T>(ref T data)
where T : struct
{
data = default(T);
}
/// <summary>
/// Constant-time conversion of the bytes array to an upper-case hex string.
/// Please see http://stackoverflow.com/a/14333437/445517 for the detailed explanation
/// </summary>
/// <param name="data">Byte array</param>
/// <returns>Hex representation of byte array</returns>
public static string ToHexStringUpper(byte[] data)
{
if (data == null)
return null;
char[] c = new char[data.Length * 2];
int b;
for (int i = 0; i < data.Length; i++)
{
b = data[i] >> 4;
c[i * 2] = (char)(55 + b + (((b - 10) >> 31) & -7));
b = data[i] & 0xF;
c[i * 2 + 1] = (char)(55 + b + (((b - 10) >> 31) & -7));
}
return new string(c);
}
/// <summary>
/// Constant-time conversion of the bytes array to an lower-case hex string.
/// Please see http://stackoverflow.com/a/14333437/445517 for the detailed explanation.
/// </summary>
/// <param name="data">Byte array</param>
/// <returns>Hex representation of byte array</returns>
public static string ToHexStringLower(byte[] data)
{
if (data == null)
return null;
char[] c = new char[data.Length * 2];
int b;
for (int i = 0; i < data.Length; i++)
{
b = data[i] >> 4;
c[i * 2] = (char)(87 + b + (((b - 10) >> 31) & -39));
b = data[i] & 0xF;
c[i * 2 + 1] = (char)(87 + b + (((b - 10) >> 31) & -39));
}
return new string(c);
}
/// <summary>
/// Converts the hex string to bytes. Case insensitive.
/// </summary>
/// <param name="hexString">Hex encoded byte sequence</param>
/// <returns>Byte array</returns>
public static byte[] FromHexString(string hexString)
{
if (hexString == null)
return null;
if (hexString.Length % 2 != 0)
throw new FormatException("The hex string is invalid because it has an odd length");
var result = new byte[hexString.Length / 2];
for (int i = 0; i < result.Length; i++)
result[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
return result;
}
/// <summary>
/// Encodes the bytes with the Base64 encoding.
/// More compact than hex, but it is case-sensitive and uses the special characters `+`, `/` and `=`.
/// </summary>
/// <param name="data">Byte array</param>
/// <returns>Base 64 encoded data</returns>
public static string ToBase64String(byte[] data)
{
if (data == null)
return null;
return Convert.ToBase64String(data);
}
/// <summary>
/// Decodes a Base64 encoded string back to bytes.
/// </summary>
/// <param name="base64String">Base 64 encoded data</param>
/// <returns>Byte array</returns>
public static byte[] FromBase64String(string base64String)
{
if (base64String == null)
return null;
return Convert.FromBase64String(base64String);
}
private const string strDigits = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
/// <summary>
/// Encode a byte sequence as a base58-encoded string
/// </summary>
/// <param name="input">Byte sequence</param>
/// <returns>Encoding result</returns>
public static string Base58Encode(byte[] input)
{
// Decode byte[] to BigInteger
System.Numerics.BigInteger intData = 0;
for (int i = 0; i < input.Length; i++)
{
intData = intData * 256 + input[i];
}
// Encode BigInteger to Base58 string
string result = "";
while (intData > 0)
{
int remainder = (int)(intData % 58);
intData /= 58;
result = strDigits[remainder] + result;
}
// Append `1` for each leading 0 byte
for (int i = 0; i < input.Length && input[i] == 0; i++)
{
result = '1' + result;
}
return result;
}
/// <summary>
/// // Decode a base58-encoded string into byte array
/// </summary>
/// <param name="strBase58">Base58 data string</param>
/// <returns>Byte array</returns>
public static byte[] Base58Decode(string input)
{
// Decode Base58 string to BigInteger
System.Numerics.BigInteger intData = 0;
for (int i = 0; i < input.Length; i++)
{
int digit = strDigits.IndexOf(input[i]); //Slow
if (digit < 0)
throw new FormatException(string.Format("Invalid Base58 character `{0}` at position {1}", input[i], i));
intData = intData * 58 + digit;
}
// Encode BigInteger to byte[]
// Leading zero bytes get encoded as leading `1` characters
int leadingZeroCount = input.TakeWhile(c => c == '1').Count();
var leadingZeros = Enumerable.Repeat((byte)0, leadingZeroCount);
var bytesWithoutLeadingZeros =
intData.ToByteArray()
.Reverse()// to big endian
.SkipWhile(b => b == 0);//strip sign byte
var result = leadingZeros.Concat(bytesWithoutLeadingZeros).ToArray();
return result;
}
}
}