1.TEA算法
在安全学领域,TEA(Tiny Encryption Algorithm)是一种分组加密算法,它的实现非常简单,通常只需要很精短的几行代码。TEA 算法最初是由剑桥计算机实验室的 David Wheeler 和 Roger Needham 在 1994 年设计的。
TEA算法使用64位的明文分组和128位的密钥,它使用Feistel分组加密框架,将明文分为两个32位无符号数,密钥分为4个32位无符号数子密钥,进行迭代(一般建议32轮)最后得到64位密文。该算法使用了一个神秘常数δ作为倍数,它来源于黄金比率,以保证每一轮加密都不相同。但δ的精确值并不重要,这里 TEA 把它定义为 δ=「(√5 - 1)231」(也就是程序中的 0×9E3779B9),该值也可能会魔改防止被作为特征识别。 加密流程大致为: 1.TEA以原文每8字节加解密(如果明文本身的长度不是8的倍数,那么还要进行填充以使其成为8的倍数),分成左右两边各四字节传入L(0)、R(0)。 2.右边传入的四个字节R(0),与密钥K和常数δ进行一系列左右移、相加、异或操作,得到结果F(R(0),K,δ),L(1)=L(0)+F(R(0),K,δ)。 3.L(1)再与密钥K和常数δ进行一系列左右移、相加、异或操作,得到结果F(L(1),K,δ),R(1)=R(0)+F(L(1),K,δ)。 4.以此重复32轮得到加密后的L和R。 具体实现代码如下:#include <stdio.h> #include <stdint.h> //加密函数 void encrypt (uint32_t* v, uint32_t* k) { uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */ uint32_t delta=0x9e3779b9; /* a key schedule constant */ uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */ for (i=0; i < 32; i++) { /* basic cycle start */ sum += delta; v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1); v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3); } /* end cycle */ v[0]=v0; v[1]=v1; } //解密函数 void decrypt (uint32_t* v, uint32_t* k) { uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */ uint32_t delta=0x9e3779b9; /* a key schedule constant */ uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */ for (i=0; i<32; i++) { /* basic cycle start */ v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3); v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1); sum -= delta; } /* end cycle */ v[0]=v0; v[1]=v1; } int main() { uint32_t v[2]={1,2},k[4]={2,2,3,4}; // v为要加密的数据是两个32位无符号整数 // k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位 printf("加密前原始数据:%u %u\n",v[0],v[1]); encrypt(v, k); printf("加密后的数据:%u %u\n",v[0],v[1]); decrypt(v, k); printf("解密后的数据:%u %u\n",v[0],v[1]); return 0; }
2.XTEA算法 之后 TEA 算法被发现存在缺陷,作为回应,设计者提出了一个 TEA 的升级版本——XTEA。XTEA 跟 TEA 使用了相同的简单运算,但它采用了截然不同的顺序,为了阻止密钥表攻击,四个子密钥采用了其他方式进行混合,但速度更慢了。 具体代码如下:
#include <stdio.h> #include <stdint.h> /* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */ void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) { unsigned int i; uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9; for (i=0; i < num_rounds; i++) { v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]); sum += delta; v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]); } v[0]=v0; v[1]=v1; } void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) { unsigned int i; uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds; for (i=0; i < num_rounds; i++) { v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]); sum -= delta; v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]); } v[0]=v0; v[1]=v1; } int main() { uint32_t v[2]={1,2}; uint32_t const k[4]={2,2,3,4}; unsigned int r=32;//num_rounds建议取值为32 // v为要加密的数据是两个32位无符号整数 // k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位 printf("加密前原始数据:%u %u\n",v[0],v[1]); encipher(r, v, k); printf("加密后的数据:%u %u\n",v[0],v[1]); decipher(r, v, k); printf("解密后的数据:%u %u\n",v[0],v[1]); return 0; }
3.XXTEA算法 XXTEA算法加解密函数均接受三个参数,待加解密的32位数据块数组、数据块数组长度、128位密钥。 每一轮迭代都会对32位数据块数组中每个元素进行加解密操作。在实际使用中还需要对数据进行填充等处理,以保证数据块长度为32位的倍数。 加密轮数rounds=6+52/n n表示待加密的数据块组的长度,单位为字节。公式中的除数52是一个常数,与数据块长度无关,它是根据算法的设计和实验结果确定的。 这个公式的含义是,对于给定的数据长度,根据公式计算出加密轮数rounds,以便在加密过程中执行足够的轮数,达到较高的安全性。 加解密过程大致为, 1.传入数据块数组v[0,1,2,3...n-1],并计算轮数等相关参数。 2.加密的每一轮迭代中,都从v[0]开始,与其相邻的两个数据块、密钥K、δ进行相应操作计算,v[0]=v[0]+F(v[n-1],v[1]),v[1]=v[1]+F(v[0],v[2]).......v[n-1]=v[n-1]+F(v[n-2],v[0]。 3.解密的每一轮迭代中,都从v[n-1]开始,与其相邻的两个数据块、密钥K、δ进行相应操作计算,v[n-1]=v[n-1]-F(v[n-2],v[0]),v[n-2]=v[n-2]-F(v[n-3],v[n-1])......v[0]=v[0]-F(v[n-1],v[1]) 具体代码如下:
#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]) { 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]; z = v[p] += MX; } 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; }
标签:加密,TEA,sum,v0,v1,XTEA,32,uint32,XXTEA From: https://www.cnblogs.com/Heyyy/p/16849541.html