SHARE

In cryptography, the Tiny Encryption Algorithm (TEA) is a block cipher notable for its simplicity of description and implementation, typically a few lines of code. It was designed by David Wheeler and Roger Needham of the Cambridge Computer Laboratory; it was first presented at the Fast Software Encryption workshop in Leuven in 1994, and first published in the proceedings of that workshop.

TEA operates on two 32-bit unsigned integers (could be derived from a 64-bit data block) and uses a 128-bit key. It has a Feistel structure with a suggested 64 rounds, typically implemented in pairs termed cycles.

Source: https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm

We provide some function in PHP and Javascript

PHP

<?php

/**
* @author www.Tutorialspots.com
*/

class TEA{
/**
* TEA encrypt
* @param $v 64bits * @param$k 128bits
*/
public static function TEAencrypt ($v,$k) {
$v0=$v[0]; $v1=$v[1]; $sum=0; /* set up */$delta=0x9e3779b9;                     /* a key schedule constant */
$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; return$v;
}

/**
* TEA decrypt
* @param $v 64bits * @param$k 128bits
*/
public static function TEAdecrypt ($v,$k) {
$v0=$v[0]; $v1=$v[1]; $sum=0xC6EF3720; /* set up */$delta=0x9e3779b9;                     /* a key schedule constant */
$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; return$v;
}
}

?>

Javascript:

var TEA = {};
/**
* TEA encrypt
* @param v 64bits
* @param k 128bits
*/
TEA.TEAencrypt = function (v, k) {
var v0=v[0], v1=v[1], sum=0,           /* set up */
delta=0x9e3779b9,                     /* a key schedule constant */
k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
for (var 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;
return v;
}

/**
* TEA decrypt
* @param v 64bits
* @param k 128bits
*/
TEA.TEAdecrypt = function (v, k) {
var v0=v[0], v1=v[1], sum=0xC6EF3720,  /* set up */
delta=0x9e3779b9,                     /* a key schedule constant */
k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
for (var 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;
return v;
}
var x=TEA.TEAencrypt([65,65],[65,65,65,65]);
console.log(x);//[-3257293243,6661612959]
alert(TEA.TEAdecrypt(x,[65,65,65,65]));

Example:

var x=TEA.TEAencrypt([65,65],[65,65,65,65]);
console.log(x);
alert(TEA.TEAdecrypt(x,[65,65,65,65]));

Result:

[-3257293243,6661612959]
[65,65]

Try it yourself

Application of this block cipher method for stream cipher:
There are many methods, but we can provide the method below:
Split your string into many block with 64 bits (8 characters), then use this block cipher method. We can use the method Null-padding for the case the string length is odd.
The key must have 16 characters (128 bits), so, we must use one Key-scheduling algorithm (KSA) to convert the key to the new key 128 bits.

PHP:

    //TEA NULL padding
private static function _nullpadding($str){ if(strlen($str)%8 != 0){
$str .= str_repeat(chr(0),8-strlen($str)%8);
}
return $str; } //TEA Key-scheduling algorithm (KSA) private static function TEAKSA($key){
for ($s = array(),$i = 0; $i < 256;$i++)
$s[$i] = $i; for ($j = 0, $i = 0;$i < 256; $i++) {$j = ($j +$s[$i] + ord($key[$i % strlen($key)])) % 256;
$x =$s[$i];$s[$i] =$s[$j];$s[$j] =$x;
}
//return array_slice($s,0,16);$expanded = array();
$i = 0; while ($i < 64)
{
$expanded[$i] = $s[4 *$i];
for($j=1;$j<4;$j++)$expanded[$i] =$expanded[$i] |$s[4 * $i +$j] << (8*$j);$i++;
}
return $expanded; } // convert 32bits interger to 4characters string private static function _32bits2str($block){
return pack('N',$block & 0xffffffff); } // convert 4characters string to 32bits interger private static function _str232bits($block){
return unpack('N*',$block)[1]; } //Stream cipher encrypt use TEA public static function TEAenc($str,$key,$mode='ECB'){
$str = self::_nullpadding($str);//var_dump($str);die();$enc = '';
$k = self::TEAKSA($key); //var_dump($k);die(); for($i=0;$i<strlen($str)/8;$i++){$block = substr($str,$i*8,8);
$chr = array(self::_str232bits(substr($block,0,4)),self::_str232bits(substr($block,4,4)));$e = self::TEAencrypt($chr,$k);
$enc .= self::_32bits2str($e[0]).self::_32bits2str($e[1]); } return$enc;
}

//Stream cipher decrypt use TEA
public static function TEAdec($str,$key,$mode='ECB'){$enc = '';
$k = self::TEAKSA($key);//var_dump($k);die(); for($i=0;$i<strlen($str)/8;$i++){$block = substr($str,$i*8,8);
$chr = array(self::_str232bits(substr($block,0,4)),self::_str232bits(substr($block,4,4)));$e = self::TEAdecrypt($chr,$k);
$enc .= self::_32bits2str($e[0]).self::_32bits2str($e[1]); } return rtrim($enc,chr(0));
}

Here, we use ECB mode, you can use CBC, PCBC, CFB, OFB, CTR mode.

Javascript:

//TEA NULL padding
if(str.length % 8 != 0){
str += "\x00".repeat(8-str.length%8);
}
return str;
},

//TEA Key-scheduling algorithm (KSA)
TEAKSA: function (key){
var s=[],i,j,x,expanded = [];
for (i = 0; i < 256; i++)
s[i] = i;
for (j = 0, i = 0; i < 256; i++)
{
j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
x = s[i];
s[i] = s[j];
s[j] = x;
}
i = 0;
while (i < 64)
{
expanded[i] = s[4* i];
for(j=1;j<4;j++)
expanded[i] = expanded[i] | s[4* i + j] << (8*j);
i++;
}
return expanded;
},

// convert 32bits interger to 4characters string
_32bits2str: function (block){
return String.fromCharCode(block >> 24) +
String.fromCharCode(block >> 16 & 255) +
String.fromCharCode(block >> 8 & 255) +
String.fromCharCode(block & 255);
},
// convert 4characters string to 32bits interger
_str232bits: function (block){
return block.charCodeAt(3) | block.charCodeAt(2) << 8 | block.charCodeAt(1) << 16 | block.charCodeAt(0) << 24;
},

//Stream cipher encrypt use TEA
TEAenc: function (str,key,mode='ECB'){
var block,e;
enc = '';
k = this.TEAKSA(key);
for(i=0;i<str.length/8;i++){
block = str.substr(i*8,8);
chr = [this._str232bits(block.substr(0,4)),this._str232bits(block.substr(4,4))];
e = this.TEAencrypt(chr,k);
enc += this._32bits2str(e[0])+this._32bits2str(e[1]);
}
return enc;
},

//Stream cipher decrypt use TEA
var block,e;
enc = '';
k = this.TEAKSA(key);
for(i=0;i<str.length/8;i++){
block = str.substr(i*8,8);
chr = [this._str232bits(block.substr(0,4)),this._str232bits(block.substr(4,4))];
}
console.log(TEA.TEAenc("abc","abc"));
console.log(TEA.TEAdec(TEA.TEAenc("abc","abc"),"abc"));