Skip to main content
GameDev.net gamedev.net
🔒 Locked

TEA encryption algorithm

Started by wooohooo Feb 28, 2006 at 8:19 PM 4 replies 2.2k views
Original Post
wooohooo
wooohooo
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
iMalc
iMalc
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.
Extrarius
Extrarius
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.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
wooohooo
wooohooo
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 >> 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);}


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 )


Thanks for your time
LessBread
LessBread
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 &#106avascript version too: <a href="http://www.simonshepherd.supanet.com/jstea.htm">&#106avascript Text Message Encryption With The Tiny Encryption Algorithm</a>. I had forgotten all about that!
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.