Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB

Tiny Encryption Algorithm

2.14/5 (4 votes)
18 Jul 2007CPOL1 min read 1   2.6K  
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:

C#
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:

VB
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:

VB
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:

VB
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).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)