Skip to content

Instantly share code, notes, and snippets.

@savaged
Last active September 24, 2023 18:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save savaged/e793b8940d6450861c2bd9db91a4f74b to your computer and use it in GitHub Desktop.
Save savaged/e793b8940d6450861c2bd9db91a4f74b to your computer and use it in GitHub Desktop.
TEA implementation
// Credit to Page Brooks https://www.codeproject.com/Articles/6137/Tiny-Encryption-Algorithm-TEA-for-the-Compact-Fram
var key = "mykey";
var encrypted = Encrypt("testing", key);
var decrypted = Decrypt(encrypted, key);
Console.WriteLine(decrypted);
static string Encrypt(string data, string key)
{
if (data.Length == 0)
throw new ArgumentOutOfRangeException("data must be at least 1 character in length.");
uint[] formattedKey = FormatKey(key);
if (data.Length % 2 != 0) data += '\0'; // Make sure array is even in length.
byte[] dataBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(data);
var cipher = string.Empty;
uint[] tempData = new uint[2];
for(int i = 0; i < dataBytes.Length; i += 2)
{
tempData[0] = dataBytes[i];
tempData[1] = dataBytes[i + 1];
Code(tempData, formattedKey);
cipher += ConvertUIntToString(tempData[0]) + ConvertUIntToString(tempData[1]);
}
return cipher;
}
static string Decrypt(string data, string key)
{
uint[] formattedKey = FormatKey(key);
int x = 0;
uint[] tempData = new uint[2];
byte[] dataBytes = new byte[data.Length / 8 * 2];
for (int i = 0; i < data.Length; i += 8)
{
tempData[0] = ConvertStringToUInt(data.Substring(i, 4));
tempData[1] = ConvertStringToUInt(data.Substring(i + 4, 4));
Decode(tempData, formattedKey);
dataBytes[x++] = (byte)tempData[0];
dataBytes[x++] = (byte)tempData[1];
}
var decipheredString = System.Text.ASCIIEncoding.ASCII.GetString(dataBytes, 0, dataBytes.Length);
if (decipheredString[decipheredString.Length - 1] == '\0') // Strip the null char if it was added.
decipheredString = decipheredString.Substring(0, decipheredString.Length - 1);
return decipheredString;
}
static uint[] FormatKey(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
if (key.Length == 0)
throw new ArgumentOutOfRangeException("key must be between 1 and 16 characters in length");
key = key.PadRight(16, ' ').Substring(0, 16); // Ensure that the key is 16 chars in length.
uint[] formattedKey = new uint[4];
// Get the key into the correct format for TEA usage.
int j = 0;
for (int i = 0; i < key.Length; i += 4)
formattedKey[j++] = ConvertStringToUInt(key.Substring(i, 4));
return formattedKey;
}
/// <summary>
/// Converts a string of length 4 to a 32-bit unsigned integer.
/// </summary>
/// <param name="input">The string of length 4 to convert.</param>
/// <returns>An encoded integer value representing a string of length 4.</returns>
static uint ConvertStringToUInt(string input)
{
uint output = (uint)input[0];
output += ((uint)input[1] << 8);
output += ((uint)input[2] << 16);
output += ((uint)input[3] << 24);
return output;
}
/// <summary>
/// Converts a 32-bit unsigned integer to a string of length 4.
/// </summary>
/// <param name="input">The unsigned integer to convert to a string.</param>
/// <returns>A string value represented by the encoded integer.</returns>
static string ConvertUIntToString(uint input)
{
var output = new System.Text.StringBuilder();
output.Append((char)((input & 0xFF)));
output.Append((char)((input >> 8) & 0xFF));
output.Append((char)((input >> 16) & 0xFF));
output.Append((char)((input >> 24) & 0xFF));
return output.ToString();
}
#region Tea Algorithm
static void Code(uint[] v, uint[] k)
{
uint y = v[0];
uint z = v[1];
uint sum = 0;
uint delta = 0x9e3779b9;
uint n = 32;
while (n-- > 0)
{
sum += delta;
y += (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1];
z += (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3];
}
v[0] = y;
v[1] = z;
}
static void Decode(uint[] v, uint[] k)
{
uint n = 32;
uint y = v[0];
uint z = v[1];
uint delta = 0x9e3779b9;
uint sum = delta << 5 ;
while (n-- > 0)
{
z -= (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3];
y -= (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1];
sum -= delta;
}
v[0] = y;
v[1] = z;
}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment