|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
9 S) O; p0 _" t& o, F$ e 2 #include <cstring> //for memcpy,memset % [" h7 @- z U$ c
3 0 `$ `" @- D ^' z* F( W0 d
4 using namespace std; # ^; l: h; _7 M" P1 x3 s4 ^
5
+ Q) F9 _' h* A. i3 H' f 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
- v/ [ y' O( W$ Z 7 :_round(round) & a; \# w$ m0 D6 k) n A, i5 O
8 ,_isNetByte(isNetByte) {
5 k' S1 Z6 d& {7 L; ~ 9 if (key != 0)
9 }% |5 D9 @1 C10 memcpy(_key, key, 16); ' L7 N! C: v. X- Q
11 else + P5 a- W9 W# I0 b# t3 V# p3 H
12 memset(_key, 0, 16);
0 I6 r' z: S" J13 }
" q$ F: \+ ]& D6 [6 n7 ~. F14
- e: U7 x( J Y15 TEA::TEA(const TEA &rhs) , H5 v: R1 t+ a
16 :_round(rhs._round)
& a6 a5 _4 J- q17 ,_isNetByte(rhs._isNetByte) {
: J1 ]" R' U0 t* }18 memcpy(_key, rhs._key, 16); / m0 `7 `, k# O* c1 C3 Y4 ]
19 }
9 x2 r: a* D5 P' R20 ! \! X- @4 ~' t6 R; u* E$ R
21 TEA& TEA::operator=(const TEA &rhs) { 5 a# j* |) c7 { R
22 if (&rhs != this) { : M5 @# |; o' ^/ N% F8 q" Q& @
23 _round = rhs._round; % T( f3 o4 q" l1 u
24 _isNetByte = rhs._isNetByte; ) P7 U, u; ` V3 j
25 memcpy(_key, rhs._key, 16);
2 ~: f/ M+ g8 _( Y5 M# `) O26 }
8 H* m: E* `$ Z# J# _+ H& Z I* ^27 return *this;
3 n/ }3 h. w0 S- L28 }
e) K% R4 e8 G" q# R3 B29 + Y3 e& n( F0 b2 J) d, {
30 void TEA::encrypt(const byte *in, byte *out) { ! {2 H1 Y3 F# y
31 encrypt((const ulong*)in, (ulong*)out); 1 ^1 P. \/ N: u, Q6 g9 t
32 }
0 v" i$ b: G( W! H33
' r5 o, R/ }; {" L- k; i$ m9 Z+ d, u34 void TEA::decrypt(const byte *in, byte *out) { ! H u g* `7 G% V6 f) T
35 decrypt((const ulong*)in, (ulong*)out);
, }7 E- |; i; t1 U3 y36 } : X; f& b+ x f. L( g3 X. z
37 6 j* `. N( [- A. Y2 b6 S5 d7 U
38 void TEA::encrypt(const ulong *in, ulong *out) { + w- e( ?; |" |1 u
39 7 v1 C7 {. j4 {$ [( l0 l
40 ulong *k = (ulong*)_key; * X% o5 z8 b2 X0 M9 k. ]
41 register ulong y = ntoh(in[0]); 1 X. v1 u; p1 l
42 register ulong z = ntoh(in[1]); 5 N: Z9 ]8 t7 v' L! g0 {8 |* |1 L4 `
43 register ulong a = ntoh(k[0]); j2 I; J7 d1 }' i
44 register ulong b = ntoh(k[1]);
6 j- x/ Y0 Q% T; a45 register ulong c = ntoh(k[2]); ; {, `. W, q; K; b
46 register ulong d = ntoh(k[3]); # _# t7 n# t3 M- V& X0 L
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ( H/ G9 t# j8 h" Q1 w( q
48 register int round = _round; " I, {8 [& D9 W. Y& n8 j0 i
49 register ulong sum = 0;
' j# ~4 W, X0 U% R50
) h8 @! w1 p3 y1 W- C, ]" U6 ]51 while (round--) { /* basic cycle start */
3 b2 H$ G# S+ p* K2 y+ \ \52 sum += delta;
& U# P Q& d r. n( [53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
0 I9 @% p: h" |+ r' E54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
/ V' Q* l+ X9 Z1 |( ]55 } /* end cycle */
& R) W' v, f, B5 A1 }4 L0 {56 out[0] = ntoh(y); & N% z9 S; k3 k3 V$ R) e6 W9 ]
57 out[1] = ntoh(z);
' b; d; M+ a. [; K+ J* r1 y2 C58 } 7 m7 h' Q/ G" Z0 b" M' {
59 + ?+ c* _+ m$ z# u$ p; G6 O
60 void TEA::decrypt(const ulong *in, ulong *out) {
* e* `5 d R% k% B; L61
) _9 r$ d M% {& M62 ulong *k = (ulong*)_key; ; D1 }# F# g+ J# G8 x |" S
63 register ulong y = ntoh(in[0]); 6 ~/ q" ~6 ~, M9 j: \. M8 v
64 register ulong z = ntoh(in[1]); ) X+ {, i" N X1 n
65 register ulong a = ntoh(k[0]);
8 R( D( z! p: Z6 S0 J D66 register ulong b = ntoh(k[1]);
r. u( b) `/ s C ~67 register ulong c = ntoh(k[2]); ! ?5 k! F9 d! j0 {& w V& M3 z2 X5 M
68 register ulong d = ntoh(k[3]); 3 T/ s8 A. U2 K- U7 ?9 K
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ % A9 c P1 u3 P7 N0 v m5 }
70 register int round = _round;
u3 w* i6 u/ H+ ^! r1 i X71 register ulong sum = 0; % H, L7 l; V( l' }
72 + A8 }* m- x) w: M& k4 y" i7 I
73 if (round == 32) 7 v+ V6 A: r% P; C3 u E# |
74 sum = 0xC6EF3720; /* delta << 5*/
; A, T3 w+ l0 u9 V75 else if (round == 16) , _8 a; A; F }$ ^- S. L. o
76 sum = 0xE3779B90; /* delta << 4*/ # ^) z4 a3 c* x# O9 c
77 else
5 ]0 l: s6 ]! ]; Z78 sum = delta << static_cast<int>(logbase(2, round)); " @ K: Y) o, r: H! n0 ~
79 9 n1 }( \8 Q0 \$ M% u& @
80 while (round--) { /* basic cycle start */
! F# y2 U0 x, D81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
' p( D ?$ h: _6 @82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
0 \/ y* C) b; ` i! X83 sum -= delta;
" y# i# v2 ~5 {- i9 |7 L7 M2 O8 [84 } /* end cycle */ ' I8 c+ k4 _ j# P* P
85 out[0] = ntoh(y);
; L( @1 X* M7 ^- u* t86 out[1] = ntoh(z); - Q, X- Y6 G* j2 {2 n" u( J7 R
87 }
$ R$ r/ c6 h* b% O- w5 [
% f! k, L g. N8 _ n需要说明的是TEA的构造函数: * z6 j: c$ o/ K+ _, k. @; n' W
TEA(const byte *key, int round = 32, bool isNetByte = false);
* P# w; U# ^+ @1 d2 u1.key - 加密或解密用的128-bit(16byte)密钥。 ' i4 f4 Q$ Y2 Z
2.round - 加密或解密的轮数,常用的有64,32,16。
( R; v2 F# S) l! U, l) M3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
& `+ l" U* \; @% j2 h. s; o
: p7 |* E$ A' h最后当然少不了测试代码: |
|