eXtended Tiny Encryption Algorithm (XTEA) – PART II

In this article, we will demonstrate eXtended Tiny Encryption Algorithm (XTEA). Don’t forget to read the Part I of TEA.

XTEA (eXtended TEA) is a block cipher designed to fix weaknesses in TEA.

Like TEA, XTEA is a 64-bit block Feistel cipher with a 128-bit key and a suggested 64 rounds.

As per book “Information Security and Cryptology – ICISC 2003

TEA is a 64-round Feistel block cipher with 64-bit block size and 128-bit key which consist of four 32-bit words K[0], K[1], K[2], and K[3]. TEA does not

has a key schedule algorithm. Instead, it uses the constant δ = 9e3779b9x.

Let (Ln, Rn) be the input of n-th round for 1 ≤ n ≤ 64. The output of n-th round is (Ln+1, Rn+1), and Ln+1 = Rn. Rn+1 is computed as follows. If n = 2i − 1 for 1 ≤ i ≤ 32,

Rn+1 = Ln + (((Rn  4) + K[0]) ⊕ (Rn + i · δ) ⊕ (Rn 5 + K[1]))

On the other hand, if n = 2i for 1 ≤ i ≤ 32,

Rn+1 = Ln + (((Rn  4) + K[2]) ⊕ (Rn + i · δ) ⊕ (Rn 5 + K[3]))

XTEA is also a 64-round Feistel block cipher with 64-bit block size like TEA. Its 128-bit secret key K is (K[0], K[1], K[2], K[3]), too. Using same notations as above, an input of n-th round is (Ln, Rn) and Ln+1 = Rn. Rn+1 is computed as

follows. If n = 2i − 1 for 1 ≤ i ≤ 32,

Rn+1 = Ln + (((Rn  4 ⊕ Rn 5) + Rn)⊕ ((i − 1)· δ + K[((i − 1)· δ 11)&3])

If n = 2i for 1 ≤ i ≤ 32, 

Rn+1 = Ln + (((Rn  4 ⊕ Rn 5) + Rn) ⊕ (i · δ + K[(i · δ 11)&3])

There is slight modification in converting TEA into XTEA. Results of both shift operations are combined by exclusive-or and then the result is added to original input by addition mod 232.

Implementations:

This standard C source code, adapted from the reference code released into the public domain by David Wheeler and Roger Needham, encrypts and decrypts using XTEA:

C# Implementations:

I have made some changes to make it xTEA woring in C#.

1. Used SHA-256 to generate key

2. Used MemoryStream and BinaryWriter to play with Binary data.

3. for loop to pass each byte[] in to xTEA sinppet to achieve encryption and decryption.

Below is eXtended Tiny Encryption Algorithm Source Code in C#

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace SymmetricCryptography
{
    static class XTinyEncryptionAlgorithm
    {

        static void Main()
        {

            Console.WriteLine("**********************************************");
            Console.WriteLine("eXtended Tiny Encryption Algorithm(XTEA)     |");
            Console.WriteLine("**********************************************");
            Console.WriteLine("");

            Console.WriteLine("Enter key to encrypt the text:");
            var key = Console.ReadLine();
            if (string.IsNullOrEmpty(key))
                return;

            Console.WriteLine("Enter message to encrypt:");
            var message = Console.ReadLine();
            if (string.IsNullOrEmpty(message))
                return;

            uint keyBits = 64;
            var encryptMessage = Encrypt(message, key, keyBits);

            Console.WriteLine($"Encrypted Message : {encryptMessage}");
            Console.WriteLine($"Decrypted Message : {Decrypt(encryptMessage, key, keyBits)}");
            Console.ReadLine();
        }



        public static string Encrypt(string data, string key, uint keyBits)
        {
            var dataBytes = Encoding.Unicode.GetBytes(data);
            var sha256 = SHA256.Create();
            var keyBuffer = sha256.ComputeHash(Encoding.ASCII.GetBytes(key));

            var blockBuffer = new uint[2];
            var result = new byte[(dataBytes.Length + 7) / 8 * 8];

            Array.Copy(dataBytes,0, result,0, dataBytes.Length);
            using (var stream = new MemoryStream(result))
            {
                using (var writer = new BinaryWriter(stream))
                {
                    for (var i = 0; i < result.Length; i += 8)
                    {
                        blockBuffer[0] = BitConverter.ToUInt32(result, i);
                        blockBuffer[1] = BitConverter.ToUInt32(result, i + 4);

                        uint v0 = blockBuffer[0], v1 = blockBuffer[1], sum = 0, delta = 0x9E3779B9;
                        for (uint j = 0; j < keyBits; j++)
                        {
                            v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + keyBuffer[sum & 3]);
                            sum += delta;
                            v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + keyBuffer[(sum >> 11) & 3]);
                        }
                        blockBuffer[0] = v0;
                        blockBuffer[1] = v1;

                        writer.Write(blockBuffer[0]);
                        writer.Write(blockBuffer[1]);
                    }
                }
            }
            return Convert.ToBase64String(result);
        }

        public static string Decrypt(string data, string key, uint keyBits)
        {
            var dataBytes = Convert.FromBase64String(data);
            var sha256 = SHA256.Create();

            var keyBuffer = sha256.ComputeHash(Encoding.ASCII.GetBytes(key));
            var blockBuffer = new uint[2];
            var buffer = new byte[dataBytes.Length];
            Array.Copy(dataBytes, buffer, dataBytes.Length);
            using (var stream = new MemoryStream(buffer))
            {
                using (var writer = new BinaryWriter(stream))
                {
                    for (var i = 0; i < buffer.Length; i += 8)
                    {
                        blockBuffer[0] = BitConverter.ToUInt32(buffer, i);
                        blockBuffer[1] = BitConverter.ToUInt32(buffer, i + 4);

                        uint v0 = blockBuffer[0], v1 = blockBuffer[1], delta = 0x9E3779B9, sum = delta * keyBits;

                        for (uint j = 0; j < keyBits; j++)
                        {
                            v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + keyBuffer[(sum >> 11) & 3]);
                            sum -= delta;
                            v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + keyBuffer[sum & 3]);
                        }
                        blockBuffer[0] = v0;
                        blockBuffer[1] = v1;

                        writer.Write(blockBuffer[0]);
                        writer.Write(blockBuffer[1]);
                    }
                }
            }
            return Encoding.Unicode.GetString(buffer);
        }
    }
}

Output of the above program

XTEA output

10 Replies to “eXtended Tiny Encryption Algorithm (XTEA) – PART II”

  1. Good to learn, I always wonder about this topics 😀. I will also utilize my spare time to learn this topic

Leave a Reply

Your email address will not be published. Required fields are marked *