65.9K
CodeProject is changing. Read more.
Home

Tiny Encryption Algorithm

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.14/5 (4 votes)

Jul 18, 2007

CPOL

1 min read

viewsIcon

64887

downloadIcon

2565

XTEA was designed by David Wheeler and Roger Needham of the Cambridge Computer Laboratory. This implementation is written in VB.NET, but the core algorithm is in C# (referred from http://www.codeproject.com/KB/windows/teaencryption.aspx).

Screenshot - text.jpg

Introduction

Inspired by this article, I tried to port the code to VB.NET. However, VB.NET does not have any implementation of arithmetic or bit operations, so it is difficult to implement the code / decode function of TEA. Readers can refer to the detailed explanation of XTEA on Wikipedia. I also took the advice from the discussion board to send 8 bytes at a time rather than 2 bytes at a time for encoding. System.bitConverter is used for conversion between UINT32 and String.

Using the Code

The solution contains two projects. ALgoXTEA is written in C# to implement the basic code / decode function:

public 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)
    {
        y += (z << 4 ^ z >> 5) + z ^ sum + k[sum & 3];
        sum += delta;
        z += (y << 4 ^ y >> 5) + y ^ sum + k[sum >> 11 & 3];
    }
    v[0]=y; v[1]=z;
}

In the VB project XTEACryptoVB, you need to add a reference to AlgoXTEA and then declare the function to code / decode with the same signatures as:

Public Declare Sub code Lib "algoXtea.dll" _
    Alias "code" (ByRef v As UInt32(), ByVal k As UInt32())
Public Declare Sub decode Lib "algoXtea.dll" (ByRef v As UInt32(), _
               ByVal k As UInt32()) 

The encryption algorithm is shown below. An instance of the algoXtea class is created, and the code / decode function can be called. 8 bytes of data is sent each time, and the formatKey() function ensures that the key is 16 bits in length:

Public Function encrypt(ByVal Data As String, ByVal key As String) As String
    If Data.Length = 0 Then
        Throw New ArgumentException("Data must be at least 1 characater in length.")
    End If

    Dim formattedKey() As UInt32 = FormatKey(key)
    'make sure data is in length of multiples of 8
    If Data.Length Mod 8 <> 0 Then
        For i As Integer = 0 To (8 - Data.Length Mod 8) - 1
            Data = Data + Chr(0)
        Next i
    End If

    Dim dataBytes As ArrayList
    dataBytes = New ArrayList(Data.Length)
    dataBytes.AddRange(System.Text.ASCIIEncoding.ASCII.GetBytes(Data))
    Dim cipher As String = String.Empty
    Dim tempData(2) As UInt32
    Dim fourBytes(4) As Byte

    For i As Integer = 0 To Data.Length - 1 Step 8
        For k As Integer = 0 To 3
            fourBytes(k) = dataBytes(i + k)
        Next k

       tempData(0) = BitConverter.ToUInt32(fourBytes, 0)

       For k As Integer = 0 To 3
         fourBytes(k) = dataBytes(i + 4 + k)
       Next k

       tempData(1) = BitConverter.ToUInt32(fourBytes, 0)
       Dim al As New AlgoXTEA.algo
       al.code(tempData, formattedKey)
       cipher = cipher + Util.ConvertUintToString(tempData(0))
       cipher = cipher + Util.ConvertUintToString(tempData(1))
    Next i
    Return cipher
End Function

The helper class is in Util.vb, which contains the method to convert between String and UINT32:

Public Shared Function ConvertStringToUint(ByVal input As String) As UInt32
    If input.Length <> 4 Then
        Throw New Exception("String length must be 4 in order to be converted!")
    End If
    Dim byteArray(4) As Byte
    Dim inputArray(4) As Char
    Dim output As UInt32

    inputArray = input.ToCharArray
    'convert to Bytes
    For i As Integer = 0 To 3
        byteArray(i) = Convert.ToByte(inputArray(i))
    Next i

    'convert to uint32
    output = BitConverter.ToUInt32(byteArray, 0)
    Return output

End Function

However, there is a problem with sending encrypted text as a string. If the encrypted character happens to be chr(0), which is a terminating character, it will not work. A solution is to send the hexadecimal representation of the decoded numbers instead of the string.

Update

The XTeaHex.zip file contains the implementation of converting the encoded unsigned integers to a hexadecimal string. Each byte is converted to a hex number and is represented as two characters (0-F) - this will avoid the problem of chr(0).