1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
| #include <cstdio> #include <stdint.h> #include <cstdlib> #include <cstring> #define DELTA 0x9e3779b9
static inline uint32_t MX_calc(uint32_t z, uint32_t y, uint32_t sum, const uint32_t key[4], unsigned p, unsigned e) { return (((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (key[(p & 3) ^ e] ^ z)); }
void xxtea_decrypt(const uint32_t *in, int n, int rounds, const uint32_t key[4], uint32_t *out) { uint32_t y, z, sum; unsigned cycle;
sum = rounds * DELTA; memcpy(out, in, sizeof(uint32_t) * n); y = out[0];
while (rounds--) { cycle = (sum >> 2) & 3;
for (int idx = n - 1; idx > 0; idx--) { z = out[idx - 1]; out[idx] -= MX_calc(z, y, sum, key, idx, cycle); y = out[idx]; } z = out[n - 1]; out[0] -= MX_calc(z, y, sum, key, 0, cycle); y = out[0]; sum -= DELTA; } }
uint32_t* __fastcall str2long(const unsigned __int8 *bytes, unsigned __int64 bytes_len, unsigned __int64 *int32_len, int preserve_bytes_len) { size_t Count; unsigned __int64 v7; unsigned __int64 i;
v7 = (bytes_len >> 2) + ((bytes_len & 3) != 0); Count = (preserve_bytes_len != 0) + v7; uint32_t* res = static_cast<uint32_t*>(malloc(Count * sizeof(uint32_t))); if ( !res ) return 0; memset(res, 0, Count * sizeof(uint32_t)); for ( i = 0; i < bytes_len; ++i ) res[i >> 2] |= (uint32_t)bytes[i] << (8 * (i & 3)); if ( preserve_bytes_len ) res[v7] = bytes_len; *int32_len = Count;
return res; }
uint8_t* __fastcall long2str(const unsigned int *Block, __int64 int32_len, unsigned __int64* bytes_len, int flag) { uint8_t *result; unsigned int v6; unsigned __int64 Size; unsigned __int64 i; unsigned __int64 v9;
Size = 4 * int32_len; v9 = 4 * int32_len; uint8_t* bytes = static_cast<uint8_t*>(malloc(Size * sizeof(uint8_t))); if ( bytes ) { *bytes_len = 24; printf("int32_len=%llu, bytes_len=%llu\n", int32_len, *bytes_len); for ( i = 0; i < Size; ++i ) bytes[i] = Block[i >> 2] >> (8 * (i & 3u)); result = bytes; } else { *bytes_len = 0; result = 0; } return result; }
void printX(uint32_t *data, int n){ for(int i=0;i<n;i++){ printf("0x%08X ",data[i]); } printf("\n"); } void print(uint32_t *data, int n){ for(int i=0;i<n;i++){ printf("%d ",data[i]); } printf("\n"); }
int main() { uint32_t plaintext[24]; uint32_t key[4]= {0x67616c66, 0, 0, 0};
static const unsigned int perm[24] = { 2, 0, 3, 1, 6, 4, 7, 5, 0xA, 8, 0xB, 9, 0xE, 0xC, 0xF, 0xD, 0x12, 0x10, 0x13, 0x11, 0x16, 0x14, 0x17, 0x15}; unsigned int inv_perm[24]; for ( int i = 0; i < 24; i++ ) { inv_perm[perm[i]] = i; }
uint8_t target[24] = { 0xEE, 0x56, 0x9D, 0x6B, 0x02, 0x63, 0x78, 0x75, 0x05, 0x42, 0x70, 0x9C, 0x63, 0xD7, 0xDC, 0xD7, 0x1A, 0xB5, 0xEA, 0x0D, 0xC6, 0x8D, 0x97, 0x5D }; uint8_t v5[24]; int n = 24; v5[0] = target[0]; for (int i = 1; i < n; i++){ uint8_t tmp = 0; for (int j = 0; j < i /3; j++){ tmp ^= target[j]; } v5[i] = target[i] ^ tmp; } unsigned char Block[24]; printf("Block数据:"); for (int i = 0; i < n; i++) { Block[i] = v5[inv_perm[i]]; printf("%02X ", Block[i]); }
long long unsigned target_len; uint32_t* ciphertext = str2long((const uint8_t*)Block, 24, &target_len, 0); printf("密文数据:"); printX(ciphertext, target_len);
xxtea_decrypt(ciphertext, target_len, 6 + 52/target_len, key, plaintext); printf("解密后的数据:"); printX(plaintext, target_len);
long long unsigned bytes_len = 0; uint8_t* bytes = long2str(plaintext, target_len, &bytes_len, 0); for (int i = 0; i < bytes_len; i++) printf("%c", bytes[i]);
return 0; }
|