Python TEA

Current Mood:
Dune Buggy emoticon
Dune Buggy

There currently don’t seem to be any publicly available implementations of TEA (Tiny Encryption Algorithm) in Python.  I had a need for one so I wrote one, here it is for what it’s worth.  Simply replace ‘k’ with a password of your choice and go for it.

The encrypt and decrypt functions both return strings that can be fed back into each other to reverse the encryption or decryption.

A lot of the heavy lifting in this was borrowed quite blatantly from this post.  I simply added a wrapper that would convert strings into proper chunks for encryption.  A side effect of this is that it will strip off trailing spaces from any string you want to encrypt/decrypt because that’s the padding character it uses.  This could probably be done better but it works in the application that I needed it.

#!/usr/bin/python

from binascii import hexlify, unhexlify

def mkbits(thestr):
    return long(eval('0x'+hexlify(thestr)))

def mkwords(thebits):
    return unhexlify(hex(thebits)[2:-1])

k = [mkbits("This"), mkbits(" is"), mkbits("pass"), mkbits("word")]

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

def encrypt(p):
    if p:
        p = "%s%s" % (p, " " * (8 - (len(p) % 8)))
        v = [mkbits(p[(x*4):(x*4)+4]) for x in range(len(p)/4)]
        c = [encipher([v[x*2],v[x*2+1]], k) for x in range(len(v)/2)]
        t = ",".join([",".join(["%s" % y for y in x]) for x in c])
        return t

def decrypt(s):
    if s:
        c = [long(x) for x in s.split(",")]
        d = [decipher([c[x*2], c[x*2+1]], k) for x in range(len(c)/2)]
        t = "".join(["".join(mkwords(y) for y in x).rstrip(' ') for x in d])
        return t
Leave a Reply