XTEA

简介

省流:TEA的大杯版

因为TEA加密有密钥调度算法过于简单(直接调用),密钥之间等价(每个密钥都被平均的使用)这两个缺陷,所以有了XTEA加密,XTEA将密钥调度的算法改为非线性的,并且略微修改了轮加密计算方法

特征

XTEA最大的特征就是每次加密使用的密钥由当前sum的累加值决定,通常是sum经过计算后&3,其余的特征和TEA加密基本相同

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
void xteaEncrypt(uint32_t *v, uint32_t *k)
{
uint32_t sum = 0, v0 = v[0], v1 = v[1];
uint32_t delta = 0x9E3779B9;
for (int i = 0; i < 32; i++)
{
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); // 使用非线性方式调用key
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]);
}
v[0] = v0;
v[1] = v1;
}

解密

虽然XTEA针对TEA进行了很多改进,但是对于逆向工程来说,我们并不是进行黑盒分析,所以XTEA和TEA并没有很大不同,直接使用Feistel密码的解法把运算过程反过来即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void xteaDecrypt(uint32_t *v, uint32_t *k)
{
uint32_t sum = 0, v0 = v[0], v1 = v[1];
uint32_t delta = 0x9E3779B9;
sum = delta * 32;
for (int i = 0; i < 32; i++)
{
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
}
v[0] = v0;
v[1] = v1;
}

完整代码

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
#include <bits/stdc++.h>
using namespace std;
void xteaEncrypt(uint32_t *v, uint32_t *k)
{
uint32_t sum = 0, v0 = v[0], v1 = v[1];
uint32_t delta = 0x9E3779B9;
for (int i = 0; i < 32; i++)
{
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]);
}
v[0] = v0;
v[1] = v1;
}
void xteaDecrypt(uint32_t *v, uint32_t *k)
{
uint32_t sum = 0, v0 = v[0], v1 = v[1];
uint32_t delta = 0x9E3779B9;
sum = delta * 32;
for (int i = 0; i < 32; i++)
{
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
}
v[0] = v0;
v[1] = v1;
}
int main()
{
uint32_t key[4] = {0x01234567, 0x89ABCDEF, 0xFEDCBA98, 0x76543210};
char plaintext[] = "Eleven11";
xteaEncrypt((uint32_t *)plaintext, key);
for (int i = 0; i < 8; i++)
printf("%02X ", plaintext[i] & 0xFF);
printf("\n");
xteaDecrypt((uint32_t *)plaintext, key);
for (int i = 0; i < 8; i++)
printf("%c", plaintext[i]);
return 0;
}

refernce

XTEA-wikipedia
Feistel network-wikipedia

Author

SGSG

Posted on

2025-04-08

Updated on

2025-04-18

Licensed under