// Tiny Encryption Algorithm // // The Tiny Encryption Algorithm is one of the fastest and most efficient // cryptographic algorithms in existence. It was developed by David // Wheeler and Roger Needham at the Computer Laboratory of Cambridge // University. It is a Feistel cipher which uses operations from mixed // (orthogonal) algebraic groups - XORs and additions in this case. It // encrypts 64 data bits at a time using a 128-bit key. It seems highly // resistant to differential cryptanalysis, and achieves complete // diffusion (where a one bit difference in the plaintext will cause // approximately 32 bit differences in the ciphertext) after only six // rounds. Performance on a modern desktop computer or workstation is // very impressive. // // // TEA takes 64 bits of data in v[0] and v[1], and 128 bits of key in // k[0] - k[3]. The result is returned in w[0] and w[1]. Returning the // result separately makes implementation of cipher modes other than // Electronic Code Book a little bit easier. // // TEA can be operated in any of the modes of DES. // // n is the number of iterations. 32 is ample, 16 is sufficient, as few // as eight should be OK for most applications, especially ones where // the data age quickly (real-time video, for example). The algorithm // achieves good dispersion after six iterations. The iteration count // can be made variable if required. // // Note this algorithm 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 Golden ratio ((5/4)1/2 - 1/2 ~ 0.618034) // multiplied by 232. On entry to decipher(), sum is set to be delta * // n. Which way round you call the functions is arbitrary: DK(EK(P)) = // EK(DK(P)) where EK and DK are encryption and decryption under key K // respectively. void encipher(const 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=0x9E3779B9L, 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(const unsigned long *const v,unsigned long *const w, const unsigned long * const k) { register unsigned long y=v[0],z=v[1],sum=0xC6EF3720L, delta=0x9E3779B9L,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; }