XXTEA加密流程分析

    代码与图解来自:https://www.jianshu.com/p/4272e0805da3

    对于我这种相关知识欠缺的人来说,光是如此有些难以理解,因此基于该作者的图片与代码试着分析了一下实际的加密过程(也因为网上没能找到具体的文字描述过程,甚至图解的字符解释也没有,所以只能自己对着代码分析了)。

 

图解:

 

C代码:

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

    如果您要对照本文章实际调试,试着小窗吧。如下文字解释不会再引用图片。

 

代码符号:

    DELTA:算是该加密算法的一个特征值,为黄金分割数(5√-2)/2与232的乘积。实际上,该值不影响算法,但能很好的避免一些错误。该数值在其他算法中也常有运用。

    MX:对照图例。暂时不知道其为什么的缩写。在本例中请对照加密图解,算是算法的一部分。

    n:对应明文或密文的数组长度。(+n用于加密,-n用于解密。单纯是在代码实现时为了方便而如此设计罢了)

    v:明文或密文数组。对应图解中的X

    key:密钥数组。对应图解中的K

    rounds:加密循环的轮数。

    sum:对应图解中的D。

    e:对应图解中的(D>>2)

    p:本例中用作明文或密文数组的索引。

    r:参照代码,类比p&3(该符号在图中而不在代码中)。3的二进制编码为11,任何数与其与运算后,可能产生(00,01,10,11),对应(0,1,2,3)(但这种理解仍有问题,怀疑图解中的r所在位置不同时具有不同的意义)

 

图解符号:

    方框:相加盒。将指向该盒的变量进行相加。

    圆圈:异或盒。将指向该盒的变量进行异或。

 

个人建议:

    观看图解的时候,推荐自下而上,那样比较符合代码编写的流程。

    其中涉及的数学原理是异或,因此具有可逆性。但对于一些变量的来历仍然不解(例如:Xω的含义尚且不明。r猜测对应了加密轮数)

 

注释:

    可以将图示当作一轮的加密过程。Xr所在的循环中的相加盒实际作用为将MZ与Xr相加后的结果赋予Xr

    代码中的y、z分别表示图例中的Xr-1与Xr+1,但需要注意的是,实际代码实现中,存在如下代码:

y = v[p+1];  
z = v[p] += MX;

    也就是说,z既对应了图中的Xr,也对应了Xr+1;而y表示Xr-1,实际上是z的后一个元素

    (换一种说法就是,将y指向明文的下一位,z指向本次需要加密的明文元素。将z经过各种复杂的变化后,再将结果与原本的数据相加得到密文,将指针后移,重复同样的操作。)

    仅对比图例有着相对别扭的说法,但这已经是笔者能在网上找到的可读性相对较好的一版代码了。

 

---------------------------------------------------

    顺便也将TEA与XTEA的图解与代码留在这里,以方便查阅和帮助XXTEA加密的流程理解。

 

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;  
}  
   
// v为要加密的数据
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位

 

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

 

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值