446,260 Members | 1,415 Online Need help? Post your question and get tips & solutions from a community of 446,260 IT Pros & Developers. It's quick & easy.

# TEA Implementation

 P: n/a I am having a few difficulties with implementing the tiny encryption algorithm (TEA) source code into a c program. I am rather new to c programming and have very little experience in it. I am confused in the way you send data to the sub-routines to encrypt and decrypt data. I was using the following source code to encrypt a 4 letter string, by it does not work. I am completely confused in how you can encrypt strings with the algorithm. Any help with this would be most appreciated! #include #include int main() { unsigned long v, k; char endp; v = strtoul(" the", endp, 2); k = strtoul("key ", endp, 2); code(v,k); return 0; } void code(long* v, long* k) { unsigned long y=v,z=v, sum=0, /* set up */ delta=0x9e3779b9, n=32 ; /* a key schedule constant */ while (n-->0) { /* basic cycle start */ sum += delta ; y += (z<<4)+k ^ z+sum ^ (z>>5)+k ; z += (y<<4)+k ^ y+sum ^ (y>>5)+k ; /* end cycle */ } v=y ; v=z ; } Nov 14 '05 #1
17 Replies

 P: n/a be***********@ntlworld.com (Ben Chivers) wrote in news:8b**************************@posting.google.c om: I am having a few difficulties with implementing the tiny encryption algorithm (TEA) source code into a c program. I am rather new to c I couldn't even read this code, here it is reformatted for humans. Hope this helps. #include #include int main(void) { unsigned long v; unsigned long k; char endp; v = strtoul(" the", endp, 2); k = strtoul("key ", endp, 2); code(v, k); return 0; } void code(long *v, long *k) { /* set up a key schedule constant */ unsigned long y = v; unsigned long z = v; unsigned long sum = 0; unsigned long delta = 0x9e3779b9; unsigned long n = 32; while (n-- > 0) { /* basic cycle start */ sum += delta ; y += (z << 4) + k ^ z + sum ^ (z >> 5) + k; z += (y << 4) + k ^ y + sum ^ (y >> 5) + k; /* end cycle */ } v = y; v = z; } -- - Mark -> -- Nov 14 '05 #2

 P: n/a "Ben Chivers" wrote in message #include #include int main() { unsigned long v, k; char endp; v = strtoul(" the", endp, 2); k = strtoul("key ", endp, 2); This is a misuse of strtol(). strtol is designed to convert human-readable number strings to computer-readable binaries. By passing " the" you are not giving strtol() a human-readable number to convert. I think what you wnat to do is to convert text to some sort of 32-bit integer, based on a coding scheme (maybe ASCII, maybe something else). In C, char variables can be treated either as characters or as small integers, so in a sense the coding is done for you. You just need to pack the letters into a long. v = (' ' << 24) | ('t' << 16) | ('h' << 8) | 'e'; code(v,k); return 0; } void code(long* v, long* k) /* it makes code much more readbale if you declar one variable per line */ /* do you know what you're doing mixing signed and unsigned here ? */ unsigned long y=v,z=v, sum=0, /* set up */ delta=0x9e3779b9, n=32 ; /* a key schedule constant */ while (n-->0) { /* basic cycle start */ sum += delta ; /* put parentheses in here to disambiguate. */ y += (z<<4)+k ^ z+sum ^ (z>>5)+k ; z += (y<<4)+k ^ y+sum ^ (y>>5)+k ; /* end cycle */ } v=y ; v=z ; } I trust that this function is doing what you want. Nov 14 '05 #3

 P: n/a On Tue, 23 Dec 2003, Mark A. Odell wrote: be***********@ntlworld.com (Ben Chivers) wrote... I am having a few difficulties with implementing the tiny encryption algorithm (TEA) source code into a c program. I am rather new to c I couldn't even read this code, here it is reformatted for humans. Hope this helps. Thanks, Mark. The OP should take note. Anyway, here's my take on the original question... #include #include int main(void) { unsigned long v; unsigned long k; char endp; v = strtoul(" the", endp, 2); k = strtoul("key ", endp, 2); Misuse of 'strtoul'. 'strtoul' converts strings like "12345" into numbers like 12345, not strings like " the" into numbers like 0x20716663. [I didn't bother looking up the real ASCII codes.] code(v, k); This implementation of TEA is obviously [to a good C programmer, although certainly not to a novice] expecting you to pass it pointers to the actual data. Like this: code((long*)"the string to be encrypted", (long *)"the key"); Only a little bit worse than that; you see, the function is designed to take only two longs' worth of data at a time (in this case, it's obviously designed for 32-bit longs). So you have to use a loop to do it [almost] right: /* at the top of 'main' declare these */ char key = "passwordpassword"; char plaintext = "the text to be encrypted"; /* must be 8| */ char *p; char *end = plaintext + sizeof plaintext; for (p = plaintext; p < end; p += 2) { /* The casts are ugly, but required */ code((long*)p, (long*)key); } return 0; } void code(long *v, long *k) This implementation of TEA is pretty awful, IMHO. It's poorly named, takes parameters of the wrong type, doesn't even make a pretense of being portable, and overwrites the plaintext with the ciphertext rather than storing it in a new buffer. Also, it has a hidden requirement: that the plaintext be exactly a multiple of 8 bytes long [hence the cryptic comment next to plaintext above] -- otherwise it barfs. The actual workings of TEA are "black magic" as far as I'm concerned; all you need to know is that it wants you to pass it 4*4 = 16 bytes of keytext, and 2*4 = 8 bytes of plaintext, which it will convert into 2*4 = 8 bytes of ciphertext and store back in the plaintext buffer. And that it only works on systems where 'long' is *exactly* 4 bytes long (and bytes are 8 bits wide). Left in the rest of the code for the benefit of those who come after me :), but no further comments. -Arthur { /* set up a key schedule constant */ unsigned long y = v; unsigned long z = v; unsigned long sum = 0; unsigned long delta = 0x9e3779b9; unsigned long n = 32; while (n-- > 0) { /* basic cycle start */ sum += delta ; y += (z << 4) + k ^ z + sum ^ (z >> 5) + k; z += (y << 4) + k ^ y + sum ^ (y >> 5) + k; /* end cycle */ } v = y; v = z; } Nov 14 '05 #4

 P: n/a "Arthur J. O'Dwyer" wrote in message news:... On Tue, 23 Dec 2003, Mark A. Odell wrote: be***********@ntlworld.com (Ben Chivers) wrote... I am having a few difficulties with implementing the tiny encryption algorithm (TEA) source code into a c program. I am rather new to c I couldn't even read this code, here it is reformatted for humans. Hope this helps. Thanks, Mark. The OP should take note. Anyway, here's my take on the original question... #include #include int main(void) { unsigned long v; unsigned long k; char endp; v = strtoul(" the", endp, 2); k = strtoul("key ", endp, 2); Misuse of 'strtoul'. 'strtoul' converts strings like "12345" into numbers like 12345, not strings like " the" into numbers like 0x20716663. [I didn't bother looking up the real ASCII codes.] code(v, k); This implementation of TEA is obviously [to a good C programmer, although certainly not to a novice] expecting you to pass it pointers to the actual data. Like this: code((long*)"the string to be encrypted", (long *)"the key"); Only a little bit worse than that; you see, the function is designed to take only two longs' worth of data at a time (in this case, it's obviously designed for 32-bit longs). So you have to use a loop to do it [almost] right: /* at the top of 'main' declare these */ char key = "passwordpassword"; char plaintext = "the text to be encrypted"; /* must be 8| */ char *p; char *end = plaintext + sizeof plaintext; for (p = plaintext; p < end; p += 2) { /* The casts are ugly, but required */ code((long*)p, (long*)key); } return 0; } void code(long *v, long *k) This implementation of TEA is pretty awful, IMHO. It's poorly named, takes parameters of the wrong type, doesn't even make a pretense of being portable, and overwrites the plaintext with the ciphertext rather than storing it in a new buffer. Also, it has a hidden requirement: that the plaintext be exactly a multiple of 8 bytes long [hence the cryptic comment next to plaintext above] -- otherwise it barfs. The actual workings of TEA are "black magic" as far as I'm concerned; all you need to know is that it wants you to pass it 4*4 = 16 bytes of keytext, and 2*4 = 8 bytes of plaintext, which it will convert into 2*4 = 8 bytes of ciphertext and store back in the plaintext buffer. And that it only works on systems where 'long' is *exactly* 4 bytes long (and bytes are 8 bits wide). Left in the rest of the code for the benefit of those who come after me :), but no further comments. -Arthur { /* set up a key schedule constant */ unsigned long y = v; unsigned long z = v; unsigned long sum = 0; unsigned long delta = 0x9e3779b9; unsigned long n = 32; while (n-- > 0) { /* basic cycle start */ sum += delta ; y += (z << 4) + k ^ z + sum ^ (z >> 5) + k; z += (y << 4) + k ^ y + sum ^ (y >> 5) + k; /* end cycle */ } v = y; v = z; } Heres my current code so far: #include #include void code(long* v, long* k); void decode( long* v, long* k ); int main(char argc[], char *argv[]) { char key = "passwor"; char plaintext = "the text to be encrypte"; /* must be 8| */ char *p, *d; char *end = plaintext + sizeof(plaintext); for (p = plaintext; p < end; p += 2) { /* The casts are ugly, but required */ code((long*)p, (long*)key); } printf("Encrypted String - %s\n", plaintext); char *end2 = plaintext + sizeof(plaintext); for (d = plaintext; d < end2; d += 2) { /* The casts are ugly, but required */ decode((long*)d, (long*)key); } printf("Decrypted String - %s\n", plaintext); system("PAUSE"); return 0; } void code(long* v, long* k) { unsigned long y = v, z = v, sum = 0, /* set up */ delta = 0x9e3779b9, n = 32; /* a key schedule constant */ while(n-- > 0) /* basic cycle start */ { sum += delta; y += (z << 4) + k ^ z + sum ^ (z >> 5) + k; z += (y << 4) + k ^ y + sum ^ (y >> 5) + k; } /* end cycle */ v = y; v = z; } void decode( long* v, long* k ) { unsigned long n = 32, sum, y = v, z=v, delta = 0x9e3779b9; sum = delta << 5; /* start cycle */ while(n-- > 0) { z -= (y << 4) + k ^ y + sum ^ (y >> 5) + k; y -= (z << 4) + k ^ z + sum ^ (z >> 5) + k; sum -= delta; } /* end cycle */ v = y; v = z; } It compiles and runs fine. From what I know the string actual encrypts fine, but when I try to decrypt the string which has just been encrypted, it doesn't return as the original string. I presume that the TEA function encrypts the variable plaintext and returns the encrypted string to be stored in the same variable through using pointers. Please remember I am only a beginner in this. I appreciate the help so far. Many Regards, Ben Chivers Nov 14 '05 #5

 P: n/a On Mon, 29 Dec 2003, Ben Chivers wrote: "Arthur J. O'Dwyer" wrote... be***********@ntlworld.com (Ben Chivers) wrote... > > I am having a few difficulties with implementing the tiny encryption > algorithm (TEA) source code into a c program. I am rather new to c This implementation of TEA is pretty awful, IMHO. It's poorly named, takes parameters of the wrong type, doesn't even make a pretense of being portable, and overwrites the plaintext with the ciphertext rather than storing it in a new buffer. Also, it has a hidden requirement: that the plaintext be exactly a multiple of 8 bytes long [hence the cryptic comment next to plaintext above] -- otherwise it barfs. Okay, Ben, I've done my homework now, and I can safely say that you've been misled by sloppy academic types. :-) The original paper on TEA, by Wheeler & Needham, is WRONG WRONG WRONG with respect to the reference implementation they provide. They left out several crucial pairs of parentheses, and both you and I were confused by that. Rightly so. The correct[ed?] code can be found at this site: http://pandora.imt.uwm.edu/docs/tea.c Note the extra parentheses in both functions. Now, the C code that site adds on top of the corrected TEA code is wrong, in that it doesn't check for strings that aren't of a length evenly divisible by 32 bits. Also, if you watch their code closely, you'll spot a rare idiocy hiding in the shadows: datasize = 0 ? 1 : datasize; Clever, eh? :-) Anyway, I've worked up a *COMPLETE* and hopefully *CORRECT* implementation of TEA, and posted it on my website at http://www.contrib.andrew.cmu.edu/~a.../tea-example.c Feel free to just grab and use that code as-is. But please watch this newsgroup for the inevitable corrections that will follow. :) Miscellaneous and hopefully moot comments: Heres my current code so far: char key = "passwor"; You need a 16-byte key, not just 8 bytes. char plaintext = "the text to be encrypte"; /* must be 8| */ In the version I've posted to my site, I've patched that requirement. You can now pass any length of data to the function, as long as you accurately report its actual length. char *p, *d; char *end = plaintext + sizeof(plaintext); for (p = plaintext; p < end; p += 2) Should be 'p += 8', or alternatively declare 'p' as 'long *' to begin with (or just use my version of the code ;). y += (z << 4) + k ^ z + sum ^ (z >> 5) + k; Here's where the reference implementation is WRONG WRONG WRONG. Change this line and the next one to match this outline: y += (z << 4) + (k ^ z) + (sum ^ (z >> 5)) + k; Similarly in 'decode'. I appreciate the help so far. You're welcome. I'm quite pleased, actually -- I found out why *my* TEA code wasn't working, too! :) -Arthur Nov 14 '05 #6

 P: n/a On Mon, 29 Dec 2003, Arthur J. O'Dwyer wrote: Anyway, I've worked up a *COMPLETE* and hopefully *CORRECT* implementation of TEA, and posted it on my website at http://www.contrib.andrew.cmu.edu/~a.../tea-example.c Feel free to just grab and use that code as-is. But please watch this newsgroup for the inevitable corrections that will follow. :) Aren't disclaimers wonderful? I should never, ever post code without some rigorous testing! When I added the wrapper functions that were supposed to let you encrypt any length of message, I forgot that the encryption shuffles around bits within the blocks. So I had worked it out so that (bad ASCII art) n o r m a l m e s s a g e |_|_|_|_|_|_|_|_I_|_|_|_|_| would get silently padded to n o r m a l m e s s a g e 0 0 0 |_|_|_|_|_|_|_|_I_|_|_|_|_|_|_|_| (where '0' represents the null byte) and then encrypted to something like e n c r y p t e d m e s s a g e |_|_|_|_|_|_|_|_I_|_|_|_|_|_|_|_| but then would get stored back into the destination buffer as a truncated version, like this: e n c r y p t e d m e s s |_|_|_|_|_|_|_|_I_|_|_|_|_| which the decoding routine would pad out to e n c r y p t e d m e s s 0 0 0 |_|_|_|_|_|_|_|_I_|_|_|_|_|_|_|_| and then proceed to foul up the result. You'll get n o r m a l m e g a r b a g e ! |_|_|_|_|_|_|_|_I_|_|_|_|_|_|_|_| Whoops! So the requirement for multiples of 8 bytes in encrypted messages still applies. I guess there's no way around it. HTH, -Arthur Nov 14 '05 #7

 P: n/a Arthur J. O'Dwyer writes: The correct[ed?] code can be found at this site: http://pandora.imt.uwm.edu/docs/tea.c Does anyone have a simple way to read that link with correct line feeds on a Windows machine? It is presented as one big line as I see it on my machine. Nov 14 '05 #9

 P: n/a "osmium" wrote in news:bs************@ID-179017.news.uni-berlin.de: Arthur J. O'Dwyer writes: The correct[ed?] code can be found at this site: http://pandora.imt.uwm.edu/docs/tea.c Does anyone have a simple way to read that link with correct line feeds on a Windows machine? It is presented as one big line as I see it on my machine. Loads perfectly in my Win32-based editor: CodeWright. Try reading the file with write instead of notepad. -- - Mark -> -- Nov 14 '05 #10

 P: n/a On Tue, 30 Dec 2003, osmium wrote: Arthur J. O'Dwyer writes: The correct[ed?] code can be found at this site: http://pandora.imt.uwm.edu/docs/tea.c Does anyone have a simple way to read that link with correct line feeds on a Windows machine? It is presented as one big line as I see it on my machine. I use Netscape Navigator, which handles Unix-style linefeeds correctly. That said, you can always try either http://www.google.com/search? q=cache:ufinmswLlXMJ:pandora.imt.uwm.edu/docs/tea.c (which for some reason changes < to <, & to &, and so on), or just download the file and view it in Word, Wordpad, or pretty much any other smart editor. Notepad doesn't understand Unix-style linefeeds, unfortunately. HTH, -Arthur Nov 14 '05 #11

 P: n/a Mark A. Odell writes: Loads perfectly in my Win32-based editor: CodeWright. Try reading the file with write instead of notepad. Yeaaa! Works with Wordpad. All I needed was the motivation, the belief that it might actually work with *something*. I still don't know what "write" is, sounds like a Macintosh program to me. Nov 14 '05 #12

 P: n/a "osmium" wrote in news:bs************@ID-179017.news.uni-berlin.de: Loads perfectly in my Win32-based editor: CodeWright. Try reading the file with write instead of notepad. Yeaaa! Works with Wordpad. All I needed was the motivation, the belief that it might actually work with *something*. I still don't know what "write" is, sounds like a Macintosh program to me. It has come with Windows since v3.0 I believe. -- - Mark -> -- Nov 14 '05 #13

 P: n/a Mark A. Odell wrote: "osmium" wrote in news:bs************@ID-179017.news.uni-berlin.de: Loads perfectly in my Win32-based editor: CodeWright. Try reading the file with write instead of notepad. Yeaaa! Works with Wordpad. All I needed was the motivation, the belief that it might actually work with *something*. I still don't know what "write" is, sounds like a Macintosh program to me. It has come with Windows since v3.0 I believe. I don't think so. write.exe got left behind with Windows 3.11. Windows 95 gave us Wordpad in its stead. Attempting to invoke write will get you Wordpad. Opening a .wri file will get you Wordpad. -- Joe Wright http://www.jw-wright.com "Everything should be made as simple as possible, but not simpler." --- Albert Einstein --- Nov 14 '05 #15

 P: n/a osmium wrote: Arthur J. O'Dwyer writes: The correct[ed?] code can be found at this site: http://pandora.imt.uwm.edu/docs/tea.c Does anyone have a simple way to read that link with correct line feeds on a Windows machine? It is presented as one big line as I see it on my machine. No problem here with Netscape 4.75. Displayed it, saved it, and loaded it into textpad with no problems. All lines were cr/lf terminated. -- Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net) Available for consulting/temporary embedded and systems. USE worldnet address! Nov 14 '05 #16

 P: n/a "osmium" wrote in message news:bs************@ID-179017.news.uni-berlin.de... Arthur J. O'Dwyer writes: The correct[ed?] code can be found at this site: http://pandora.imt.uwm.edu/docs/tea.c Does anyone have a simple way to read that link with correct line feeds on a Windows machine? It is presented as one big line as I see it on my machine. IE shouldn't have a problem, but failing that, WordPad usually does the job. -- Peter Nov 14 '05 #17 