?
Solved

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

Posted on 2003-03-04
22
Medium Priority
?
375 Views
Last Modified: 2010-04-15
the following two functions are taken from the website:
http://vader.eeng.brad.ac.uk/tea/source.shtml
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.

thanks in advance
mf
0
Comment
Question by:mc_fly
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 6
  • 3
  • +2
22 Comments
 

Expert Comment

by:sarkalgud
ID: 8066687
How about this?
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 Comment

by:mc_fly
ID: 8066696
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
made variable if required.

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
 
LVL 6

Expert Comment

by:gj62
ID: 8066698
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

Expert Comment

by:jkr
ID: 8066725
>>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 Comment

by:mc_fly
ID: 8066760
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 Comment

by:mc_fly
ID: 8066766
that was meant for sarkalgud.
0
 

Author Comment

by:mc_fly
ID: 8066780
i have to read and try a little. thanks so far.
0
 
LVL 6

Expert Comment

by:gj62
ID: 8066790
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
 
LVL 6

Expert Comment

by:gj62
ID: 8066813
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
 
LVL 86

Expert Comment

by:jkr
ID: 8066837
>>if nobody has posted code for you...

2l8 :o)
0
 

Author Comment

by:mc_fly
ID: 8066853
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 Comment

by:mc_fly
ID: 8066877
but then again..  it's 200 points
hope that excuses some stupidity ;)
0
 
LVL 8

Expert Comment

by:Exceter
ID: 8066912
>> 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
 
LVL 8

Expert Comment

by:Exceter
ID: 8066931
>> hope that excuses some stupidity ;)

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

Exceter
0
 

Author Comment

by:mc_fly
ID: 8067027
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
 
LVL 86

Expert Comment

by:jkr
ID: 8067213
Doesn't crash here...
0
 
LVL 86

Expert Comment

by:jkr
ID: 8067228
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 Comment

by:mc_fly
ID: 8067465
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
 
LVL 86

Expert Comment

by:jkr
ID: 8067494
>>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 Comment

by:mc_fly
ID: 8067632
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
 
LVL 86

Accepted Solution

by:
jkr earned 800 total points
ID: 8071668
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 Comment

by:mc_fly
ID: 8073866
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 :)

oh and btw Exceter: i really appreciate your comments
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question