|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 6 w7 t( O0 j9 F( d: A0 q: x2 z- ~
2 #include <cstring> //for memcpy,memset
8 W1 B: T8 S) f 3 8 V8 [4 w( @& g4 P1 m' Y
4 using namespace std;
) h1 X1 g6 e, t/ v' m2 k T- p; y 5
8 Q! O* k) Q% G' c 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) $ ?! C) }* `& W' p6 M4 S6 j
7 :_round(round)
" k8 j; c7 X" {# k9 W! ]; L) Y/ j 8 ,_isNetByte(isNetByte) { ( V% @+ B5 X8 d3 b! Z
9 if (key != 0) 7 T. q4 y0 F ?) v
10 memcpy(_key, key, 16);
8 w1 P3 t( p0 X11 else , q+ Z$ C0 V' J4 X! |
12 memset(_key, 0, 16);
0 n$ y/ h; P/ @13 } # U9 h8 A& k/ s* h9 F& ]4 h2 A
14
* `2 ?) z# V2 L# R# E* K15 TEA::TEA(const TEA &rhs)
" ?. m8 z: W8 p6 n4 _+ i( v16 :_round(rhs._round) 4 k2 D. O: W7 K9 C" P6 ]9 @
17 ,_isNetByte(rhs._isNetByte) {
% i% ]3 F' J* R9 P18 memcpy(_key, rhs._key, 16); 0 D/ [5 I. N/ D6 |
19 }
0 B( w N0 u. G* H* C, x+ I4 b* x20 : a( D, X9 {' C7 D0 n7 |
21 TEA& TEA::operator=(const TEA &rhs) {
9 i; s2 C/ C1 g22 if (&rhs != this) {
, ?) v% o$ O9 Y U( b23 _round = rhs._round; 7 \7 k4 t) a$ l5 n2 N! }/ r- v
24 _isNetByte = rhs._isNetByte; # P& G) F% c9 ]9 _8 r8 l
25 memcpy(_key, rhs._key, 16);
4 c6 v, e$ A. T# ^' O& T26 }
. K: e8 M) K8 Z- @27 return *this; ) O, l6 w) b# E b- B* Y4 }
28 }
, ?: D$ W6 h1 R) u `8 s$ d8 c29
% K6 p7 W! c/ R7 e/ F30 void TEA::encrypt(const byte *in, byte *out) {
) I) H8 p* [1 \9 N. V0 X/ x# G' N31 encrypt((const ulong*)in, (ulong*)out);
9 A3 J1 F# c7 H. s32 } " |* O) T: b2 V3 P7 X# ?; c
33 6 ?; R# c2 v2 A
34 void TEA::decrypt(const byte *in, byte *out) { 2 g! W0 J. {. Q% b5 N3 }4 }
35 decrypt((const ulong*)in, (ulong*)out); & H% _6 ^/ e2 P; o+ \1 s7 q* C% P
36 }
6 ^' S( m3 V: z' B' Y5 |37 5 b4 y% O3 D& m- Y5 {& { ~
38 void TEA::encrypt(const ulong *in, ulong *out) { % C" P- h. |5 W: b1 ^
39 5 n% r+ t7 L6 J, y
40 ulong *k = (ulong*)_key;
" o: g( c8 ?( D* Z" k% I5 X# j. X# K41 register ulong y = ntoh(in[0]);
0 N8 h. z9 b w5 b( M42 register ulong z = ntoh(in[1]);
. M* {$ I9 p) B6 w f8 v43 register ulong a = ntoh(k[0]); . Q4 U9 p$ L8 M
44 register ulong b = ntoh(k[1]); $ ^5 V }* X+ k& ~
45 register ulong c = ntoh(k[2]);
% i* e* e. f0 `! Q% N5 ~$ Q8 O) ]; z46 register ulong d = ntoh(k[3]);
! W7 N" n$ }6 I, @# w3 T47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
. `$ D. t7 M# N+ }1 Y9 s; h48 register int round = _round;
; u: d: Y6 f/ C) E( D0 y G49 register ulong sum = 0;
; s4 R& I7 @+ q! k- t50
) S. I! w! G/ P$ a51 while (round--) { /* basic cycle start */
, G6 h! H$ i. m) x# c: s52 sum += delta; ' y7 M/ T' r. ^7 B7 M% T1 ]
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
3 m/ y3 [, C& G: Q/ S' s" p54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ! X* t H- K. ^; ?8 l
55 } /* end cycle */ ! j( ^% W* t) [5 F$ g" p4 c
56 out[0] = ntoh(y); . }. Y) N, j; Y$ c7 q/ N
57 out[1] = ntoh(z); ' _' K( l8 E7 k" M- T/ ]' l- w
58 } 4 m1 ^: d0 B/ S6 J
59
9 V! N+ ~" M" o+ r% X y& H60 void TEA::decrypt(const ulong *in, ulong *out) {
% G/ U) ^) J$ a! @/ {% V61 ) \+ R3 H' Q$ U; l% c* \ Q. U
62 ulong *k = (ulong*)_key; - |$ \; d+ a& V, d- X
63 register ulong y = ntoh(in[0]);
1 T7 d" C3 r9 U: [" [1 A64 register ulong z = ntoh(in[1]); 8 T, \5 f( j. _
65 register ulong a = ntoh(k[0]);
* p3 y8 G, ^4 I66 register ulong b = ntoh(k[1]); 2 Z @- ]: h- i! T* Z+ U
67 register ulong c = ntoh(k[2]); 4 |& T% f) Q( V
68 register ulong d = ntoh(k[3]);
" F2 P1 o i9 f4 ~# s4 r1 z7 B( n69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ - Q6 m E- z4 T8 u5 e" T
70 register int round = _round; , T8 C5 s6 D8 ~5 E5 W
71 register ulong sum = 0;
# {& ?% f$ ^* y m: B, Y. j9 C: E72
: a& Y2 N6 \& c/ [: J# \! X0 k73 if (round == 32) ) k7 ]! x7 _+ K% f
74 sum = 0xC6EF3720; /* delta << 5*/
; [, @. Z7 p9 b) J$ S75 else if (round == 16) + }) z' I5 x; T3 D2 j- N
76 sum = 0xE3779B90; /* delta << 4*/ 8 ~" |# w$ x, k) m
77 else
2 t+ k' {5 r" l; N( L! D78 sum = delta << static_cast<int>(logbase(2, round)); ' U. w* p; Z1 l- w$ i. a
79
5 n0 I( {2 K5 s8 S# I3 s" A" w80 while (round--) { /* basic cycle start */
# g! s9 h5 V7 I, q- {81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
1 n4 b( s4 `! ?3 G, l" Y2 F. R82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); " H4 ?2 ^! ?. N& f2 Q. V8 N
83 sum -= delta; 7 F' r; Q9 w) h# N
84 } /* end cycle */ , B5 W8 T3 A, l0 m
85 out[0] = ntoh(y);
6 C' y) n9 x+ |86 out[1] = ntoh(z);
/ E0 q, n7 Y/ v87 }
* M5 D1 n9 V& L( l3 a$ k9 C0 h5 D1 d1 K* i. f8 i, g
需要说明的是TEA的构造函数:
, ]" T- D2 D* \% u( X) p* h4 aTEA(const byte *key, int round = 32, bool isNetByte = false);
( O/ x0 N# b) h1.key - 加密或解密用的128-bit(16byte)密钥。
) X" n1 K8 `0 v5 G2.round - 加密或解密的轮数,常用的有64,32,16。 , D7 L6 c; c. s: O# f, a. T2 H
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
' D- S: M) U- v3 T' R2 F7 G0 K. @
p! w i7 m4 W' Z最后当然少不了测试代码: |
|