TEA加密算法学习

最近几场比赛都看到了TEA算法的影子,但是以前从来没接触过,今天刚好来学一下

TEA

TEA算法全称微型加密算法(Tiny Encryption Algorithm),先贴一下参考代码

#define uint unsigned int
void encrypt(uint *v, uint *key)
{
	uint l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
	for (int i = 1; i <= 32; ++i)
	{
		sum += delta;
		l += ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);
		r += ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);
	}
	v[0] = l, v[1] = r;
}
void decrypt(uint *v, uint *key)
{
	uint l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
	sum = delta * 32;
	for (int i = 1; i <= 32; ++i)
	{
		r -= ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);
		l -= ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);
		sum -= delta;
	}
	v[0] = l, v[1] = r;
}

其实看代码就已经很好理解了,加密算法中只涉及了几个量,v[0]和v[1]分别是第一、第二个明文,delta是TEA算法的一个重要特征值(magic number),固定为0x9e3779b9(当然可能有魔改版不是这个值?),有4个密钥key

显而易见的,TEA算法的强度在于其循环加密的次数

在一般情况下,TEA加密算法的密钥长度为128位,使用时首先判断密钥字节数组长度,如密钥字节数组长度小于16位,则将其长度扩展到16位,多余的位数用16进制的0x20代替(就是个空格)。然后将字节数组切分成4份,每4位为一新的字节数组,采用字节数组转无符号整数方法,完成密钥格式化成长度为4的无符号整数数组(就是上面代码里面的key[]数组的0~3位)。

相应的,明文字串的长度需要是偶数位,如果不是就用0x0增补一位。每两位明文用字节数组转无符号整数方法转换成2位无符号整数数组,并将这两个数进行加密(就是上面代码里的v[0],v[1]),并将加密后的数添加进新的字节数组,直到明文加密完毕。

解密过程恰好相反,在相应的解密后判断末位是否是0x0,是的话去掉就行

XTEA

XTEA是TEA算法的加强版,他增加了密钥的数量,位运算的操作也有所增加,还有一个差别是把r的变化结果和l的变化结果进行了交替赋值

#define uint unsigned int
void encrypt(uint *v, uint *key)
{
	uint l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
	for (int i = 1; i <= 32; ++i)
	{
		l += (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]);
		sum += delta;
		r += (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]);
	}
	v[0] = l;
	v[1] = r;
}

void decrypt(uint *v, uint *key)
{
	uint l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
	sum = delta * 32;
	for (int i = 1; i <= 32; ++i)
	{
		r -= (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]);
		sum -= delta;
		l -= (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]);
	}
	v[0] = l;
	v[1] = r;
}

XXTEA

先贴一个板子,后面找到好的博客再深入学习

#include <cstdio>
#define uint unsigned int
#define MX (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (k[(i & 3) ^ e] ^ z)))
void xxtea(uint *v, int n, uint *k)  
{
	uint y, z, sum, i, t, e, delta = 0x9e3779b9;;
	if (n > 1) // encrypt
	{
		t = 6 + 52 / n, sum = 0, z = v[n - 1];
		while (t--)
		{
			sum += delta, e = (sum >> 2) & 3;
			for (i = 0; i < n - 1; ++i)
			{
				y = v[i + 1];
				z = v[i] += MX;
			}
			y = v[0];
			z = v[n - 1] += MX;
		}
	}
	else if (n < -1) // decrypt
	{
		n = -n, t = 6 + 52 / n, sum = t * delta, y = v[0];
		while (t--)
		{
			e = (sum >> 2) & 3;
			for (i = n - 1; i > 0; --i)
			{
				z = v[i - 1];
				y = v[i] -= MX;
			}
			z = v[n - 1];
			y = v[0] -= MX;
			sum -= delta;
		}
	}
}
int main()
{
	uint v[2]= {1,2}, k[4]= {2,2,3,4};
	int n = 2; // abs(n) = strlen(v)
	printf("data: %u %u\n",v[0],v[1]);
	xxtea(v, n, k);
	printf("encrypt:%u %u\n",v[0],v[1]);
	xxtea(v, -n, k);
	printf("decrypt: %u %u\n",v[0],v[1]);
	return 0;
}
posted @ 2021-11-29 19:53  iPlayForSG  阅读(168)  评论(0编辑  收藏  举报