|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" , p8 s- z5 [( L# n5 a& B4 {% b
2 #include <cstring> //for memcpy,memset ; `; @; l+ F ~% c3 L% j
3
/ O' ~! ?/ A! a0 ~+ [ 4 using namespace std; # V8 c& q6 ^3 X
5 8 d/ I$ j# \5 j& M4 Z6 B
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) # l8 S4 W! S) r% v6 ~1 f
7 :_round(round) " q1 x. j9 L/ ]4 {* J- G) y
8 ,_isNetByte(isNetByte) {
b8 y5 \! b8 K7 ~; k+ U* @ 9 if (key != 0)
( @+ o% r% l6 ^; B! P7 m5 K. Z10 memcpy(_key, key, 16);
6 Z; r6 n- Q, v& d. ^: g, |* e11 else / s( N8 ~$ S; u3 I$ |$ D4 p
12 memset(_key, 0, 16); 3 M5 q- K' [ S, w" W* x
13 }
5 p+ }# D/ S# O14
9 Y( K3 X# F9 N& j9 X1 R- c15 TEA::TEA(const TEA &rhs)
* H4 m8 S$ ^8 ?' V' @0 @$ f" e. @16 :_round(rhs._round) 0 I" g }1 `* q& q$ [
17 ,_isNetByte(rhs._isNetByte) {
- K* _4 m) p" M8 R6 ~) r& ^! a18 memcpy(_key, rhs._key, 16);
: t7 \. H& A9 K; u! C1 i19 } 1 {/ W$ F% Z1 U
20 4 g& r6 O6 _ l3 M3 x/ N# i" x; H
21 TEA& TEA::operator=(const TEA &rhs) {
! F* e# w' R5 I5 e22 if (&rhs != this) { U2 F0 P4 R, C, A5 z
23 _round = rhs._round;
& \9 K' k4 F, u# \3 o- ]3 n24 _isNetByte = rhs._isNetByte; 8 z% s% N5 B, o* u4 d
25 memcpy(_key, rhs._key, 16); ) p P R; C4 L% o/ A8 ^- L7 `0 p
26 }
5 t0 g6 o/ y! Y( ~. _27 return *this; & ^( a2 P1 l% C& E, K& M
28 } . K0 W; G$ E# l
29
% W5 a8 ?7 h! U% W5 g30 void TEA::encrypt(const byte *in, byte *out) {
n: _+ U0 }/ y$ K/ ^31 encrypt((const ulong*)in, (ulong*)out);
+ K4 @3 M. f4 g( @1 ]% N* I32 }
+ K4 `4 n3 y8 g# p6 i! ]33
% t7 p( G$ E. j34 void TEA::decrypt(const byte *in, byte *out) {
9 U( Q. P, l l1 ]35 decrypt((const ulong*)in, (ulong*)out); 9 G" F* g6 g( S# X* Z! l7 p
36 }
2 S# X6 M N8 _1 ?, x37 & J6 K. z0 Q/ {0 j; b3 }' n
38 void TEA::encrypt(const ulong *in, ulong *out) { : k s0 E: L8 _8 ]- z
39 ! p5 K2 T) M. O3 t0 Y F( t8 L
40 ulong *k = (ulong*)_key;
- N- E0 p4 Q" c- }: Y41 register ulong y = ntoh(in[0]); ; Q4 H5 i6 ]5 S( {4 |) F$ z
42 register ulong z = ntoh(in[1]);
0 V1 ]0 ]# a& f43 register ulong a = ntoh(k[0]); ' E5 f0 K1 a: P
44 register ulong b = ntoh(k[1]); 7 w; u6 i8 ?* e1 K$ ?
45 register ulong c = ntoh(k[2]); 7 X1 s( z- x2 i/ i% `
46 register ulong d = ntoh(k[3]);
) w2 ?6 O& d* _8 p47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
% d: t& a" J4 Y48 register int round = _round; 6 B- t6 Q9 t) s
49 register ulong sum = 0; ) ]8 \* G+ ?5 e% Q7 s
50
1 _9 e8 E8 M$ l H, C51 while (round--) { /* basic cycle start */ 5 z0 E! I# q$ G; X
52 sum += delta;
3 X# E& I0 d2 t+ I. f7 y53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 2 T& [; C( r6 x# J* @; X
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
( P7 D4 u- l- v8 y( |! K+ R- s55 } /* end cycle */
g& K/ ?& U- g# u5 e56 out[0] = ntoh(y); * I2 B% T" ^: i4 H0 V
57 out[1] = ntoh(z); ; P# X: h* a/ ]- v5 w2 I3 r
58 }
. Z5 {- y4 ^; D) Z Y59 ( U. Y) y" w/ a" O- E1 x
60 void TEA::decrypt(const ulong *in, ulong *out) {
5 u6 d$ }! O) A8 U61 . U7 D- ^- q4 X4 c- r
62 ulong *k = (ulong*)_key; 3 }- q2 ?; R( S8 {3 ^- x/ w- r
63 register ulong y = ntoh(in[0]); 4 M3 y; }7 D3 F+ b2 C
64 register ulong z = ntoh(in[1]);
7 s6 B, D0 P! D& H1 W* d3 }$ `2 u65 register ulong a = ntoh(k[0]); # E9 L+ [; l9 `, C+ d3 @4 f6 Q5 U
66 register ulong b = ntoh(k[1]);
' |" _0 ~8 }" x; }6 q67 register ulong c = ntoh(k[2]);
( y9 G( a- E) u' l5 \& `5 w68 register ulong d = ntoh(k[3]);
B! U, `) U# z, b% h69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
- K, T+ \. k, S2 I: y; G70 register int round = _round;
+ @; @9 q2 V' B* H" o8 u" ^71 register ulong sum = 0; 9 Q4 R( W2 A8 _
72 ! ~( g& L8 k2 U
73 if (round == 32) 0 _% r0 q& o: [5 Y; @
74 sum = 0xC6EF3720; /* delta << 5*/
, v9 V1 q. s; @; ?: I3 T q8 N75 else if (round == 16) - Q) D) V* D6 T6 k* V4 Y
76 sum = 0xE3779B90; /* delta << 4*/
) i" O6 W. k! B' o77 else
$ F% F$ ], w) L4 Z78 sum = delta << static_cast<int>(logbase(2, round)); 0 \* T' {7 ~0 r, N! l
79
, C' c4 y2 m$ X80 while (round--) { /* basic cycle start */
8 p9 C t1 ~6 c/ j/ N7 J9 ]+ e81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); : S$ t) M/ p( G+ W
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ) W( z, u! V2 x: ]
83 sum -= delta;
; h; o: z; o4 L* b84 } /* end cycle */
0 R' f& O4 {; ?9 `: ^3 k85 out[0] = ntoh(y);
" u. d- N2 ^) H0 y86 out[1] = ntoh(z); , c, B$ q& E9 a5 K5 N- k
87 }
3 f5 N7 V$ X; n, u5 z1 u" z& Z1 O2 c& e# U `7 @
需要说明的是TEA的构造函数:
3 q4 \2 o! R# T5 vTEA(const byte *key, int round = 32, bool isNetByte = false); & k, M2 N) B' u+ q
1.key - 加密或解密用的128-bit(16byte)密钥。
0 H; X7 @- A% ~( [6 t2.round - 加密或解密的轮数,常用的有64,32,16。
5 H# G: f) `. l: J+ O' |$ ?' t3 U3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
. A5 Y$ z7 e1 O# G% _9 x
1 Q- [& B$ r+ G( z最后当然少不了测试代码: |
|