|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
" a- X- j; M( f4 B- J 2 #include <cstring> //for memcpy,memset
) g$ D* ?5 m3 U: ~4 Z5 Y! c 3 5 O6 ]# k* b6 O. F; B2 o9 `: u
4 using namespace std; 3 c/ }1 L! Y3 I+ m$ C
5
2 }/ N0 [0 _2 C1 L5 m f2 H 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 1 @: `; J( A7 m5 }- p, n. R L' q
7 :_round(round)
7 C" J0 G( D* V6 U( K 8 ,_isNetByte(isNetByte) {
* q) t4 A- d: s8 T% O, Y. G 9 if (key != 0)
0 X6 e1 _1 W5 K% f: b10 memcpy(_key, key, 16);
& h0 P3 ?8 A3 ?# K& M8 I6 O11 else . d1 ^& {, u/ h- E) z
12 memset(_key, 0, 16);
# v. |/ C! c! `* O/ P- ~; r13 } " w9 R3 t1 k( f( Q; G4 ~$ o+ G
14
: a0 p V. p& L: b1 R) K6 `/ j* i15 TEA::TEA(const TEA &rhs) ( a% p t2 j5 C5 z1 ]
16 :_round(rhs._round) 8 k2 {8 \2 T( \/ k
17 ,_isNetByte(rhs._isNetByte) {
8 V$ k I. I4 c+ S18 memcpy(_key, rhs._key, 16); 7 Y; a2 f) t& d3 J
19 }
5 f1 V. ]: p' G+ e+ a20
9 V8 g% |6 n {4 z) W5 E" m6 P% w21 TEA& TEA::operator=(const TEA &rhs) {
" M% ~& o; T6 X0 _. \8 c0 o9 u22 if (&rhs != this) { ; P& F, \5 R6 k5 Q( s4 j
23 _round = rhs._round; 6 P# a. e9 B5 B& @
24 _isNetByte = rhs._isNetByte; 4 g$ l- M4 N9 [: E
25 memcpy(_key, rhs._key, 16); , k+ ^: ?5 N8 u& U
26 } $ q( Z$ q, _6 K8 J4 V& ~0 a
27 return *this; 9 Z6 l8 c1 b6 C4 v! Q& _# T9 n
28 }
u( \. P& h' a6 [; w: @$ N& ^* u29
: s) M9 S2 P! U! C30 void TEA::encrypt(const byte *in, byte *out) {
1 L U* L- _: d: ~2 p31 encrypt((const ulong*)in, (ulong*)out);
3 D" S4 W9 ?4 b/ U' i" m32 }
0 T8 Q$ ~& A/ e% c r |33
: s9 I8 H3 L! G$ H# s; S7 U34 void TEA::decrypt(const byte *in, byte *out) { & u% }. P& u$ W8 ] k
35 decrypt((const ulong*)in, (ulong*)out);
/ ^9 L9 x8 ~9 p2 v: V4 D' L36 }
" |6 v$ I# b- c" _; P4 w4 `37
2 h# N' K: C+ ? y- |38 void TEA::encrypt(const ulong *in, ulong *out) { % N+ h" L8 L5 {4 }
39
- I G | u$ \0 o" Q7 [/ x40 ulong *k = (ulong*)_key;
4 b X' \+ H/ e$ g( N, j41 register ulong y = ntoh(in[0]);
2 p7 x, t" f3 Y2 E42 register ulong z = ntoh(in[1]); & f2 m( r+ Q9 ?6 x4 {' d
43 register ulong a = ntoh(k[0]); ( Y( D4 a- h h* e1 _
44 register ulong b = ntoh(k[1]);
2 ^) Y6 P) k6 T; t45 register ulong c = ntoh(k[2]); / C5 T* {, c# f) J9 ]
46 register ulong d = ntoh(k[3]); $ F8 o5 V" u. F" G/ ~
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ - Z" V. P: J* V3 V& ~% s, e8 ], N
48 register int round = _round;
' \% T* o' c' L1 B4 v# x: ~0 G49 register ulong sum = 0;
7 ]$ O; s" Y( E) `- y( J( w* f! \$ s50
/ i/ Z6 l+ X* {+ [5 O* E ~7 _$ t8 m51 while (round--) { /* basic cycle start */
) O1 k# c. T( d$ N5 E. F& o K52 sum += delta;
8 S$ }& e# ]- s. p9 I. o9 n8 I! ]53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
1 Q2 ^+ I1 T! O2 o54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 2 L) Y& a# ~3 C; b+ X
55 } /* end cycle */
: { ^* p" ]; J4 k+ z0 M! l2 q56 out[0] = ntoh(y); 8 @+ }" @2 H! K
57 out[1] = ntoh(z);
1 w# [7 o; d% i, `7 ^58 }
* c* h9 {* ]! j59
/ X' R! y7 v6 x) f! C4 c60 void TEA::decrypt(const ulong *in, ulong *out) {
2 U7 j! f5 M y7 q61
/ E: N* L: ?. {9 I# q* a& e62 ulong *k = (ulong*)_key; * b( d3 _$ j% @/ O
63 register ulong y = ntoh(in[0]); : D/ v5 I! Z2 o& A& ^
64 register ulong z = ntoh(in[1]);
5 A& A/ ^. P5 r65 register ulong a = ntoh(k[0]); 4 e _$ z7 j4 x8 G0 W3 C9 a
66 register ulong b = ntoh(k[1]); ( f4 J% O4 d; I# y) G
67 register ulong c = ntoh(k[2]);
) q6 j1 g7 @& l5 n* p7 G) i68 register ulong d = ntoh(k[3]);
2 p* N% m S* `- P, N69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 4 o3 Y8 l5 U: Y# {
70 register int round = _round;
I0 x* T1 ?+ H3 T71 register ulong sum = 0;
% O* | V {" e0 I( S72 ( `$ F* o3 k9 j( A& m' K
73 if (round == 32) % R6 O, F! P8 G
74 sum = 0xC6EF3720; /* delta << 5*/ 0 B$ t8 n6 W9 c3 G
75 else if (round == 16) ( C' R/ |" I1 B( I4 H
76 sum = 0xE3779B90; /* delta << 4*/
& b; Y/ Y: E3 H4 | L) ]0 s; _( C77 else 4 ]2 h" ?; G9 y% p: [
78 sum = delta << static_cast<int>(logbase(2, round)); 0 ~8 `! x& u3 B. L* a1 M# Z
79
7 V0 ^. c$ K) U! m% a! |: L+ C80 while (round--) { /* basic cycle start */ $ v' E$ h d0 V1 _
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ' x. I, {4 D& r+ q6 J/ u4 Y
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
; \! v6 t6 f7 k3 j' ?83 sum -= delta; 4 r" N* M4 B2 d4 d. R# ~
84 } /* end cycle */ S. H& c$ b9 k' X |
85 out[0] = ntoh(y); ; ^; ` A; \# m; i! M9 M$ Z
86 out[1] = ntoh(z);
: ^; F/ ^) T. y- [' l87 }
9 \/ e$ v; F4 o) W: E0 b* J3 u( U
需要说明的是TEA的构造函数: ' r% v+ N3 C1 ?- O$ C+ K! S& ]
TEA(const byte *key, int round = 32, bool isNetByte = false); & q% Q7 G, }0 }, W) W
1.key - 加密或解密用的128-bit(16byte)密钥。
8 ]" q- M; z. Q4 X1 r! r2.round - 加密或解密的轮数,常用的有64,32,16。
, i( l, r5 E$ q8 s4 W) Y3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
' A& z7 f! @* g$ ^; l# _( m7 V4 ^5 {, Q* h9 V# f3 J2 \# x
最后当然少不了测试代码: |
|