|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" : d2 C# h" T+ g4 \# V7 l
2 #include <cstring> //for memcpy,memset - W- a! [% V* S6 Q y! Z$ ^
3
9 t" j& F: D1 C+ D% h% ^ 4 using namespace std;
3 m! U3 ^8 G, e 5 5 M7 @+ o( t6 ^; p( d6 E
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
' ?1 E8 J- u. B4 l6 t 7 :_round(round) 7 ?2 ]1 _$ {" p+ v J6 o
8 ,_isNetByte(isNetByte) { , S& i3 v3 Y( |: H; i
9 if (key != 0)
& {& b8 ~ o7 p2 O2 S5 b: b5 K+ ]10 memcpy(_key, key, 16); 0 x1 a) t. @! d3 o& |/ k n+ T
11 else
% W C& {+ O/ K* X% ?( R6 `12 memset(_key, 0, 16); - [; k; V( Z$ E
13 } ! d9 C( L& g' x! }0 Q U
14
2 K9 B) }7 p, |. r15 TEA::TEA(const TEA &rhs)
' E+ \9 |7 @6 n0 Z# ^7 h/ p16 :_round(rhs._round)
4 \6 V9 q) ]% \, r G17 ,_isNetByte(rhs._isNetByte) {
0 S; \! E: r- | _2 n18 memcpy(_key, rhs._key, 16); ) G+ u9 G+ a9 O6 t7 ^+ m3 J
19 } & X# J: Q1 r+ `: a. Z) ]2 r, e
20
5 m* m; S% b$ o' w! v" J2 w21 TEA& TEA::operator=(const TEA &rhs) {
: f1 j! w% R2 `$ w. K/ a& ?( Q/ {22 if (&rhs != this) { ( b( H4 e7 {+ m2 C& t0 ?
23 _round = rhs._round; % q3 C) V+ p0 d5 | g
24 _isNetByte = rhs._isNetByte; 8 o* \' H; O7 {5 {9 E3 R, K
25 memcpy(_key, rhs._key, 16); + ]; C- b9 z$ `/ y0 F7 {. G$ y
26 }
2 G5 A8 Q% x) S, w. R5 l. q$ o27 return *this;
1 }5 ?* h3 J7 C F1 z+ M28 }
$ _6 y1 W5 D, H. r5 \0 M5 O29
# Z1 y$ k; F' c30 void TEA::encrypt(const byte *in, byte *out) { * y9 x& z( | o6 B
31 encrypt((const ulong*)in, (ulong*)out); 1 p; H, X$ G9 `& ^+ ^0 x
32 } # n1 N% o; F- Q6 u2 J" `
33
. Y# {) X& X) Q( J34 void TEA::decrypt(const byte *in, byte *out) {
' S0 T* O$ v/ r7 s* V35 decrypt((const ulong*)in, (ulong*)out); 3 e% M' ]7 b4 o- o1 ]
36 }
9 P" j- \, W8 l37
$ ~* B$ F/ T2 U$ ?$ T& P3 p2 H38 void TEA::encrypt(const ulong *in, ulong *out) {
& _: P( z1 k* a B7 D1 K2 v39 3 F; i* |9 Z" j
40 ulong *k = (ulong*)_key; $ P& a. T8 B3 h4 |- l. f+ c* \
41 register ulong y = ntoh(in[0]); / @& R* O8 _7 t( G/ {+ z
42 register ulong z = ntoh(in[1]);
0 r4 x' e9 h2 R3 ^+ Q43 register ulong a = ntoh(k[0]);
7 p+ B: b# I. J44 register ulong b = ntoh(k[1]); ' T/ X: q+ ^7 }- c
45 register ulong c = ntoh(k[2]); # g) e/ z- v$ ^4 `& ]# ]
46 register ulong d = ntoh(k[3]);
# r2 _: u& i$ S; G47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
" { }8 Q8 d( C$ @) D5 W48 register int round = _round;
- t d* f) s% q& ^ [1 D5 K49 register ulong sum = 0; / g, G: O, e' H
50
! \3 ^4 h/ W; L51 while (round--) { /* basic cycle start */ 2 b, Z& Z6 ^8 J: z9 V$ g- W' H
52 sum += delta;
) I Z: ]2 c$ O. { X7 j53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 6 H" S/ s5 ?% H0 f( @ O5 H
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
( V6 g" l9 ^. v; `# V% s7 P55 } /* end cycle */ ; p& \3 Z3 `& o
56 out[0] = ntoh(y);
: Z. j1 f8 [3 r" ?, X& [2 U57 out[1] = ntoh(z);
0 P4 e; ?( x0 Z- K9 Z! a% S( Q58 } ( C n) z w: Q4 e
59 , s" v7 |( [. O# h' a
60 void TEA::decrypt(const ulong *in, ulong *out) { ' x) ]$ I" t" x8 U3 u' w n
61
* L" \: a5 V. G' g3 A& D# J! h62 ulong *k = (ulong*)_key; . _- C& ` `& z4 a: n
63 register ulong y = ntoh(in[0]);
. t6 |! C6 o' Z' s5 U! p64 register ulong z = ntoh(in[1]); . X, L" c7 Z5 f( P
65 register ulong a = ntoh(k[0]); : j: `. e8 @/ P, U' |3 w
66 register ulong b = ntoh(k[1]); % y m, U" K" I$ g0 W
67 register ulong c = ntoh(k[2]); , B) a2 w0 K a+ N
68 register ulong d = ntoh(k[3]);
$ C2 i( S/ ~& U2 r. Z69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
% v- v' d1 T8 h3 y0 a70 register int round = _round;
1 q1 {! R7 e9 |* ?; S: ]71 register ulong sum = 0; $ o* c( m: H' r0 o
72
( a- P- p% ^8 p: }1 j3 n: Y73 if (round == 32)
/ a B2 S; e0 G7 a74 sum = 0xC6EF3720; /* delta << 5*/
4 A- k* t- X2 a4 R6 r* O* N( X75 else if (round == 16)
$ z' Q& t& d! `, W" F5 T76 sum = 0xE3779B90; /* delta << 4*/ / e7 }! ?* I' Y0 l3 V8 E D
77 else
7 K# ~ r$ ], _8 D3 g9 u3 ]78 sum = delta << static_cast<int>(logbase(2, round));
n V. F c2 b79 # O+ u. j, v! g7 p4 i2 U
80 while (round--) { /* basic cycle start */ : h- ~( p* g8 M0 K s
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
4 r4 `) H$ |# ?& `# N; G- S( F0 x82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 1 i# f! e( A- U+ _8 O( k7 K
83 sum -= delta;
8 @' T' D0 [/ s) d( Q! o; _84 } /* end cycle */ 4 ?+ K1 }" R' u! g$ a
85 out[0] = ntoh(y); # r E/ A. X( @8 ^& c& G7 [
86 out[1] = ntoh(z); ; b' X0 O3 S. B$ \7 H$ \
87 }3 p4 Q8 E/ f( Z" d8 [7 a# l
2 f! q. I1 W# G8 Y0 j2 j3 {/ d; W6 |需要说明的是TEA的构造函数:
8 h/ o4 C& W$ v) v1 @9 iTEA(const byte *key, int round = 32, bool isNetByte = false);
0 D6 t0 U' Q6 O1.key - 加密或解密用的128-bit(16byte)密钥。 6 O2 p' U1 O& T6 o; n' E" ~
2.round - 加密或解密的轮数,常用的有64,32,16。
7 G2 t) V7 h- ]2 ~, u3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
0 z( L8 H% _) A4 _! V6 Z0 L E3 R+ Q# f6 d, h/ n6 D9 n+ q
最后当然少不了测试代码: |
|