tea
介紹
"TEA" 的全稱為"Tiny Encryption Algorithm" 是1994年由英國劍橋大學的David j.wheeler發明的.
TEA算法也算是微型加密算法
在安全學領域,TEA(Tiny Encryption Algorithm)是一種分組加密(CBC)算法,它的實現非常簡單,通常只需要很精短的幾行代碼。
分組加密(CBC)加密
CBC模式的加密方式是通過一個初始向量(IV)先和明文分組第一組異或后使用秘鑰K加密,作為第一組密文,同時又與后一分組的明文異或后進行加密產生下一組密文,依次重復。
其解密和加密是對稱的,密文先解密,再異或。
其特點如下:
- 明文有一組中有錯,會使以后的密文組都受影響,但經解密后的恢復結果,除原有誤的一組外,其后各組明文都正確地恢復。
- 解密時,有一組秘鑰錯誤,該錯誤會影響下一分組相同位置的解密
- 若在傳送過程中,某組密文組出錯時,則該組恢復的明文和下一組恢復數據出錯。再后面的組將不會受中錯誤比特的影響
加密圖及實現
tea加密至少需要兩個數據,通常為64位8字節,同時需要一個delta值,delta每次迭代倍增,一般為0x9E3779B9,有一個128位密鑰,一般分為4個32位密鑰,每組加密一般進行32輪迭代。
C語言實現
void Encrypt(long* EntryData, long* Key) { //分別加密數組中的前四個字節與后4個字節,4個字節為一組每次加密兩組 unsigned long x = EntryData[0]; unsigned long y = EntryData[1]; unsigned long sum = 0;//迭代器 unsigned long delta = 0x9E3779B9;//delta值 //總共加密32輪 for (int i = 0; i < 32; i++) { sum += delta;//delata倍增 x += ((y << 4) + Key[0]) ^ (y + sum) ^ ((y >> 5) + Key[1]); y += ((x << 4) + Key[2]) ^ (x + sum) ^ ((x >> 5) + Key[3]); } //最后加密的結果重新寫入到數組中 EntryData[0] = x; EntryData[1] = y; }
xtea
最大的不同在於,xtea的sum第一次加密為0,subkey的取值方式為sum中的兩個二進制位,一般一個是最后兩個,一個是左移11位在取得的
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;//注意於tea的區別 v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]); } v[0]=v0; v[1]=v1; }
xxtea
相比xtea與tea,xxtea的復雜度更上了一層,subkey的方式變為已進行的輪數的最后兩位與delta疊加的最后兩位相異或,delta迭代與tea相同
#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 xxtea(uint32_t* v, int n, uint32_t* key) { uint32_t y, z, sum; unsigned p, rounds, e; if (n > 1) // encrypt { 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) // decrypt { 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); } } // test int main() { // 兩個32位無符號整數,即待加密的64bit明文數據 uint32_t v[2] = {0x12345678, 0x78563412}; // 四個32位無符號整數,即128bit的key uint32_t k[4]= {0x1, 0x2, 0x3, 0x4}; //n的絕對值表示v的長度,取正表示加密,取負表示解密 int n = 2; printf("Data is : %x %x\n", v[0], v[1]); xxtea(v, n, k); printf("Encrypted data is : %x %x\n", v[0], v[1]); xxtea(v, -n, k); printf("Decrypted data is : %x %x\n", v[0], v[1]); return 0; }