Page 1 of 1

### Tiny Encryption Algorithm (TEA)

Posted: 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).``````