|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
: T/ K* o) G) {/ u8 U s 2 #include <cstring> //for memcpy,memset 0 T `' d0 v$ g: F8 J; [; z
3 # o; E- U; n: b- p3 Y' b$ `( V. J% O
4 using namespace std; ( b6 {' O' e- f: X6 C9 t$ f
5 6 f8 C* J$ ~: x0 X7 w7 ^ U4 d4 r
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) ( l$ e& h' ]' N2 \& E9 [
7 :_round(round)
8 ^& F4 G9 a" x7 G7 v; P 8 ,_isNetByte(isNetByte) { 1 h% S: C6 X$ @
9 if (key != 0) }* p% } ~& R2 C& U& [# C
10 memcpy(_key, key, 16); - D+ k6 m( M" c5 f N! U1 E
11 else 7 ?" k$ u( C; X: ^ W2 V/ w
12 memset(_key, 0, 16); 5 H* g6 \$ ]2 p; y
13 } ( h0 o& O& ]' ?" A! D" n c
14
9 [# L, x. g7 {9 [6 H5 i, {15 TEA::TEA(const TEA &rhs)
+ P* }' q( h8 |* x, w16 :_round(rhs._round)
9 L1 _9 r4 ?" Y5 I" {17 ,_isNetByte(rhs._isNetByte) { 4 d6 U5 a1 }* E# _1 ^$ G% j8 W9 T
18 memcpy(_key, rhs._key, 16);
8 D) _" W7 ]2 I' t8 e' y19 } 7 w- `4 n+ x: p7 _( Q9 c+ z6 V
20
+ k2 R' |! I2 T p0 ^0 Y. ~21 TEA& TEA::operator=(const TEA &rhs) { 8 E* H- [7 ~$ `( ~- ~- f0 k. L
22 if (&rhs != this) { 9 b. G: l, F/ E8 b, v2 a+ k
23 _round = rhs._round;
4 s" r" x, o: `) z24 _isNetByte = rhs._isNetByte;
3 P/ W0 N8 L' Z+ |25 memcpy(_key, rhs._key, 16); 4 T$ l: Q- p: |" c, F
26 }
1 o/ e7 L4 d/ a6 m1 V27 return *this;
2 I) j( k" p6 F( z0 a. ]# v28 }
J3 V0 h% R; k; [! o29 ( F# C& K3 b2 a! Q
30 void TEA::encrypt(const byte *in, byte *out) { / ^8 x, C5 B* n) R h X& |
31 encrypt((const ulong*)in, (ulong*)out); % [! N' M& o( ^
32 }
2 N' O* f4 R0 p* M3 \/ A33
( L/ F/ @* w% X3 c4 ^6 o34 void TEA::decrypt(const byte *in, byte *out) {
0 W: P/ V, K. e: Z1 T/ E& _2 y7 V35 decrypt((const ulong*)in, (ulong*)out);
: Q; i3 `+ w" R* b8 n0 {36 } 1 V. C r5 q: L# e, j
37
- Z# p9 _1 ^# s38 void TEA::encrypt(const ulong *in, ulong *out) { - q2 Y) a! }( y0 e2 f# o. _
39 : e3 o2 Y4 K- K7 o1 m3 n% L
40 ulong *k = (ulong*)_key; $ \7 E1 T5 O" p5 E8 {
41 register ulong y = ntoh(in[0]); 0 x* J$ H Z% v- w. Z, v/ k" K
42 register ulong z = ntoh(in[1]);
_: \* \7 F' }43 register ulong a = ntoh(k[0]); 2 e; Y6 i; S5 S( w" N/ W
44 register ulong b = ntoh(k[1]);
1 H! p+ {1 C [+ l Z0 m& Y45 register ulong c = ntoh(k[2]);
: s1 S* N6 ^& Q46 register ulong d = ntoh(k[3]); 9 q, {+ J% [! X% c+ Y K
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
: c2 I- k/ ?: c& r9 O3 |5 ^* ?48 register int round = _round;
6 N& ~: U5 b7 Y, f2 f: ?9 @49 register ulong sum = 0;
# e( ^6 A8 i: ?7 U) l50 4 t( f, O( \+ d" W9 M3 D& r
51 while (round--) { /* basic cycle start */ # K* I" V& E' E0 h; a% k9 M7 `
52 sum += delta; $ k6 U' T" `( S" K
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); " [- U* b, J E) V/ V0 t
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
$ U. g1 i3 J8 n- e% L9 Q55 } /* end cycle */ / U1 v9 a, R+ z/ @
56 out[0] = ntoh(y);
0 ~% A9 u% N( Q* K57 out[1] = ntoh(z);
+ y4 f: v; }$ `) Z) a- V58 }
" I! B4 t3 Q; K2 k j Y59 ) ?( H# }- Q+ N8 P9 h
60 void TEA::decrypt(const ulong *in, ulong *out) { ; v/ b' ?# q" R6 f" v" |
61
7 z6 M2 {0 |8 @5 M# P62 ulong *k = (ulong*)_key;
C9 }. _% w8 F& U, P& y63 register ulong y = ntoh(in[0]); - [8 p! ~" T! M
64 register ulong z = ntoh(in[1]);
: Q+ c3 Q( r1 n) m J65 register ulong a = ntoh(k[0]);
! v+ r- C$ E8 K66 register ulong b = ntoh(k[1]); s( a$ D; m% Z: L# m$ {
67 register ulong c = ntoh(k[2]);
1 ? P! v, y& P* F) o, E) ]' F68 register ulong d = ntoh(k[3]); - C. F# x! t$ v8 v! u
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ( D, M: Z/ e7 t$ F
70 register int round = _round;
. L1 J' h8 I* h) ^3 t6 f71 register ulong sum = 0; ; x8 I" {1 g* B1 q/ a6 B% J# C
72
. ] K7 t& J5 k8 f73 if (round == 32) 2 |' V& k; c, V3 ]" h( A
74 sum = 0xC6EF3720; /* delta << 5*/ 3 A* A+ U7 F9 g5 d4 a$ O6 ]+ b0 G
75 else if (round == 16)
a" u7 \/ u- f/ }76 sum = 0xE3779B90; /* delta << 4*/
0 }, Q: c6 N* M2 p0 Z% ?: w7 o& E$ k! d77 else 0 T8 H, r5 n4 B3 \$ }0 t
78 sum = delta << static_cast<int>(logbase(2, round)); ; Q8 t! f1 \5 _- _
79 2 d) }1 h5 f) J A$ z
80 while (round--) { /* basic cycle start */ : _$ ]9 k X. L5 [: n% m
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
9 n0 }* c7 T; Q! M) T82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 1 n5 ?' L- N+ b$ l
83 sum -= delta; 4 O) S6 O w5 a* e
84 } /* end cycle */
$ A' ]" S1 \7 Z, N3 \5 R6 O85 out[0] = ntoh(y); 0 B. L* r0 ]% G% j+ e! ^
86 out[1] = ntoh(z);
5 H4 |0 b' u4 z8 U7 [- t87 }
; O3 K' z" |' D$ r6 K A5 Z \4 \0 Z, E
需要说明的是TEA的构造函数:
9 P, O% u5 S. y% x6 [6 GTEA(const byte *key, int round = 32, bool isNetByte = false); & m2 v& k4 X- B$ |% Y
1.key - 加密或解密用的128-bit(16byte)密钥。 5 }2 r- X; x5 x+ F# V
2.round - 加密或解密的轮数,常用的有64,32,16。
# d2 i. z* q0 U2 V6 {3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
5 g& V2 t# a2 X) O8 f0 S3 D; U3 R; y/ X, _0 y9 c
最后当然少不了测试代码: |
|