Tea、XTea、XXTea原理和实现

TEA算法

共同点

1、特征量(一般是0x9e3779b9,它是黄金分割数和232的乘积),可以替换成其他的值,但是可能会出现问题

2、主要加密部分进行异或和移位操作(一般都存在<<4、>>5)

3、key为128bit

Tea

加密流程

数组的奇数下标元素从右侧传入后进行了移位异或和相加操作,最后偶数下标加上上面操作完的值,所以可以把等式右边看成一个常数,这样写逆向脚本好理解

结束第一步之后,奇数下标元素的偶数下标元素进行置换,再对奇数下标进行相同的加密

第三步就是sum+=Delta

加密代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main()
{
unsigned int Data[8] = { 0 };
unsigned int key[4] = { 0 };
unsigned int tmp[2] = { 0 };
unsigned int sum = 0;
unsigned int delta = 0x9e3779b9;
for (int i = 0; i < 8; i += 2)
{
tmp[0] = Data[i];
tmp[1] = Data[i + 1];
sum=0;
for (int j = 0; j < 32; ++j)
{
sum += delta;
tmp[0] += ((tmp[1] << 4) + key[0]) ^ (tmp[1] + sum) ^ ((tmp[1] >> 5) + key[1]);
tmp[1] += ((tmp[0] << 4) + key[2]) ^ (tmp[0] + sum) ^ ((tmp[0] >> 5) + key[3]);
}
Data[i] = tmp[i];
Data[i + 1] = tmp[i + 1];
}
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
#include<string.h>
#include <stdio.h>

int main()
{
unsigned int Data[8] = { 0 };
unsigned int key[4] = { 0 };
unsigned int tmp[2] = { 0 };
unsigned int sum = 0;
unsigned int delta = 0x9e3779b9;
for (int i = 0; i < 8; i += 2)
{
tmp[0] = Data[i];
tmp[1] = Data[i + 1];
sum = delta*32;
for (int j = 0; j < 32; ++j)
{
tmp[1] -= ((tmp[0] << 4) + key[2]) ^ (tmp[0] + sum) ^ ((tmp[0] >> 5) + key[3]);
tmp[0] -= ((tmp[1] << 4) + key[0]) ^ (tmp[1] + sum) ^ ((tmp[1] >> 5) + key[1]);
sum -= delta;
}
Data[i] = tmp[i];
Data[i + 1] = tmp[i + 1];
}
return 0;
}

解密的时候主要是要找到Key和密文,并且可能会有大小端序的问题

XTea

Xtea是Tea的升级版,添加了一些移位和异或操作

加密流程

因为加密过程实际上没发生太多变化,就不贴加密和解密的代码了

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
56
57
58
59
60
61
62
63
64
#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 btea(uint32_t *v, int n, uint32_t const key[4]) //v是要加密的两个元素的数组
{ //n为数组的长度
uint32_t y, z, sum; //无符号整型
unsigned p, rounds, e;
if (n > 1) /* Coding Part */
{
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];
v[p] += MX;
z = v[p];
}
y = v[0];
z = v[n-1] += MX;
}
while (--rounds);
}
else if (n < -1) /* Decoding Part */
{
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]= {1,2};
uint32_t const k[4]= {2,2,3,4};
int n= 2; //n的绝对值表示v的长度,取正表示加密,取负表示解密
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
printf("加密前原始数据:%u %u\n",v[0],v[1]);
btea(v, n, k);
printf("加密后的数据:%u %u\n",v[0],v[1]);
btea(v, -n, k);
printf("解密后的数据:%u %u\n",v[0],v[1]);
return 0;
}

还没实现过,看着流程图不知道怎么入手