You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

127 lines
3.4 KiB

using System;
namespace SogClient
{
internal sealed class PackUtils
{
internal static uint BE_To_UInt32(byte[] bs, int off)
{
return (uint)bs[off] << 24
| (uint)bs[off + 1] << 16
| (uint)bs[off + 2] << 8
| (uint)bs[off + 3];
}
internal static void UInt32_To_BE(uint n, byte[] bs, int off)
{
bs[off] = (byte)(n >> 24);
bs[off + 1] = (byte)(n >> 16);
bs[off + 2] = (byte)(n >> 8);
bs[off + 3] = (byte)(n);
}
}
public class SogFastXTEAKey
{
private const int delta = unchecked((int)0x9E3779B9);
private uint[] _S = new uint[4];
public byte[] Key { get; }
public uint[] Sum0 { get; }
public uint[] Sum1 { get; }
public SogFastXTEAKey(byte[] srcKey)
{
if(srcKey.Length != 16)
{
TraceLog.Error("SogFastXTEAKey key length must is error {0}", srcKey);
throw new Exception("SogXTEAKey key length must is 16");
}
Key = srcKey;
Sum0 = new uint[SogFastXTEA.Rounds];
Sum1 = new uint[SogFastXTEA.Rounds];
int i, j;
for (i = j = 0; i < 4; i++, j += 4)
{
_S[i] = PackUtils.BE_To_UInt32(srcKey, j);
}
for (i = j = 0; i < SogFastXTEA.Rounds; i++)
{
Sum0[i] = ((uint)j + _S[j & 3]);
j += delta;
Sum1[i] = ((uint)j + _S[j >> 11 & 3]);
}
}
}
/// <summary>
/// XTEA加密的变种,小于8个字节不加密,轮数量减少到8,提高效率
/// </summary>
public sealed class SogFastXTEA
{
public const int Rounds = 8;
private const int delta = unchecked((int)0x9E3779B9);
private SogFastXTEA()
{
}
public static void Encrypt(byte[] data, SogFastXTEAKey key)
{
int iBlockCount = data.Length / 8;
int offset = 0;
for(int block = 0; block < iBlockCount; block++)
{
uint v0 = PackUtils.BE_To_UInt32(data, offset);
uint v1 = PackUtils.BE_To_UInt32(data, offset + 4);
for (int i = 0; i < Rounds; i++)
{
v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ key.Sum0[i];
v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ key.Sum1[i];
}
PackUtils.UInt32_To_BE(v0, data, offset);
PackUtils.UInt32_To_BE(v1, data, offset + 4);
offset += 8;
}
}
public static void Decrypt(byte[] data, SogFastXTEAKey key)
{
int iBlockCount = data.Length / 8;
int offset = 0;
for (int block = 0; block < iBlockCount; block++)
{
uint v0 = PackUtils.BE_To_UInt32(data, offset);
uint v1 = PackUtils.BE_To_UInt32(data, offset + 4);
for (int i = Rounds - 1; i >= 0; i--)
{
v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ key.Sum1[i];
v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ key.Sum0[i];
}
PackUtils.UInt32_To_BE(v0, data, offset);
PackUtils.UInt32_To_BE(v1, data, offset + 4);
offset += 8;
}
}
}
}