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 * @copyright 2017 */ 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]
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 _nullpadding: function(str){ 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; str = this._nullpadding(str); 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 TEAdec: 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.TEAdecrypt(chr,k); enc += this._32bits2str(e[0])+this._32bits2str(e[1]); } return enc.replace(/(\\x00)+$/,""); }
Example:
console.log(TEA.TEAenc("abc","abc")); console.log(TEA.TEAdec(TEA.TEAenc("abc","abc"),"abc"));
Read more:
Test vectors TEA
XTEA block cipher implement in PHP and Javascript
XXTEA block cipher implement in PHP and Javascript
3 Comments
Test vectors TEA | Free Online Tutorials
(January 21, 2017 - 1:50 pm)[…] Read first: TEA block cipher implement in PHP and Javascript […]
XTEA block cipher implement in PHP and Javascript | Free Online Tutorials
(January 22, 2017 - 2:40 am)[…] more: TEA block cipher implement in PHP and Javascript Test vectors TEA XXTEA block cipher implement in PHP and […]
XXTEA block cipher implement in PHP and Javascript | Free Online Tutorials
(January 22, 2017 - 2:41 am)[…] more: TEA block cipher implement in PHP and Javascript Test vectors TEA XTEA block cipher implement in PHP and […]