views:

224

answers:

3

Anybody knows proper python implementation of TEA (Tiny Encryption Algorithm)? I tried the one I've found here: http://sysadminco.com/code/python-tea/ - but it does not seem to work properly.

It returns different results than other implementations in C or Java. I guess it's caused by completely different data types in python (or no data types in fact).

Here's the code and an example:

def encipher(v, k):
    y=v[0];z=v[1];sum=0;delta=0x9E3779B9;n=32
    w=[0,0]
    while(n>0):
        y += (z << 4 ^ z >> 5) + z ^ sum + k[sum & 3]
        y &= 4294967295L # maxsize of 32-bit integer
        sum += delta
        z += (y << 4 ^ y >> 5) + y ^ sum + k[sum>>11 & 3]
        z &= 4294967295L
        n -= 1

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

def decipher(v, k):
    y=v[0]
    z=v[1]
    sum=0xC6EF3720
    delta=0x9E3779B9
    n=32
    w=[0,0]
    # sum = delta<<5, in general sum = delta * n

    while(n>0):
        z -= (y << 4 ^ y >> 5) + y ^ sum + k[sum>>11 & 3]
        z &= 4294967295L
        sum -= delta
        y -= (z << 4 ^ z >> 5) + z ^ sum + k[sum&3]
        y &= 4294967295L
        n -= 1

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

Python example:

>>> import tea
>>> key = [0xbe168aa1, 0x16c498a3, 0x5e87b018, 0x56de7805]
>>> v = [0xe15034c8, 0x260fd6d5]
>>> res = tea.encipher(v, key)
>>> "%X %X" % (res[0], res[1])
**'70D16811 F935148F'**

C example:

#include <unistd.h>
#include <stdio.h>

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;
}

int main()
{
        unsigned long v[] = {0xe15034c8, 0x260fd6d5};
        unsigned long key[] = {0xbe168aa1, 0x16c498a3, 0x5e87b018, 0x56de7805};

        unsigned long res[2];

        encipher(v, res, key);

        printf("%X %X\n", res[0], res[1]);

        return 0;
}

$ ./tea
**D6942D68 6F87870D**

Please note, that both examples were run with the same input data (v and key), but results were different. I'm pretty sure C implementation is correct - it comes from a site referenced by wikipedia (I couldn't post a link to it because I don't have enough reputation points yet - some antispam thing)

+1  A: 

Since TEA is a block cipher and your v is a very small block, I'd guess there may be block padding differences, or as Wikipedia notes: http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm:

Note that the reference implementation is bound to a specific microprocessor architecture meaning that byte order considerations are important when cyphertext is shared and processed on different systems. The original paper does not specify any details about microprocessor architecture and so anyone implementing a system using TEA would need to make those specifications for themselves.

I didn't inspect either implementation in detail. Your &= statements feel suspicious, too.

msw
+2  A: 

Tea is broken, do not use it.

XXTEA which is secure does not define endianess and stuff and you should should reinvent whell when you can use AES.

There is no point in using unsecure cryptography.

I strongy advice you to apply AES, it can be implemented in 8bit microcontolers whit just few kB of code

EDIT

Did you checked this code? http://sysadminco.com/code/python-tea/

ralu
I can't change the cryptography algorithm in this application. Server-side implementation uses TEA.
Gaks
Yeah, I even referenced the same code in my first post.
Gaks
*"There is no point in using unsecure cryptography."*Gur fgeratgu bs gur rapelcgvba arrqrq qrcraqf ba jub lbh ner gelvat gb uvqr vg sebz.
Seth
Qute Seth: "the strength of the encryption needed depends on who you are trying to hide it from"Implementing security by default aims at strongest attacker. Otherway you can not claim that your scheme is secure. Just obfuscated.
ralu
+3  A: 

I fixed it. Here is working TEA implementation in python:

from ctypes import *

def encipher(v, k):
    y=c_uint32(v[0]);
    z=c_uint32(v[1]);
    sum=c_uint32(0);
    delta=0x9E3779B9;
    n=32
    w=[0,0]

    while(n>0):
        sum.value += delta
        y.value += ( z.value << 4 ) + k[0] ^ z.value + sum.value ^ ( z.value >> 5 ) + k[1]
        z.value += ( y.value << 4 ) + k[2] ^ y.value + sum.value ^ ( y.value >> 5 ) + k[3]
        n -= 1

    w[0]=y.value
    w[1]=z.value
    return w

def decipher(v, k):
    y=c_uint32(v[0])
    z=c_uint32(v[1])
    sum=c_uint32(0xC6EF3720)
    delta=0x9E3779B9
    n=32
    w=[0,0]

    while(n>0):
        z.value -= ( y.value << 4 ) + k[2] ^ y.value + sum.value ^ ( y.value >> 5 ) + k[3]
        y.value -= ( z.value << 4 ) + k[0] ^ z.value + sum.value ^ ( z.value >> 5 ) + k[1]
        sum.value -= delta
        n -= 1

    w[0]=y.value
    w[1]=z.value
    return w

And a small sample:

>>> v
[1385482522, 639876499]
>>> tea.decipher(tea.encipher(v,key),key)
[1385482522L, 639876499L]
Gaks