https://gdufs-king.github.io/2020/01/03/Tea%E7%AE%97%E6%B3%95%E5%8F%8A%E5%85%B6%E5%8F%98%E7%A7%8D%E7%A0%94%E7%A9%B6/

经典 Tea 加密

https://www.cnblogs.com/zpchcbd/p/15974293.html

特征值识别

模式匹配

TEA 算法的实现

 
#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;
}

XTea

 
#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;  
}  
//加密过程发现不同之处在于,加密算法变了,key 的利用不同,同时多了轮转数的选择,其他的还是变化不大,还是一样可以逆推。 
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;  
}

这里在知道 tea 算法的基础上,再记住特征,key[sum&3],还有轮转数的选择,就可以认出 Xtea 算法了

XXtea

#include <stdio.h>  
#include <stdint.h>  
#define DELTA 0x9e3779b9  
  
void btea (uint32_t *v, int n, uint32_t const key[4])  
{  
    uint32_t y, z, sum;  
    unsigned i, rounds, e;  
    if (n > 1)            //n 作为加解密的选择,正数为加密,负数为解密
    {  
        rounds = 6 + 52/n; //轮转数的选择,是个特征值:6+52/n
        sum = 0;  
        z = v[n-1]; //先取出最后一个值  
        do  
        {  
            sum += DELTA;  //开始加密
            e = (sum >> 2) & 3;  //通过 sum 得到 e,也是个特征值
            for (i=0; i<n-1; i++)  //轮转次数
            {  
                y = v[i+1];  //得到
                v[i] += (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(i&3)^e] ^ z)));  
                z = v[i];
                //细细分析就会知道,首先通过 v[n-1]和 v[1]进行加密得到 v[0],然后通过 v[0]和 v[2]加密得到 v[1]就会发现规律了:其实就是 3 个数为一组,通过左右两个数加密得到中间的数这里只会运算到 v[n-2]
            }  
            y = v[0];  
            v[n-1] += (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(i&3)^e] ^ z)));  
            z = v[n-1];//最后一个数 v[n-1]的加密,拿到 v[0]和 v[n-2]进行加密得到, 算法一样
        }  //第一轮结束,每个数都加密了一遍
        while (--rounds);	//执行 rounds 轮,加密完全
    }  
    else if (n < -1)   //当负数时就是解密
    {  
        n = -n;  //首先把负数转成正数
        rounds = 6 + 52/n;  //确定轮转数
        sum = rounds*DELTA;  //根据轮转数计算 sum
        y = v[0];  
        do  
        {  
            e = (sum >> 2) & 3;  
            for (i=n-1; i>0; i--) //逆序倒推
            {  
                z = v[i-1];  //先解密 v[n-1],需要知道 v[0]和 v[n-2],
                v[i] -= (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(i&3)^e] ^ z)));  
                y = v[i];//只会解密到 v[1]
            }  
            z = v[n-1]; //对于第一个 v[0]的解密,要知道 v[n-1]和 v[1] 
            v[0] -= (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(i&3)^e] ^ z)));  
            y = v[0]; 
            sum -= DELTA;//sum 的减减
        }  
        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;  
}

特征值 rounds = 6 + 52/n e = (sum >> 2) & 3