Tiny Encryption Algorithm (微型加密算法)
性质 块加密,对称加密
块加密:将明文按一定大小分组之后用确定的算法和对称密钥对魅族分别加密,一般来说加密和解密函数为反函数,一般会进行多轮加密 
对称加密:加密解密双方使用同一个密钥加密解密或双方使用的是两个可以简单地相互推算的密钥 
 
过程 定义与初始化 1 2 key = [a,b,c,d] delta = 0x9E3779B9  
 
轮加密 1 2 3 4 5 6 7 for  i in  (0 ,len (m),2 ):	x = m[i] 	y = m[i+1 ] 	for  j in  range (32 ): 		delta++ 		x += ((y << 4 ) + Key[0 ]) ^ (y + delta) ^ ((y >> 5 ) + Key[1 ]) 		y += ((x << 4 ) + Key[2 ]) ^ (x + delta) ^ ((x >> 5 ) + Key[3 ]) 
 
注:具体算法可能不同,但是一般都是x 由y和key改变,y由x和key改变,delta可能加可能减,但是一般情况不会把for i in (0,len(m),2)改成for i in (len-1),这样就不是块加密了
此处省略了&0xffffffff,需要让所有值都是int/dword,下面也是,之后不说了
 
XTEA的加密部分:
1 2 3 4 for  i in  range (n):    x += (((y << 4 ) ^ (y >> 5 )) + y) ^ (delta + key[delta & 3 ])     delta++     y += (((x << 4 ) ^ (x >> 5 )) + x) ^ (delta + key[(delta>>11 ) & 3 ]) 
 
注;相当于添加了与和位移,让key的取值不固定,但是框架没啥区别
 
XXTEA的加密部分
1 2 3 4 5 6 7 8 round  = 6  + 52  // n MX = lambda  sum , y, z, p, e, k: ((z >> 5  ^ y << 2 ) + (y >> 3  ^ z << 4 )) ^ ((sum  ^ y) + (k[p & 3  ^ e] ^ z)) for  i in  range  (round ):	sum  = (sum  + DELTA) & 0xffffffff  	e = sum  >> 2  & 3  	for  p in  range (n): 		y = m[(p + 1 ) % n] 		z = m[p] = (m[p] + MX(sum , y, z, p, e, k)) & 0xffffffff  
 
贴一个c语言版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #include  <stdio.h>  #include  <stdint.h>  #define  DELTA 0x9e3779b9 #define  MX (((z>>5^y<<2) + (y> >3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z))) void  xxtea (uint32_t * v, int  n, uint32_t * key) {     uint32_t  y, z, sum;     unsigned  p, rounds, e;     if  (n > 1 )                  {         rounds = 6  + 52 /n;         sum = 0 ;         z = v[n-1 ];         do          {             sum += DELTA;             e = (sum >> 2 ) & 3 ;             for  (p=0 ; p<n-1 ; p++)             {                 y = v[p+1 ];                 z = v[p] += MX;             }             y = v[0 ];             z = v[n-1 ] += MX;         }         while  (--rounds);     }     else  if  (n < -1 )           {         n = -n;         rounds = 6  + 52 /n;         sum = rounds * DELTA;         y = v[0 ];         do          {             e = (sum >> 2 ) & 3 ;             for  (p=n-1 ; p>0 ; p--)             {                 z = v[p-1 ];                 y = v[p] -= MX;             }             z = v[n-1 ];             y = v[0 ] -= MX;             sum -= DELTA;         }         while  (--rounds);     } } int  main () {          uint32_t  v[2 ] = {0x12345678 , 0x78563412 };          uint32_t  k[4 ]= {0x1 , 0x2 , 0x3 , 0x4 };          int  n = 2 ;     printf ("Data is : %x %x\n" , v[0 ], v[1 ]);     xxtea(v, n, k);     printf ("Encrypted data is : %x %x\n" , v[0 ], v[1 ]);     xxtea(v, -n, k);     printf ("Decrypted data is : %x %x\n" , v[0 ], v[1 ]);     return  0 ; } 
 
修正:XXTEA和前面两个的区别在于:
前两个加密只是两个两个地相互加密,但是xxtea是用前一个值和后一个值加密这个位,按每个都加密一遍算一轮,一共进行round轮,这里放一个我理解的XXTEA,根据网上的测试,都是一样的,但是不知道为什么如果用我的测试样例就过不了(网上的版本会失效)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include  <iostream>  #include  <stdint.h>  #include  "Arr.h"  int  XXTEA (Arr& input, uint32_t * const  key)   {	uint32_t  delta = 0x9E3779B9 ; 	uint32_t  sum = 0 ; 	uint32_t  len = input.getsize (); 	uint32_t  round = 52  / len + 6 ; 	 	for  (int  i = 0 ; i < round; i++) 	{ 		sum += delta; 		for  (int  now = 0 ; now < len; now++) 		{ 			input[now] += (((input[now - 1 ] >> 5  ^ input[now + 1 ] << 2 ) + 				(input[now + 1 ] >> 3  ^ input[now - 1 ] << 4 )) ^ ((sum ^ input[now + 1 ]) + 					(key[(now & 3 ) ^ ((sum >> 2 ) & 3 )] ^ input[now - 1 ]))); 		} 	} 	return  0 ; } int  deXXTEA (Arr& input, uint32_t * const  key)   {	uint32_t  delta = 0x9E3779B9 ; 	uint32_t  len = input.getsize (); 	uint32_t  round = 52  / len + 6 ; 	uint32_t  sum = delta * round; 	for  (int  i = 0 ; i < round; i++) 	{ 		for  (int  now = len - 1 ; now > -1 ; now--) 		{ 			input[now] -= (((input[now - 1 ] >> 5  ^ input[now + 1 ] << 2 ) + 				(input[now + 1 ] >> 3  ^ input[now - 1 ] << 4 )) ^ ((sum ^ input[now + 1 ]) + 					(key[(now & 3 ) ^ ((sum >> 2 ) & 3 )] ^ input[now - 1 ]))); 		} 		sum -= delta; 	} 	return  0 ; } int  main (void )   {	 	Arr* test = new  Arr ((uint32_t *)"HELLO_MESSAGE_he" , 4 ); 	 	uint32_t  const  key[4 ] = { 2 ,2 ,3 ,4  }; 	XXTEA (*test, (uint32_t *)key); 	std::cout << *test; 	deXXTEA (*test, (uint32_t *)key); 	std::cout << *test; 	std::cout << (char *)test->getarr (); 	return  0 ; } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #pragma  once #include  <initializer_list>  #include <algorithm>  #include <iostream>  #include  <iomanip>  #include  <cstring>  class  Arr { private :	size_t  size; 	unsigned  int * arr; public :	Arr (size_t  s); 	Arr (uint32_t * p, unsigned  s); 	Arr (std::initializer_list<unsigned  int > init); 	~Arr (); 	unsigned  int  getsize ()  const  ; 	unsigned  int * getarr ()  const  ; 	friend  std::ostream& operator <<(std::ostream& os, const  Arr& obj); 	unsigned  int & operator [](unsigned  i); 	unsigned  int * begin ()  const  ; 	unsigned  int * end ()  const  ; }; 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #include  "Arr.h"  Arr::Arr (size_t  s) : size (s), arr (new  uint32_t [s]) { 	std::fill_n (arr, s, 0 ); } Arr::Arr (uint32_t * p, unsigned  s) : Arr (s) { 	for  (size_t  i = 0 ; i < size; i++) 	{ 		arr[i] = p[i]; 	} } Arr::Arr (std::initializer_list<unsigned  int > init) :size (init.size ()), arr (new  unsigned  int [init.size ()]) { 	std::copy (init.begin (), init.end (), arr); } Arr::~Arr () { 	delete [] arr; } unsigned  int  Arr::getsize ()  const  {	return  size; } unsigned  int * Arr::getarr ()  const  {	return  arr; } unsigned  int & Arr::operator [](unsigned  i){ 	i = (i + size) % size; 	i = i >= 0  ? i : (i + size); 	return  arr[i]; } unsigned  int * Arr::begin ()  const  {	return  arr; } unsigned  int * Arr::end ()  const  {	return  arr + size; } std::ostream& operator <<(std::ostream& os, const  Arr& obj) { 	os << "len: "  << obj.getsize () << std::endl; 	os << "element list:"  << std::endl; 	for  (unsigned  i : obj) { 		os << "0x"  << std::hex << std::uppercase << std::setw (8 ) << std::setfill ('0' ) << i << std::endl; 	} 	return  os; } 
 
破解方法 缺陷 似乎网上很多blog都提到了密钥表攻击TEA,但是我没找到
[等待施工][QAQ]