LOADING

加载过慢请开启缓存 浏览器默认开启

题目复现和一些加密算法

2024/10/26

2024螺丝新生赛

Tea加密算法

又是Tea加密算法,在这里总结一下。

Tea
#include <iostream>

//加密函数
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],i; 
    uint32_t delta = 0x9e3779b9;   
    uint32_t sum = delta*32;
    uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
    for(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;
}

这种比较简单,无脑反着来就行。

XTea

稍微复杂一点,加密如下

void encrypt_xtea(uint32_t num_rounds, uint32_t v[2], uint32_t const key[4]) { uint32_t 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 decrypt_xtea(uint32_t num_rounds, uint32_t v[2], uint32_t const key[4]) { uint32_t 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;
}

解密如下:

void decrypt_xtea(uint32_t num_rounds, uint32_t v[2], uint32_t const key[4]) {
    uint32_t 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;
}

相比Tea就是sum在中间加了一下,还是反着来就行

XXTea

热身赛就是这个,附上热身赛RE代码:

void encrypt(uint32_t *v, int n, uint32_t const key[4])
{
    uint32_t y, z, sum;
    unsigned p, rounds, e;
    //加密
    rounds = 11451419;
    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);   
}

这个加密方式v[p]是由v[p-1](上一轮z)和v[p+1](本轮y)决定的。也就是左边是z,右边是y。复原可以先复原

解密代码如下:

void decrypt(uint32_t *v, int n, uint32_t const key[4]){
    uint32_t y, z, sum;
    unsigned p, rounds, e;
    rounds = 11451419;
    sum = DELTA *11451419;
    do{
        e = (sum >> 2) & 3;
        y = v[0];
        for(p=n-1;p>0;p--){
            z = v[p-1];
            y=v[p]-=MX;
        }
        z = v[n-1];
        v[0]-=MX;
        sum -=DELTA;
    }while(--rounds);
 }

想明白过程逆推过去很关键。