Tiny Encryption Algorithm (TEA)
Posted: 26 Nov 2012 10:18
The c codes for TEA (from Wikipedia) are as follows:
======================================================================
The following is an implementation of TEA using VIP7.3(CE):
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).