|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" - l6 ]1 y7 z/ ~( C
2 #include <cstring> //for memcpy,memset 9 C1 }6 F3 E/ z1 E- Z
3 5 U2 e3 ]: Q6 B& M8 b
4 using namespace std; p' m! C& |7 ]; i0 ]4 x [) _. ]
5
. X+ x" |! G* U I2 g/ N/ d# w 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) : v. u q- m' n2 A0 K
7 :_round(round) 3 U5 D0 z7 y1 l5 l( V
8 ,_isNetByte(isNetByte) {
" b; r9 U1 W; ^, Q2 {% f 9 if (key != 0)
. }/ F9 [' F8 t4 [/ \1 o( Y: p9 N10 memcpy(_key, key, 16);
2 q4 }: }- U+ S- p; q4 e3 m11 else
- D) J- z) [) n- P5 c12 memset(_key, 0, 16);
~ Z* X9 a! m) c/ e" }4 }13 }
4 d- Y' }5 l/ [- U! ]14
5 B2 x: b) V$ F, w" v# A15 TEA::TEA(const TEA &rhs)
5 B5 |6 M" N) n$ H5 B6 l, ?! q3 _16 :_round(rhs._round)
. [+ _8 o3 D& a17 ,_isNetByte(rhs._isNetByte) {
) k# G* i& r4 S) D8 Q18 memcpy(_key, rhs._key, 16);
{5 U3 f. m0 l' D6 [ P19 }
9 z5 t9 v7 Q! J9 d$ d20 # V7 r; o9 I3 B4 `" E
21 TEA& TEA::operator=(const TEA &rhs) { 9 l5 s4 M$ h+ i% f% L% N
22 if (&rhs != this) { 8 c' ?* g$ t( u
23 _round = rhs._round;
) C! e5 o5 Q# b24 _isNetByte = rhs._isNetByte; 7 Z ?& n7 w$ M1 D* t- r1 r
25 memcpy(_key, rhs._key, 16); 9 a$ c8 |& a1 s/ V( u8 I6 x7 \
26 }
$ a) ~0 q* Y+ f( W27 return *this; / { T. o0 R" Q/ h* V) C
28 } 2 S C9 W# W' C+ ]( N! F3 R. c; `
29 4 y) `' b# ?2 [+ m/ S* l/ O, j1 {
30 void TEA::encrypt(const byte *in, byte *out) { / a- ^ P( ~8 f9 F
31 encrypt((const ulong*)in, (ulong*)out); 6 V0 F! `; ?8 G+ q$ }! L! d# X+ p
32 } ' @. t' t. Y7 \( i( y
33 * U2 w& U# s; E& [: v# K
34 void TEA::decrypt(const byte *in, byte *out) {
# Y6 Y) V- E1 [) H: K6 j35 decrypt((const ulong*)in, (ulong*)out); 3 ?# u) {$ m: o% Z/ |# [
36 } : [2 h4 @% ?/ Y, k8 }; t
37
3 n& E! Z3 V# U8 B# ~38 void TEA::encrypt(const ulong *in, ulong *out) { ! n5 `: B, {! N
39
1 {2 i4 C# n7 ]( ^. B40 ulong *k = (ulong*)_key; $ q. M6 h( S, u6 X! D0 o7 J
41 register ulong y = ntoh(in[0]); . `. U6 v$ E! x, h2 G- `
42 register ulong z = ntoh(in[1]); - n \, k$ x: }& |* j
43 register ulong a = ntoh(k[0]); 6 m8 j4 N$ \4 P1 H% h5 a3 T
44 register ulong b = ntoh(k[1]);
' _# Z8 W3 ~9 p* C45 register ulong c = ntoh(k[2]);
- {" Y9 A* i* {' f46 register ulong d = ntoh(k[3]); ! j9 w. x e0 q( s% y- N5 v5 v
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
) ?, e) t' \2 h' E6 M) {; t1 I48 register int round = _round; / T8 |( o5 W; Q: e
49 register ulong sum = 0;
1 z7 J+ N, }5 r, p9 A1 p2 J/ t50 ; Q+ u" k T+ t( _# y: u3 a1 [
51 while (round--) { /* basic cycle start */
6 O( z l* Q: K52 sum += delta;
- S% [5 o) z- F4 k53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 9 [! I7 }/ X" W/ C' m) T
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
6 m/ ~' c4 B& O" Y# |9 G& L" K% G55 } /* end cycle */
% d+ S; K# B' f% }. S3 R& B, j56 out[0] = ntoh(y); 4 K+ r" @1 v' U3 [0 C) `
57 out[1] = ntoh(z); 7 ^* H6 I: {8 s" @ f$ N0 j
58 } X \+ T6 W4 P# A
59
1 m/ M+ U( {+ P$ j! n. q60 void TEA::decrypt(const ulong *in, ulong *out) {
6 C8 R* R* b' P5 ^" m61
8 i& u, A8 O. |- B1 x3 H62 ulong *k = (ulong*)_key;
+ U6 u! J) n4 @) F2 R4 S2 ]63 register ulong y = ntoh(in[0]);
+ y6 J2 }0 I4 W* y) ?( Z, l2 C) q64 register ulong z = ntoh(in[1]); 3 K6 t& T1 G! |4 Y: A" v2 \
65 register ulong a = ntoh(k[0]); % ~: n5 @5 \& e$ r0 ` `# \# ~/ r% }. H
66 register ulong b = ntoh(k[1]);
9 W' Y5 a4 }" i67 register ulong c = ntoh(k[2]); 1 u0 X& L2 b3 _6 N' A' T
68 register ulong d = ntoh(k[3]);
" C- q0 v4 }& s/ K" C. G M* I69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 6 @9 m9 g" }/ s
70 register int round = _round;
' [ c: w4 j3 m0 l71 register ulong sum = 0; : h# g% E$ ~7 y; w: @- T) |
72
8 U- b q) {3 D% A. F& I) Q: i/ q7 t73 if (round == 32)
* c6 G" f; ~* v; w z74 sum = 0xC6EF3720; /* delta << 5*/
~6 i: ^; z; K% A75 else if (round == 16) ! q, W5 E8 x, \0 D4 F: j2 ^3 R
76 sum = 0xE3779B90; /* delta << 4*/ # E8 V& C3 D& Y
77 else 8 ]/ F/ N. B& }/ H
78 sum = delta << static_cast<int>(logbase(2, round));
$ R" f/ Y9 m0 x6 S79 % h: H- {" X/ ?8 ~
80 while (round--) { /* basic cycle start */ 7 p4 B# l! W4 t: ]' M. L6 J* O
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
: B* P- g0 }( D2 Y3 Z4 O82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); # F' W' o& o; I. [- } K
83 sum -= delta; # r4 |8 a6 V* {5 y/ R- h. w
84 } /* end cycle */
. U5 z/ `. `4 X* F# O5 r' H" g85 out[0] = ntoh(y); $ X3 }. y6 j% F6 g# R& F T
86 out[1] = ntoh(z); / v: D5 |) d+ ]
87 }4 f7 w( t( o4 }& T
, @& |* g" i8 v
需要说明的是TEA的构造函数: " N8 E6 l5 B' V# L4 X( n$ n9 u
TEA(const byte *key, int round = 32, bool isNetByte = false);
* P' u% \) h' N0 W/ y1.key - 加密或解密用的128-bit(16byte)密钥。 5 g$ @2 U3 `8 c+ I4 p
2.round - 加密或解密的轮数,常用的有64,32,16。 + V) ?8 `+ ^5 q# e
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! * X% z) r- f# T! j, j* F
( w' X) ?1 ~+ W最后当然少不了测试代码: |
|