• Status: Solved
• Priority: Medium
• Security: Public
• Views: 383

# usage of encrypt/decrypt functions/convert char* to long*

the following two functions are taken from the website:
they implement the Tiny Encryption Algorithm (TEA)

void encipher(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,
a=k[0],b=k[1],c=k[2],d=k[3],n=32;

while(n-->0)
{
sum += delta;
y += (z << 4)+a ^ z+sum ^ (z >> 5)+b;
z += (y << 4)+c ^ y+sum ^ (y >> 5)+d;
}

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

void decipher(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,a=k[0],b=k[1],
c=k[2],d=k[3],n=32;

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

while(n-->0)
{
z -= (y << 4)+c ^ y+sum ^ (y >> 5)+d;
y -= (z << 4)+a ^ z+sum ^ (z >> 5)+b;
sum -= delta;
}

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

How would i use these functions to encrypt/decrypt a char* ? how can i convert char* to long* and will this do it? a simple typecast doesn't do it apparently.

mf
0
mc_fly
• 10
• 6
• 3
• +2
1 Solution

Commented:
Use the algorithm to get you an encrypted long. Then, convert the long into a string - by using another algorithm. Say, for each digit, substitute a character.
0

Author Commented:
i forgot to paste this comment.sorry about that

/************************************************

The Tiny Encryption Algorithm (TEA) by
David Wheeler and Roger Needham of the
Cambridge Computer Laboratory

**** ANSI C VERSION ****

Notes:

TEA is a Feistel cipher with XOR and
and addition as the non-linear mixing
functions.

Takes 64 bits of data in v[0] and v[1].
Returns 64 bits of data in w[0] and w[1].
Takes 128 bits of key in k[0] - k[3].

TEA can be operated in any of the modes
of DES. Cipher Block Chaining is, for example,
simple to implement.

n is the number of iterations. 32 is ample,
16 is sufficient, as few as eight may be OK.
The algorithm achieves good dispersion after
six iterations. The iteration count can be

Note this is optimised for 32-bit CPUs with
fast shift capabilities. It can very easily
be ported to assembly language on most CPUs.

delta is chosen to be the real part of (the
golden ratio Sqrt(5/4) - 1/2 ~ 0.618034
multiplied by 2^32).

************************************************/
0

Commented:
This works with two groups of 64 bits of data.  You can break a char * up to work with this as follows:

First, create a 128 bit key, such as:

long key[2], lFirst, lSecond;
key[0]=0xf83c88ef;
key[1]=0x8e1a79a4;

Then copy the first 2 characters of your string (sClear) into one long, and the next 2 characters of your string into the second long

memcpy(&lFirst, sClear[i], sizeof(long));
memcpy(&lSecond, sClear[i+2], sizeof(long);

when you get to the end, you might have to copy null values (if your string is not in multiples of 4 characters), but that is OK.

Then call

encipher(&lFirst,&lSecond, &key);

If you have a string to hold the encrypted text (let's call it sEncrypt), you would store the values by:

memcpy(&sEncrypt[i], &lFirst, sizeof(long));
memcpy(&sEncrypt[i], &lSecond, sizeof(long));

The reverse would deincrypt the string...
0

Commented:
>>how can i convert char* to long* and will this do it?

It does - the trick is that these routines only process 64 bits (8bytes) of data per call (see http://vader.eeng.brad.ac.uk/tea/tea.shtml - "It encrypts 64 data bits at a time using a 128-bit key"). So, if you want to encrypr a whole string, you have to break it down in 8byte chunks and use TEA for each of them, e.g.

char acKey [ 16] = ...; // place your key here
char acTestInput[] = "How would i use these functions to encrypt/decrypt a char* ?"
char* pInBuf;
char* pOutBuf;
unsigned long ul8ByteAlignedSize, ulInputSize;

ulInputSize = strlen ( acTestInput);
ul8ByteAlignedSize = ulInputSize + ( 8 - ( ulInputSize % 8));

pInBuf = ( char*) malloc ( ul8ByteAlignedSize);
pOutBuf = ( char*) malloc ( ul8ByteAlignedSize);

for ( int i = 0; i < ul8ByteAlignedSize; i+=8) {

encipher ( (unsigned long*) ( pInBuf + 8 * i), (unsigned long*) ( pOutBuf + 8 * i), (unsigned long*) acKey);
}
0

Author Commented:
this seems a bit complicated. i was hoping for some hints to functions in the std lib for the conversion. something like atoi or sscanf or sprintf or whatever to convert.
some source code would be greatly appreciated. something like:

char* in = "blabla"
char* out..
char* out2..
//convert 'in'? ( and 'out' ?)
encrypt(..in..out..)
//convert 'out' back to char*?
//do something with out
//convert 'out'? ( and 'out2' ?)
decrypt(..out..out2..)
//convert out2
//do something with out2

0

Author Commented:
that was meant for sarkalgud.
0

Author Commented:
i have to read and try a little. thanks so far.
0

Commented:
Error in my previous post -

Key needs to be an array of 4 longs, not 2, for 128 bit - my mind is sluggish today...
0

Commented:
Actually, ignore the whole thing.  The second parameter is the encrypted value (or deincrypted).  I assumed this was like a previous algorithm posted here which did 128 bytes at a time, not 64...

Will fix later if nobody has posted code for you...
0

Commented:
>>if nobody has posted code for you...

2l8 :o)
0

Author Commented:
gj62: thanks! looking forward to see an example
jkr: i seem to get an access violation when i execute your code. all i changed was the 'char acKey [ 16] = ...;'-line.it's odd that the encrypted string is printed and then the program crashes. geez, i feel really stupid.
0

Author Commented:
but then again..  it's 200 points
hope that excuses some stupidity ;)
0

Commented:
>> it's odd that the encrypted string is printed and then the program crashes

That sounds like the string is not null terminated.

>> geez, i feel really stupid.

Don't.

Exceter
0

Commented:
>> hope that excuses some stupidity ;)

The only stupid question is the one you don't ask.

Exceter
0

Author Commented:
that one fails. where's my mistake?

int main () {

char acKey [ 16] = "123456789123456" ; // place your key here
acKey[15] = '\0';
char acTestInput[] = "How would i use these functions to encrypt/decrypt a char* ?";
char* pInBuf;
char* pOutBuf;
unsigned long ul8ByteAlignedSize, ulInputSize;

ulInputSize = strlen ( acTestInput);
ul8ByteAlignedSize = ulInputSize + ( 8 - ( ulInputSize % 8));

pInBuf = ( char*) malloc ( ul8ByteAlignedSize);
pOutBuf = ( char*) malloc ( ul8ByteAlignedSize);

for ( int i = 0; i < ul8ByteAlignedSize; i+=8) {

encipher ( (unsigned long*) ( pInBuf + 8 * i), (unsigned long*) ( pOutBuf + 8 * i), (unsigned long*) acKey);
}
//cout << pOutBuf << endl;
return 0;
}
0

Commented:
Doesn't crash here...
0

Commented:
Shame on me :o)

Forgot the relevant part:

char acKey [ 16] = "123456789123456" ; // place your key here
acKey[15] = '\0';
char acTestInput[] = "How would i use these functions to encrypt/decrypt a char* ?";
char* pInBuf;
char* pOutBuf;
unsigned long ul8ByteAlignedSize, ulInputSize;

ulInputSize = strlen ( acTestInput);
ul8ByteAlignedSize = ulInputSize + ( 8 - ( ulInputSize % 8));

pInBuf = ( char*) malloc ( ul8ByteAlignedSize);
pOutBuf = ( char*) malloc ( ul8ByteAlignedSize);

// --------------------------------------------
memset ( pInBuf, 0, ul8ByteAlignedSize);
memset ( pOutBuf, 0, ul8ByteAlignedSize);
strcpy ( pInBut, acInput);
// --------------------------------------------

for ( int i = 0; i < ul8ByteAlignedSize; i+=8) {

encipher ( (unsigned long*) ( pInBuf + 8 * i), (unsigned long*) ( pOutBuf + 8 * i), (unsigned long*) acKey);
}
//cout << pOutBuf << endl;
return 0;
}

0

Author Commented:
yes, it works now.
when i use printf( "%s\n", pOutBuf);   only 8 characters are printed. i think there must be something missing since the input string is quite a bit longer. when i use cout i still get the access violation.
0

Commented:
>>i think there must be something missing

Well, the encrypted string is binary - it is sort of optimistic to use 'printf()' to output it, as there certainly might be NULL bytes in it.

But, I just spoppted an error - the call to encipher should be

encipher ( (unsigned long*) ( pInBuf + i), (unsigned long*) ( pOutBuf + i), (unsigned long*) acKey);

0

Author Commented:
this works, thank you.
how would i decipher it again? i tried that (s.b.) but it printed just rubbish. it looks awful atm, i know, but i want to get it to work before i think about 'doing it nicely'

int main () {

char acKey [ 16] = "123456789123456" ; // place your key here
acKey[15] = '\0';
char acTestInput[] = "How would i use these functions to encrypt/decrypt a char* ?";
char* pInBuf;
char* pOutBuf;
unsigned long ul8ByteAlignedSize, ulInputSize;

ulInputSize = strlen ( acTestInput);
ul8ByteAlignedSize = ulInputSize + ( 8 - ( ulInputSize % 8));

pInBuf = ( char*) malloc ( ul8ByteAlignedSize);
pOutBuf = ( char*) malloc ( ul8ByteAlignedSize);

memset ( pInBuf, 0, ul8ByteAlignedSize);
memset ( pOutBuf, 0, ul8ByteAlignedSize);
strcpy ( pInBuf, acTestInput);

for ( unsigned int i = 0; i < ul8ByteAlignedSize; i+=8) {
encipher ( (unsigned long*) ( pInBuf + i), (unsigned long*) ( pOutBuf + i), (unsigned long*) acKey);
}

printf( "%s\n", pOutBuf);

char* pInBuf2;
char* pOutBuf2;

unsigned long ul8ByteAlignedSize2, ulInputSize2;

ulInputSize2 = strlen ( pOutBuf);
ul8ByteAlignedSize2 = ulInputSize2 + ( 8 - ( ulInputSize2 % 8));

pInBuf2 = ( char*) malloc ( ul8ByteAlignedSize2);
pOutBuf2 = ( char*) malloc ( ul8ByteAlignedSize2);

// --------------------------------------------
memset ( pInBuf2, 0, ul8ByteAlignedSize2);
memset ( pOutBuf2, 0, ul8ByteAlignedSize2);
strcpy ( pInBuf2, pOutBuf);
// --------------------------------------------

for ( unsigned int j = 0; j < ul8ByteAlignedSize2; j+=8) {
decipher ( (unsigned long*) ( pInBuf2 + j), (unsigned long*) ( pOutBuf2 + j), (unsigned long*) acKey);
}

printf( "%s\n", pOutBuf2);

return 0;
}
0

Commented:
Hmm, that very source code works fine for me here:

int main () {

//__asm { int 3};

char acKey [ 16] = "123456789123456" ; // place your key here
acKey[15] = '\0';
char acTestInput[] = "How would i use these functions to encrypt/decrypt a char* ?";
char* pInBuf;
char* pOutBuf;
unsigned long ul8ByteAlignedSize, ulInputSize;

ulInputSize = strlen ( acTestInput);
ul8ByteAlignedSize = ulInputSize + ( 8 - ( ulInputSize % 8));

pInBuf = ( char*) malloc ( ul8ByteAlignedSize);
pOutBuf = ( char*) malloc ( ul8ByteAlignedSize);

memset ( pInBuf, 0, ul8ByteAlignedSize);
memset ( pOutBuf, 0, ul8ByteAlignedSize);
strcpy ( pInBuf, acTestInput);

for ( unsigned int i = 0; i < ul8ByteAlignedSize; i+=8) {
encipher ( (unsigned long*) ( pInBuf + i), (unsigned long*) ( pOutBuf + i), (unsigned long*) acKey);
}

printf( "Enciphered:\n%s\n", pOutBuf);

char* pInBuf2;
char* pOutBuf2;

unsigned long ul8ByteAlignedSize2, ulInputSize2;

ulInputSize2 = strlen ( pOutBuf);
ul8ByteAlignedSize2 = ulInputSize2 + ( 8 - ( ulInputSize2 % 8));

pInBuf2 = ( char*) malloc ( ul8ByteAlignedSize2);
pOutBuf2 = ( char*) malloc ( ul8ByteAlignedSize2);

// --------------------------------------------
memset ( pInBuf2, 0, ul8ByteAlignedSize2);
memset ( pOutBuf2, 0, ul8ByteAlignedSize2);
strcpy ( pInBuf2, pOutBuf);
// --------------------------------------------

for ( unsigned int j = 0; j < ul8ByteAlignedSize2; j+=8) {
decipher ( (unsigned long*) ( pInBuf2 + j), (unsigned long*) ( pOutBuf2 + j), (unsigned long*) acKey);
}

printf( "Deciphered again:\n%s\n", pOutBuf2);

free ( pInBuf);
free ( pOutBuf);
free ( pInBuf2);
free ( pOutBuf2);

return 0;
}
That's the output I am getting:

Enciphered:
6¹KCä¼&#9474;é]×&#9600;j&#9577;V¾£U&#9792;&#9830;&#9632;&#9792;"&#9787;&#9792;÷cé;&#9608;qGe9ß&#8595;Ë&#9824;à&#9472;å~@¾&#9532;å¶¯ò&#9496;Å'&#9474;Îm&#9474;4á|ÌIÐS"&#9786;&#9787;
Deciphered again:
How would i use these functions to encrypt/decrypt a char* ?
0

Author Commented:
thats strange. the output i get with your main() pasted to my source file is the following:

Enciphered:
ÔÐvýo&#9827;®py)7&#305;&#9508;²]9(Ìfá¦&#8616;&#9632;Ì®*&#9571;&#9792;4µØ&#9788;d&#8596;Ö&#8962;&#9668;ÿV9fî¤^&#9829;T|Ú&#9632;ƒ&#9571;_·^&#9571;¡\$¾&#9562;Uâ¦ƒ²²²²
Deciphered again:
j»bsô "¤Ó¢f1¥Mì|
ëÒ¿ïÙB2%À&#9472;Q×+û­-&#9556;Ð|³&#9474;&#9608;­ªrX®«¤x&#9565;ý{fèÂ&#9552;n}&#9824;ù&#8616;&#9830;S&#9556;æ9K R

but anyways, obviously it works as can be seen in your comment. thanks a lot for helping me out. i guess i need some time to get this thing to work, but im steady :)

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.