Tiny Encryption Algorithm (TEA)

Share Tips, Code Samples, etc. with the Visual Prolog community.
Post Reply
Chan Bok
Active Member
Posts: 69
Joined: 13 Sep 2000 23:01

Tiny Encryption Algorithm (TEA)

Post by Chan Bok » 26 Nov 2012 10:18

The c codes for TEA (from Wikipedia) are as follows:

Code: Select all

void encrypt (uint32_t* v, uint32_t* k) {     uint32_t v0=v[0], v1=v[1], sum=0, i;           /* set up */     uint32_t delta=0x9e3779b9;                     /* a key schedule constant */     uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */     for (i=0; i < 32; i++) {                       /* basic cycle start */         sum += delta;         v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);         v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);     }                                              /* end cycle */     v[0]=v0; v[1]=v1; }

Code: Select all

void decrypt (uint32_t* v, uint32_t* k) {     uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;  /* set up */     uint32_t delta=0x9e3779b9;                     /* a key schedule constant */     uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */     for (i=0; i<32; i++) {                         /* basic cycle start */         v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);         v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);         sum -= delta;     }                                              /* end cycle */     v[0]=v0; v[1]=v1; }
======================================================================

The following is an implementation of TEA using VIP7.3(CE):

Code: Select all

class facts   v0_ : unsigned := 0.   v1_ : unsigned := 0.   sum_ :unsigned := 0.   class predicates   encrypt: (binary Orig, string Password) -> binary Encrypted.   decrypt: (binary Orig, string Password) -> binary Decrypted.   clauses   encrypt(OrigBin, Password) = AnsBin:-     hash_password(Password, K0, K1, K2, K3),     Len = binary::getSize(OrigBin),                         Ptr = uncheckedConvert(pointer, OrigBin),   % Make exact copy so un-processed bytes remain the same     AnsBin = binary::createAtomicFromPointer(Ptr, Len),     PairMax = Len div 8,                                % Process pairs of unsigned (i.e. 8 bytes at a time)       foreach Pair = std::fromTo(1, PairMax) do         Pair2 = Pair + Pair,         N0 = Pair2 - 2,         N1 = Pair2 - 1,         v0_ := binary::getIndexed_unsigned(OrigBin, N0),         v1_ := binary::getIndexed_unsigned(OrigBin, N1),         sum_ := 0,         foreach _N = std::fromTo(1, 32) do             sum_ := add(sum_, 0x9e3779b9),              % Delta = 0x9e3779b9             Temp0 = bit::bitXor((bit::bitXor(addL4(v1_, K0), add(v1_, sum_))), addR5(v1_, K1)),             v0_ := add(v0_, Temp0),             Temp1 = bit::bitXor((bit::bitXor(addL4(v0_, K2), add(v0_, sum_))), addR5(v0_, K3)),             v1_ := add(v1_, Temp1)         end foreach,                                    % Loop 32 times end         binary::setIndexed_unsigned(AnsBin, N0, v0_),         binary::setIndexed_unsigned(AnsBin, N1, v1_)     end foreach.                                        % Loop Pair end     decrypt(OrigBin, Password) = AnsBin:-     hash_password(Password, K0, K1, K2, K3),     Len = binary::getSize(OrigBin),     Ptr = uncheckedConvert(pointer, OrigBin),     AnsBin = binary::createAtomicFromPointer(Ptr, Len),     PairMax = Len div 8,                                % Process pairs of unsigned     foreach Pair = std::fromTo(1, PairMax) do         Pair2 = Pair + Pair,         N0 = Pair2 - 2,         N1 = Pair2 - 1,         v0_ := binary::getIndexed_unsigned(OrigBin, N0),         v1_ := binary::getIndexed_unsigned(OrigBin, N1),         sum_ := 0xC6EF3720,     % = (Delta << 5)         foreach _N = std::fromTo(1, 32) do             Temp1 = bit::bitXor((bit::bitXor(addL4(v0_, K2), add(v0_, sum_))), addR5(v0_, K3)),             v1_  := sub(v1_, Temp1),             Temp0 = bit::bitXor((bit::bitXor(addL4(v1_, K0), add(v1_, sum_))), addR5(v1_, K1)),             v0_  := sub(v0_, Temp0),             sum_ := sub(sum_, 0x9e3779b9)               % Delta = 0x9e3779b9,         end foreach,            % Loop 32 times end         binary::setIndexed_unsigned(AnsBin, N0, v0_),         binary::setIndexed_unsigned(AnsBin, N1, v1_)     end foreach.                % Loop Pair end   class predicates   add: (unsigned, unsigned) -> unsigned Result.        % Safe Addition with modulo   sub: (unsigned, unsigned) -> unsigned Result.        % Safe Subtraction   clauses   add(U32orig, U32incr) = convert(unsigned, Ans) :-         U64orig = convert(unsigned64, U32orig),         % Prevent integer overflow error         Ans = (U64orig + U32incr) mod 4294967296.       % 2^32     sub(Orig, Decr) = Ans :-         if Orig >= Decr then             Ans = Orig - Decr         else             Ans = (0xffffffff - Decr) + Orig + 1         end if.   class predicates   addR5 : (unsigned Orig, unsigned Incr) -> unsigned.   % bitRight by 5 bits then incr   addL4 : (unsigned Orig, unsigned Incr) -> unsigned.   % bitLeft  by 4 bits then incr   clauses   addR5(U, Incr) = add(Incr, bit::bitRight(U, 5)).     addL4(U, Incr) = add(Incr, bit::bitLeft(U, 4)).   class predicates   hash_password: (string Password, unsigned K1, unsigned K2, unsigned K3, unsigned K4) procedure (i,o,o,o,o).   clauses   hash_password(Password, K0, K1, K2, K3):-         PasswordSalted = string::concat(Password, "Put your salt here"),         HashBin = cryptography::hashString(crypt_native::calg_md5, PasswordSalted),         K0 = binary::getIndexed_unsigned8(HashBin, 0),         K1 = binary::getIndexed_unsigned8(HashBin, 1),         K2 = binary::getIndexed_unsigned8(HashBin, 2),         K3 = binary::getIndexed_unsigned8(HashBin, 3).
Chan Bok
Axon Research

Post Reply