# TEA encryption algorithm

This topic is 4670 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, I was trying to convert the code here to C heres the simple code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void encipher(const unsigned long *const v,unsigned long *const w,
const unsigned long * const k)
{
register unsigned long       y=v[0],z=v[1],sum=0,delta=0x9E3779B9,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];
}

w[0]=y; w[1]=z;
}

void decipher(const unsigned long *const v,unsigned long *const w,
const unsigned long * const k)
{
register unsigned long       y=v[0],z=v[1],sum=0xC6EF3720,
delta=0x9E3779B9,n=32;

/* sum = delta<<5, in general sum = delta * n */

while(n-->0)
{
z -= (y << 4 ^ y >> 5) + y ^ sum + k[sum>>11 & 3];
sum -= delta;
y -= (z << 4 ^ z >> 5) + z ^ sum + k[sum&3];
}

w[0]=y; w[1]=z;
}

unsigned long ConvertStringToUInt(char *input)
{
unsigned long output=0;

output =  ((unsigned long)input[0]);
output += ((unsigned long)input[1] << 8);
output += ((unsigned long)input[2] << 16);
output += ((unsigned long)input[3] << 24);

return output;
}

void ConvertUIntToString(unsigned long input,char *szOutput)
{
char tempChar;
char szReturn[64]={0};

tempChar = (char)input & 0xFF;
szReturn[0]=tempChar;
tempChar = (char)((input >> 8) & 0xFF);
szReturn[1]=tempChar;
tempChar = (char)((input >> 16) & 0xFF);
szReturn[2]=tempChar;
tempChar = (char)((input >> 24) & 0xFF);
szReturn[3]=tempChar;

sprintf(szOutput,"%s",szReturn);
}
void Decrypt(char* data, char *key, char*decrypted)
{
unsigned long tempData[2];
unsigned long returnData[2];
char szTemp[128]={0};
unsigned long longKey[64];
unsigned int i;

//printf(">>>>>>%d %s\n",strlen(key),key);

for(i=0;i<64;i++){longKey=0;}
for(i=0;i<strlen(key);i++)
{
longKey=key;
}

for(i=0;i<strlen(data);i+=8)
{
strncpy(szTemp,data+i,4);
tempData[0]=ConvertStringToUInt(szTemp);
strncpy(szTemp,data+i+4,4);
tempData[1]=ConvertStringToUInt(szTemp);

printf("> (%c-%c)\n",tempData[0],tempData[1]);
decipher(tempData,returnData,longKey);
printf("> (%c-%c)\n",returnData[0],returnData[1]);

}
}

void Encrypt(char* data,char *key,char* encrypted)
{
unsigned long tempData[2];
unsigned long tempData2[2];
unsigned long returnData[2];

char szTemp[128]={0};
unsigned long longKey[64];
unsigned int i;

//printf(">>>>>>%d %s\n",strlen(key),key);
if(strlen(data)%2!=0)
{
data[strlen(data)]='\0';
}

for(i=0;i<64;i++){longKey=0;}
for(i=0;i<strlen(key);i++)
{
longKey=key;
}

for(i=0;i<strlen(data);i+=2)
{
tempData[0]=data;
tempData[1]=data[i+1];

encipher(tempData,returnData,longKey);
printf("> (%c-%c)\n",returnData[0],returnData[1]);
decipher(returnData,tempData2,longKey);
printf("> (%c-%c)\n",tempData2[0],tempData2[1]);

ConvertUIntToString(returnData[0],szTemp);
strcat(encrypted,szTemp);
ConvertUIntToString(returnData[1],szTemp);
strcat(encrypted,szTemp);
}
}

void main()
{
char szEncrypted[128]={0};
char szDecrypted[128]={0};
char szString[128]={0};
char szKey[64]="thekey";

scanf("%s",szString);

Encrypt(szString,szKey,szEncrypted);

printf("Encrypted:%s\n",szEncrypted);

Decrypt(szEncrypted,szKey,szDecrypted);

printf("Decrypted:%s\n",szDecrypted);

}


I don't really understand the technicalities behind the algorithm but the output ive been getting is
Quote:
 hi > ( -+) > (h-i) Encrypted: S►}+ö¼♦ > ( -+) > (┤-°) Decrypted:
as you can see, in the Encrypt function, i encipher the string, and decipher it straight away for debug purposes In the Decrypt function i print out the data being passed into the decipher function for debug purposes as shown above, the data being passed into the decipher function in function Encrypt and Decrypt is the same " -+" but the output is different My only guesses were, the key im passing in differs, or the encoding is related to variable address? Why does the decipher function behave so? any help would be appreciated Thanks in advance encipher and decipher functions taken from http://www.simonshepherd.supanet.com/tea.htm

##### Share on other sites
First of all you can't do strlen(data) on the encrypted data. The encryption and decryption process work with binary data, and as such, encryption could output any number of null characters. strlen would then cut the data short.
The same flaw is limiting you in other places such as the key itself, too.

Basically you must eliminate eny occurrence of strlen in that code, and instead pass the length around as a parameter to anything requiring it.

You shouldn't be trying to print out the encrypted data either, as that not only stops at the first null character, but does unwanted things for binary data. You should instead output the data after first converting it to hex.

The original code used 'string's, which are allowed to contain embedded nulls.

Your replacement for 'FormatKey' in both your encrypt and decrpyt are totally wrong. They longKey should only be 4 (32-bit) ints in length, not 64. I presume that the key is supposed to be stored in a hex string, in which case you should be again making use of binary <-> hex string conversion routnies.

##### Share on other sites
Just so you know, applying the encryption algorithm to each block of data individually (called 'electronic codebook mode') is not at all the correct way to use a block cipher. Even if the algorithm itself is the best, using it like that introduces all kinds of problems.

If you're going to use encryption for anything (even stuff that doesn't need to be secure at all), you might as well do it right.

See Block Cipher Modes of Operation on wikipedia for a primer.

##### Share on other sites
Hi, Thanks for the replies

Clearly, I am not at this level of programming but would like to learn more

Correct me if i'm wrong and forgive my noob questions

void ConvertUIntToString(unsigned long input,char *szOutput){	char tempChar;	char szReturn[64]={0};	tempChar = (char)input & 0xFF;	szReturn[0]=tempChar;	tempChar = (char)((input &gt;&gt; 8) & 0xFF);	szReturn[1]=tempChar;	tempChar = (char)((input &gt;&gt; 16) & 0xFF);	szReturn[2]=tempChar;	tempChar = (char)((input &gt;&gt; 24) & 0xFF);	szReturn[3]=tempChar;	sprintf(szOutput,"%s",szReturn);}

the code above will split a 32 bit integer into 8 bit blocks , each represented by a char
the >> operator will shift the bits 8 bits at a time , and the & 0XFF will extract the 8 right most bits
am i correct so far?

Is FormatKey a standard C# sharp function? as i could not find an explanation from the author on what the function does

Quote:
 Your replacement for 'FormatKey' in both your encrypt and decrpyt are totally wrong. They longKey should only be 4 (32-bit) ints in length, not 64. I presume that the key is supposed to be stored in a hex string, in which case you should be again making use of binary <-> hex string conversion routnies.

I am not clear on this part, could you point me further in the right direction by giving an example perhaps

Quote:
 Just so you know, applying the encryption algorithm to each block of data individually (called 'electronic codebook mode') is not at all the correct way to use a block cipher. Even if the algorithm itself is the best, using it like that introduces all kinds of problems.If you're going to use encryption for anything (even stuff that doesn't need to be secure at all), you might as well do it right.See Block Cipher Modes of Operation on wikipedia for a primer.

Thanks for the suggestions

And, are there any simple but reasonably secure and reputable encryption algorithms that anyone can suggest?
It has to be platform and language independant ( easy to implement in various languages and platforms )

bump

##### Share on other sites
Here's a link where you can find out pretty much everything you ever wanted to know about the Tiny Encryption Algorithm. There's even an ANSI C version of it - and - to pat myself on the back - that site links to my a javascript version too: javascript Text Message Encryption With The Tiny Encryption Algorithm. I had forgotten all about that!

1. 1
2. 2
Rutin
16
3. 3
4. 4
5. 5

• 26
• 11
• 9
• 9
• 11
• ### Forum Statistics

• Total Topics
633706
• Total Posts
3013465
×