xxtea算法
<p>[TOC]</p>
<h1>🌓过程分析</h1>
<p>xxtea在xtea的基础上加上了多次循环和其他异或相加运算</p>
<p>大概流程为</p>
<p><img src="https://pic.imgdb.cn/item/63777ad516f2c2beb1101cc7.png" alt="" /> </p>
<p>第一次加密由第n个块和第2个块进行运算后赋值给第1个块,第二次加密由第1个块和第3个块进行运算赋值给第2个块,第三次加密由第4个块和第2个块运算赋值给第3个块,以此类推,到最后一次加密由第n-1个块和第1个块运算赋值给第n个块(其实就是块的前置和块的后置运算赋值当前块),然后再进行rounds次这种运算</p>
<p>具体的块之间的运算为</p>
<pre><code>((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (key[(p&3)^e] ^ z))</code></pre>
<p>z是前置块,y是后置块</p>
<p>整体的伪代码实现为</p>
<pre><code class="language-cpp">void Encrypt(long* v, int n, long *key) {
unsigned long y, z, sum;
unsigned long delta = 0x9e3779b9;
unsigned p, rounds, e;
rounds = 6 + 52/n;
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] += ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (key[(p&3)^e] ^ z)); // 前置块和后置块运算和加上到第p个块上,并把它赋值给z当做下一个块的前置块
}
y = v[0]; // 处理最后一个块
z = v[n-1] += ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (key[(p&3)^e] ^ z));
} while(--rounds); // 进行rounds次加密
}
</code></pre>
<p>如果要解密需要先解密第n个块,再解密第n-1个块,最后再解密第1个块,前置块和后置块的运算没有变化,用块减去计算出来的结果就是原本的值 </p>
<pre><code class="language-cpp">void Decrypt(long *v, int n, long *key) {
unsigned long y, z, sum;
unsigned long delta = 0x9e3779b9;
unsigned p, rounds, e;
rounds = 6 + 52/n;
sum = rounds*delta;
y = z[0]; // 最后一个块的后置块
do {
for(p = n-1; p > 0; p--) { // 处理除第1个块以外的块
z = v[p-1]; // 前置块
y = v[p] -= ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (key[(p&3)^e] ^ z));
}
z = v[n-1]; // 处理第1个块
y = v[0] -= ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (key[(p&3)^e] ^ z));
} while(--rounds);
}</code></pre>
<h1>🌓参考文章</h1>
<p><a href="https://www.anquanke.com/post/id/224198"><a href="https://www.anquanke.com/post/id/224198">https://www.anquanke.com/post/id/224198</a></a></p>