|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" + t% c$ G4 [8 q
2 #include <cstring> //for memcpy,memset
6 l! P7 B' t, T e. Z) S! Q5 D+ {- O 3 2 z9 n1 c ]! L5 I
4 using namespace std; 4 H6 X- J% N3 g7 |- {4 ]9 v
5 & Z7 F* P! M \; ^( F- F3 u
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
' h# W/ g# a7 H 7 :_round(round)
3 r: V2 ?# w1 ~2 Y* E 8 ,_isNetByte(isNetByte) {
9 {/ P( i) \/ u0 T' U 9 if (key != 0)
4 J! a; O& x' C, {10 memcpy(_key, key, 16); ; R: W! H' Y* D' P* s$ j* T
11 else
8 H! W; c8 X+ [# C: W' Y$ V& S( p& @12 memset(_key, 0, 16); 6 }$ s9 n/ M$ S( b
13 } 2 o3 _5 E9 l. @& Z
14 7 ]& b" W D ?8 @8 C' Y
15 TEA::TEA(const TEA &rhs) . I: H6 t6 v4 a/ d0 G1 Q# Z
16 :_round(rhs._round) # ^0 V% R9 r7 R8 N5 I* z" ~9 G7 S
17 ,_isNetByte(rhs._isNetByte) { % k0 z+ _9 f' x/ g) i
18 memcpy(_key, rhs._key, 16);
0 R/ V( ]0 |2 D19 }
6 n' O6 A X9 w- |5 A1 k/ C20 + S& E' m8 _ H* V: m
21 TEA& TEA::operator=(const TEA &rhs) { 7 @) @9 l: Z! {5 A) X" {
22 if (&rhs != this) { : w- q7 s D8 H$ @- \; J/ W
23 _round = rhs._round; * e+ T: {; b/ o7 M
24 _isNetByte = rhs._isNetByte; ! k9 U: V3 ~6 e- ]. ~: y3 \- w/ o3 H$ E
25 memcpy(_key, rhs._key, 16);
% O \5 o1 w3 [5 [26 } 8 k/ r" A8 F1 K L% m2 L# l% u& i
27 return *this;
~8 l% C7 ]% ^1 W3 V" n28 } . H& K0 u+ t+ c" p" Y6 Z
29
" ]3 h- K& I1 j. \# T$ o5 Z30 void TEA::encrypt(const byte *in, byte *out) { 2 u* M4 F3 T8 m% d: |4 ? G2 L- D) P
31 encrypt((const ulong*)in, (ulong*)out); ! e1 m4 D5 e% r4 |, N4 o
32 }
7 d4 c& u9 z" D4 L33 8 K* g: ]: b+ `) M% h, G
34 void TEA::decrypt(const byte *in, byte *out) {
+ j& {. p; e" s2 v( Q, Y0 u35 decrypt((const ulong*)in, (ulong*)out); * z2 B( n9 v( w( n `& H
36 } 8 P& P, w+ V- v/ K7 v
37
4 C# g7 T, a4 ]" g38 void TEA::encrypt(const ulong *in, ulong *out) { # F% X- }! G! U4 N; Z& p! v: i; N
39
' N3 D9 J8 o8 M6 I7 \40 ulong *k = (ulong*)_key;
; d9 a1 e* i1 Y41 register ulong y = ntoh(in[0]);
+ c# D) p0 a3 m42 register ulong z = ntoh(in[1]); ' B: D+ { l" R% k
43 register ulong a = ntoh(k[0]); 8 J9 N( G0 F7 k9 v6 V s
44 register ulong b = ntoh(k[1]);
8 k3 l7 ~- E( S& }45 register ulong c = ntoh(k[2]); # c8 |; J9 k, f1 ^/ J, M9 F1 K" W
46 register ulong d = ntoh(k[3]); * q% z7 U) Q/ m" P, i; ?& F
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
8 a# P0 j2 P$ v. l4 G6 v- O0 ]3 A48 register int round = _round;
: _0 M4 S0 M8 a49 register ulong sum = 0; 6 ~- P' t# s! Z1 x
50 % `3 H; V8 d( x5 a* x' X' E
51 while (round--) { /* basic cycle start */
3 j s5 ~' G: L; x K* Z52 sum += delta;
) k" x* L- N- P1 {* g; O" j( i53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); : r! k/ J) J! n S" {. X5 z
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
' H+ R7 M3 h' y, M8 Y55 } /* end cycle */ 3 y$ C% ^5 W$ l& Q6 @5 p) Y
56 out[0] = ntoh(y);
2 |, H- Q# X$ \- p% q4 c57 out[1] = ntoh(z); ; M& G8 e9 I5 L" a- J& a* R! v
58 }
! a+ l$ E+ S2 @; Y8 O, v- l. `59 + B! x0 G% C6 e7 F P1 w
60 void TEA::decrypt(const ulong *in, ulong *out) {
) o" z, h; |2 w9 L% p! x8 J5 j/ f6 U9 L' M61
( p4 O: s2 |- t62 ulong *k = (ulong*)_key;
' A* E, W7 c% d4 D5 T0 [# [63 register ulong y = ntoh(in[0]);
7 o+ p( A- A) [; ?. Q2 [64 register ulong z = ntoh(in[1]);
9 ^2 p R# }0 C6 Q5 ~& I65 register ulong a = ntoh(k[0]); ' d& M+ c$ ~0 `4 @5 {# R3 u; E
66 register ulong b = ntoh(k[1]);
+ v2 C z V: y: \1 s% T67 register ulong c = ntoh(k[2]); % z# F4 F+ q. [& T# m; b/ z
68 register ulong d = ntoh(k[3]);
5 ]2 m5 F, w# A& j69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
; ~% p' E, A2 [8 X# m70 register int round = _round;
& a. ^' y/ ]( d8 T' I# v$ |$ i71 register ulong sum = 0;
3 s4 P1 S; m8 P" _+ E- R9 F72 ' G1 F' i3 Q: R/ W2 \0 J0 M
73 if (round == 32)
7 c9 m4 e8 L9 c74 sum = 0xC6EF3720; /* delta << 5*/
( d5 S1 v H+ Z, x75 else if (round == 16)
) R/ g1 M7 A5 g, E6 t! l: m76 sum = 0xE3779B90; /* delta << 4*/
- b8 U; r5 U/ V6 ?; b: C/ ?' }6 r77 else 7 V$ |4 `& \" ?: K
78 sum = delta << static_cast<int>(logbase(2, round));
3 m" _& ?2 H! l( R# Z. G% U/ O- ~79
4 @6 x5 s3 h. }) V9 _% }80 while (round--) { /* basic cycle start */ / ~& O( S+ N/ m; h. M6 l4 E
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); , z5 M' l) `: j6 f& x
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
) ?' K% y& @9 @! ~/ e0 J. W6 c9 w83 sum -= delta; / S! l" z$ K5 k V" n$ y' I
84 } /* end cycle */
- h4 E) c! ?: K85 out[0] = ntoh(y);
# `5 V/ k# i h0 o+ P& Q8 l86 out[1] = ntoh(z);
: I6 o. {7 ?( [" C87 }
+ g1 ~! {5 a* h6 C# j% f8 H
) e3 B0 M7 C; c* ^3 P3 W- d$ |需要说明的是TEA的构造函数:
! l# l1 H/ G5 T u) W( ZTEA(const byte *key, int round = 32, bool isNetByte = false);
3 X3 @+ D+ J' j, s! c1.key - 加密或解密用的128-bit(16byte)密钥。
. T. Q. ?4 S% n2.round - 加密或解密的轮数,常用的有64,32,16。
# o6 p+ `1 Z# b# ^! \ O5 Y; \3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ! z% Z+ F; Y6 U) u/ X
7 k4 F' Q. s4 t% i/ j) a最后当然少不了测试代码: |
|