TEA算法使用64位的明文分组和128位的密钥,它使用Feistel分组加密框架,需要进行 64 轮迭代,尽管作者认为 32 轮已经足够了。该算法使用了一个神秘常数δ作为倍数,它来源于黄金比率,以保证每一轮加密都不相同。但δ的精确值似乎并不重要,这里 TEA 把它定义为 δ=「(√5 - 1)231」(也就是程序中的 0×9E3779B9)。
简单的说就是,TEA加密解密是以原文以8字节(64位bit)为一组,密钥16字节(128位bit)为一组,(char为1字节,int为4字节,double为8字节),该算法加密轮次可变,作者建议为32轮,因为被加密的明文为64位,所以最终加密的结果也是64位。
代码实现:
加密:
void encry(unsigned int *v,unsigned int *k){unsigned int v0=v[0],v1=v[1];unsigned sum=0;unsigned k0=k[0],k1=k[1],k2=k[2],k3=k[3];unsigned int delta = 0x9e3779b9;for(int i=0;i<32;i++){sum+=delta;v0+=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);v1+=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);}v[0]=v0;v[1]=v1;
}
解密:
void decry(unsigned int *v,unsigned int *k){unsigned int v0=v[0],v1=v[1],sum=0xC6EF3720;unsigned k0=k[0],k1=k[1],k2=k[2],k3=k[3];unsigned int delta = 0x9e3779b9;for(int i=0;i<32;i++){v1-=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);v0-=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);sum-=delta;}v[0]=v0;v[1]=v1;}
完整代码:
测试用例:v[]={1,567},k[]={2,2,3,4}
#include <iostream>
#include <string>
#include <queue>
using namespace std;
void encry(unsigned int *v,unsigned int *k){unsigned int v0=v[0],v1=v[1];unsigned sum=0;unsigned k0=k[0],k1=k[1],k2=k[2],k3=k[3];unsigned int delta = 0x9e3779b9;for(int i=0;i<32;i++){sum+=delta;v0+=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);v1+=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);}v[0]=v0;v[1]=v1;
}
void decry(unsigned int *v,unsigned int *k){unsigned int v0=v[0],v1=v[1],sum=0xC6EF3720;unsigned k0=k[0],k1=k[1],k2=k[2],k3=k[3];unsigned int delta = 0x9e3779b9;for(int i=0;i<32;i++){v1-=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);v0-=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);sum-=delta;}v[0]=v0;v[1]=v1;}
int main(){unsigned int v[2]={1,567};unsigned int k[4]={2,2,3,4};encry(v,k);cout<<v[0]<<" "<<v[1]<<endl; decry(v,k);cout<<v[0]<<" "<<v[1]<<endl;}
注意事项:
detla 可以为任意值,解密的sum必须等于32*detla
<<与>>后的数可以为任意值,只要加密的与解密的相等即可。
v[]中的内容是32位的,两个加一起是64位。
例子:
2025HnuSec寒假招新ez_so
WP:
典型的TEA算法
密文。
当时做的时候看到这里就不会了,不是应该一次加密2组数吗,有三组数什么回事,而且这大小也不对吧,
使用Shift+E提取数据:
这感觉这也不对啊,当时也没好好做,也没有去学习TEA的原理,什么也看不出来,等后面官方WP出来后,也看不懂那12个数是怎么来的,现在终于明白了。
xmmword是一个128位的数据块,正好可以分成4个数据,两组V。
例如第一个:xmmword_5A0 xmmword 0ADCFB94655774D31F09B1CD9828FE749h
可以分为:ADCFB946 55774D31 F09B1CD 9828FE749
我不太理解为什么要逆序的来放.(这是小端序)
9828FE749 F09B1CD 55774D31 ADCFB946
这样就行了,但很费手
其他同理
exp:
#include <iostream>
using namespace std;
void decry(unsigned int *v,unsigned int *k,int n){unsigned int v0=v[n],v1=v[n+1],sum=0xC6EF3720;unsigned k0=k[0],k1=k[1],k2=k[2],k3=k[3];unsigned int delta = 0x9e3779b9;for(int i=0;i<32;i++){v1-=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);v0-=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);sum-=delta;}v[n]=v0;v[n+1]=v1;}
int main(){unsigned int v[12] = {0x828fe749, 0xf09b1cd9, 0x55774d31, 0xadcfb946,0x8d1c0b0, 0x8821441d, 0xa124ff59, 0x520f4848, 0xa124ff59, 0x520f4848,0x1214b05a, 0x5fc89b6b};unsigned int k[4]={1668048215, 1415933295, 2003127919, 1918989395};
for (int i=0;i<12;i+=2){decry(v,k,i);
}
for (int i=0;i<12;i++){char c = static_cast<char>(v[i]);cout<<c;
}}
flag{ohhhhh}
XTEA:
XTEA算法与TEA算法最大不同的是对密钥的运用,在TEA算法中,密钥是直接暴露的,而在XTEA中,密钥的运用是采取流的方式,不再固定,此外就是异或顺序的更改,其他的就没有什么区别了。
代码实现:
加密:
void encrypt(uint32_t *v,uint32_t *k,unsigned int n,int rounds){uint32_t v0=v[n],v1=v[n+1];uint32_t sum=0;uint32_t delta = 0x9E3779B9;for(int i = 0;i<rounds;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[n]=v0;v[n+1]=v1;
}
解密:
void decrypt (uint32_t *v,uint32_t *k,unsigned int n,int rounds){uint32_t v0=v[n],v1=v[n+1];uint32_t sum=0xC6EF3720;uint32_t delta = 0x9E3779B9;for(int i = 0;i<rounds;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[n]=v0;v[n+1]=v1;
}
完整代码:
#include <iostream>
#include <cstdint>
using namespace std;void encrypt(uint32_t *v,uint32_t *k,unsigned int n,int rounds){uint32_t v0=v[n],v1=v[n+1];uint32_t sum=0;uint32_t delta = 0x9E3779B9;for(int i = 0;i<rounds;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[n]=v0;v[n+1]=v1;
}
void decrypt (uint32_t *v,uint32_t *k,unsigned int n,int rounds){uint32_t v0=v[n],v1=v[n+1];uint32_t sum=0xC6EF3720;uint32_t delta = 0x9E3779B9;for(int i = 0;i<rounds;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[n]=v0;v[n+1]=v1;
}
int main(){uint32_t v[]={5,25};uint32_t k[]={1,2,3,4};encrypt(v,k,0,32);cout<<v[0]<<" "<<v[1]<<endl;decrypt(v,k,0,32);cout<<v[0]<<" "<<v[1]<<endl;
}
测试用例为5,25,密钥为 1,2,3,4
注意事项:
detla 可以为任意值,解密的sum必须等于32*detla
<<与>>后的数可以为任意值,只要加密的与解密的相等即可。
v[]中的内容是32位的,两个加一起是64位。