|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ! c _4 a2 C8 s: L( m
2 #include <cstring> //for memcpy,memset
- u. V: W+ q0 K& h8 T 3 0 ~) N3 a. s& V+ L. D
4 using namespace std; 5 ]/ [% v. ^' ^% t0 Y" i4 q4 M
5
1 l6 D" _) \: \+ t4 ^3 ` 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) + j( h# I$ U! ?) t5 E! u
7 :_round(round)
* \0 q& t; m% T/ V 8 ,_isNetByte(isNetByte) {
8 `- ^% b0 S( ]5 ?! D 9 if (key != 0) # Y8 d8 g" I" ?$ M
10 memcpy(_key, key, 16);
* n5 B/ N" o: ]11 else
* [, q" T7 G ~1 \# m12 memset(_key, 0, 16);
& G3 N p& B0 B+ d/ a13 }
' N$ X, Z, Q0 H) I5 ?14 ' y% c9 `4 ^3 C# W7 _0 c" w
15 TEA::TEA(const TEA &rhs) + Z6 H D9 k) M' _: R0 F4 Z
16 :_round(rhs._round)
' e7 T: y6 S" }& W/ r17 ,_isNetByte(rhs._isNetByte) {
1 _/ D8 W3 z4 C. m18 memcpy(_key, rhs._key, 16);
+ r+ u7 Y2 w) x k19 }
$ ?6 R0 g* z& J" l! _) R20 + S( @7 x' n1 }( l% B
21 TEA& TEA::operator=(const TEA &rhs) {
+ H* B6 |# X: t: Y" U6 {4 J; {22 if (&rhs != this) { ' c* N4 X8 c/ t/ d1 P* J5 ~
23 _round = rhs._round; ) |; J% o) m$ q
24 _isNetByte = rhs._isNetByte; - S* x& r" C5 }( O: a4 [1 G, n2 B8 v
25 memcpy(_key, rhs._key, 16); 8 A) r# K; k* `" K( K% W% R
26 } ' ^! y( U) B% L% O( [
27 return *this;
8 o: { @$ [7 `; {: U28 }
" O& u' |' F* |- v7 B( h29 . ~ f _, h& {1 n" `
30 void TEA::encrypt(const byte *in, byte *out) { 2 E4 i2 @1 R$ Y5 z; W
31 encrypt((const ulong*)in, (ulong*)out);
, z4 m0 d2 A8 J1 p4 m9 T) Y32 }
3 c5 _& r: ~6 p& R7 b; w33 ; D! Z+ T6 U4 f {$ @' r; {
34 void TEA::decrypt(const byte *in, byte *out) {
+ n* z: f4 u2 B. i* g1 l/ Q" ^35 decrypt((const ulong*)in, (ulong*)out); 4 O5 p0 _* B' {4 i P9 z
36 } 9 D9 _ Z/ J G2 X0 p
37 # F; M, n9 K8 `8 L2 p
38 void TEA::encrypt(const ulong *in, ulong *out) { & w1 v! D4 F2 u" f6 _
39
5 g! o9 b0 E0 @$ [$ {40 ulong *k = (ulong*)_key; 5 a2 y; o- D6 T: a1 v( S* Z
41 register ulong y = ntoh(in[0]); ) N: w3 \- Z* E; G
42 register ulong z = ntoh(in[1]); & n4 S2 a+ U( f/ X* ~; p# Y7 I: O: j" W, @
43 register ulong a = ntoh(k[0]); + l# f) D7 _" c, Y
44 register ulong b = ntoh(k[1]);
( c! g0 F$ j1 V$ W, e45 register ulong c = ntoh(k[2]); : B" ?& y2 S& g+ p# u- w
46 register ulong d = ntoh(k[3]); $ n6 C& X; ]2 I: Y4 ]
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ . ?/ y/ z2 m2 K. N$ E& K! k
48 register int round = _round;
4 G/ H7 J9 c/ p; D2 A9 c, g6 h# y49 register ulong sum = 0;
; T+ k4 R" ]- R& E' m E+ o: h2 A50 7 m, h+ d, n" V8 Y9 @8 `2 ~- o
51 while (round--) { /* basic cycle start */
' A) H- D: X- k0 _6 r. C) \6 S! k% ?52 sum += delta; ; C; K& B8 P) o
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
& M, ?' L K2 e54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 3 ]2 v% _1 a4 Y1 Z9 z* V7 c
55 } /* end cycle */
/ h( {4 t& ]' V$ `; `56 out[0] = ntoh(y);
. t8 \3 q9 ?! e U6 N57 out[1] = ntoh(z); : F6 j9 w' C$ {
58 }
- R7 E8 ~3 U$ ], g9 G; g. @59
: ?$ ]3 ?1 ~( D) }$ q60 void TEA::decrypt(const ulong *in, ulong *out) { , K/ x, c8 B3 Z( W- W* `
61 # y& y1 R+ |3 A7 w! ]8 u |) B- f
62 ulong *k = (ulong*)_key; % b9 @7 M' I8 `+ E7 x6 b1 j
63 register ulong y = ntoh(in[0]); 7 L: n8 r7 G" |3 B; c6 ^
64 register ulong z = ntoh(in[1]);
7 g, m: x5 d* C) u& @8 k' B& A- {65 register ulong a = ntoh(k[0]);
! s W- j9 \- g0 r- Q66 register ulong b = ntoh(k[1]);
5 d X; {+ R+ S) e1 ]- [% L67 register ulong c = ntoh(k[2]);
, ?2 s. w) L. i: p2 v7 D68 register ulong d = ntoh(k[3]);
. Y/ F/ e& {8 V# H69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 9 h- B) q- V( ^2 t. N& r% ]! |
70 register int round = _round; 5 n, b5 U3 K8 ~4 m; {
71 register ulong sum = 0;
+ t* h& M! t9 G6 {72 " J% I* U9 \" Z# F2 Z
73 if (round == 32)
2 C: n$ {2 P( g3 Z. K/ H" G74 sum = 0xC6EF3720; /* delta << 5*/
e( W6 f& h2 v1 x75 else if (round == 16)
$ s2 `8 e/ `, C' Y, N$ c9 r' u76 sum = 0xE3779B90; /* delta << 4*/ : Y( N5 M4 `' A4 r" \3 v2 @+ C' l
77 else * L7 H& e! k( q( s
78 sum = delta << static_cast<int>(logbase(2, round)); ' ~) @' v- F/ n J$ H7 q: ^7 y' Q' N" u
79 - z# d' b: t2 Y( w1 S: l y
80 while (round--) { /* basic cycle start */ % @# Q5 C# E# |5 O6 V) k9 @# v
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
) R( W* e. n# Q d# L82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); , @' V8 E$ |( v x
83 sum -= delta;
% \; {8 A0 R) w `8 u- H. g. ?84 } /* end cycle */ : Z( _& [* _# L3 ]! v% a( a* L' g- D% L
85 out[0] = ntoh(y);
5 W7 D( g l$ m/ r! `3 ]) F: C' ]86 out[1] = ntoh(z);
* j! V/ a, w& g7 f7 p( T87 }$ B( Y, I* G+ J" t& Z! j: g3 y# u
; I1 A R; Y6 F需要说明的是TEA的构造函数:
3 M6 v# }7 [( ~$ n' eTEA(const byte *key, int round = 32, bool isNetByte = false);
! i" o9 r+ Q9 H; n' u& k7 L4 @6 A; z1.key - 加密或解密用的128-bit(16byte)密钥。
) `" q. X/ q, @+ z0 d5 F1 s2.round - 加密或解密的轮数,常用的有64,32,16。 / \' B5 M7 }9 M1 T6 ]" l8 V( ~" l
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
# F, r: Z; L; R7 ^7 s0 W
% f: j& S/ I0 \7 x, g% o* |最后当然少不了测试代码: |
|