|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
. Q4 K7 a( R1 `. K8 E' s 2 #include <cstring> //for memcpy,memset
E% i8 g& {( v0 {- q" C2 y r2 f4 M% q 3 # s; {, |1 E9 n! g
4 using namespace std;
9 g: A. w: I6 I7 E* r 5
( P: V% T3 }2 H( P: v9 H2 y D, `! e( A 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
' w# X* P" u0 N6 U 7 :_round(round) 1 J) U( L. U$ p; F/ O( B1 c
8 ,_isNetByte(isNetByte) {
: m% F6 k/ N1 }; ~' } 9 if (key != 0) . ~- m" `9 V) K* v# t
10 memcpy(_key, key, 16);
% ?5 n1 N5 b) v* B11 else 6 B% J! {% F4 Y/ H% S ~! j5 T
12 memset(_key, 0, 16); & c0 n8 w' D5 @ I; W3 t3 r
13 } 8 o1 ]3 T- c# [ \
14
) W2 I/ M8 m) c15 TEA::TEA(const TEA &rhs) 8 i9 x/ q2 y/ i8 E% z k2 M
16 :_round(rhs._round) 8 |9 O3 h* ?/ x0 a# `3 O: c
17 ,_isNetByte(rhs._isNetByte) {
! o2 ~ r3 N& J4 z18 memcpy(_key, rhs._key, 16);
! [4 z2 L) C9 e8 l19 }
1 @: ~# @' H9 o2 {8 w q" m: M8 Z* n( L20 # K- g8 a; @6 F F# [5 C. z- o, C
21 TEA& TEA::operator=(const TEA &rhs) {
) D+ M3 I' o: p* F" X22 if (&rhs != this) { 4 \1 |$ A& g) i& [+ _. f
23 _round = rhs._round;
) q2 |' R3 b; F# i, J24 _isNetByte = rhs._isNetByte;
( G' B4 M1 F- U6 z) G7 U* a1 l25 memcpy(_key, rhs._key, 16); , P' S9 {2 w, x9 l/ e! {2 @
26 } * \* D* W( x* f7 r
27 return *this;
) X9 E8 V% B4 `28 }
' L* Q- G# Z: o; Z! F29 ! ^: F3 X# O) s$ d# e9 {9 |9 `
30 void TEA::encrypt(const byte *in, byte *out) {
, R* h. d3 `+ r# n* v2 c1 W31 encrypt((const ulong*)in, (ulong*)out); ! j7 x! i. @ B( @7 b2 I
32 }
* w2 ]. t+ V' A& f0 }* k# ^7 M33 - L9 \" \) q) h! w2 G+ z
34 void TEA::decrypt(const byte *in, byte *out) {
3 r3 j7 l# k7 P35 decrypt((const ulong*)in, (ulong*)out);
( w0 f {0 H0 O0 `$ z36 } ! G* C! c8 q0 X
37
& \6 a4 _ P4 t' M, ^% E38 void TEA::encrypt(const ulong *in, ulong *out) {
1 K$ V! B" r7 j3 ^/ T4 v1 ?5 T39 ) I! q1 ?* w' q) W5 E
40 ulong *k = (ulong*)_key; 0 N$ X0 U: R/ x) b& v2 d/ v
41 register ulong y = ntoh(in[0]);
( U7 f, A# u# G- p( Z y& N6 A42 register ulong z = ntoh(in[1]);
) \8 t- y% z D* Y0 T; w43 register ulong a = ntoh(k[0]); ' v5 c! t4 E/ ?
44 register ulong b = ntoh(k[1]); , W4 P9 h0 q" v2 g+ j0 i6 k6 V! G
45 register ulong c = ntoh(k[2]);
' K0 L3 J2 W1 B- q" g! z46 register ulong d = ntoh(k[3]);
/ H- k) R8 E* F Y2 l8 ?' x47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ; A+ y L& V" Z7 H/ v' l' E
48 register int round = _round; 0 Y+ B6 P! k6 l; T4 d
49 register ulong sum = 0; 5 v" U- e" N b
50 ! Z, l( w, c9 R4 \: q. z6 h
51 while (round--) { /* basic cycle start */ 7 W7 _9 m7 K) [6 z2 W1 A" R7 ?
52 sum += delta; $ E; j1 L& |; k6 [3 d: t7 ?: m; ]4 R
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); % W# `5 M: m8 c, w4 o x0 w
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); % W ~4 K. o) Z6 a2 F7 P
55 } /* end cycle */ : z% R& b0 t7 c9 j5 @& t1 S }2 {
56 out[0] = ntoh(y);
& E, Z% x& W6 ]" h57 out[1] = ntoh(z); " F# L: l& u7 h1 N3 J% Z
58 } ' t, v' ]0 N: t8 W5 y" R4 z
59 , o4 ^+ u$ ^$ U
60 void TEA::decrypt(const ulong *in, ulong *out) {
1 i1 E: y# l# l: X& k7 X61
+ v* v' ?! {/ X& T$ @+ l62 ulong *k = (ulong*)_key; # o2 e" w- u h
63 register ulong y = ntoh(in[0]); 5 S+ f, c+ G- f/ ]( ]
64 register ulong z = ntoh(in[1]);
7 p N% S9 x$ Z, b65 register ulong a = ntoh(k[0]);
! s4 p- f4 u) }+ _$ V) U. W/ m66 register ulong b = ntoh(k[1]); $ _) K2 b8 e0 C' p8 G& F$ W: Q
67 register ulong c = ntoh(k[2]);
* J7 L7 ^! n6 n* A% T5 O, B68 register ulong d = ntoh(k[3]);
6 r1 F5 r% `: j! r( i9 b- Y69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
: E' t/ A2 M2 \. u9 ^+ p! F70 register int round = _round;
0 J5 o$ o9 z8 K8 J% v; n8 t71 register ulong sum = 0;
! X. p# b% c6 ?' l4 J72 8 _" [& H, g* l5 O6 \7 D2 T3 G2 a; b
73 if (round == 32) . g) K6 v9 |; j& q
74 sum = 0xC6EF3720; /* delta << 5*/ " Z7 k2 s0 h" E/ Z" k: o, n
75 else if (round == 16)
2 g! q! p1 Z, L7 W1 y76 sum = 0xE3779B90; /* delta << 4*/
! }$ y$ w) t! q5 D, h77 else ' [6 q# D4 w& [. L" g
78 sum = delta << static_cast<int>(logbase(2, round)); 7 r! p( P, S5 \
79
) l2 n( b( N5 b/ H g5 N80 while (round--) { /* basic cycle start */ % i7 z( |' m2 t/ d$ K
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ( e' |# `0 X" S/ H0 s
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
& Q: Y V! y+ P3 d3 Y83 sum -= delta; . O/ [0 k4 P% `; f/ d) X
84 } /* end cycle */
- V% ]- U* e$ Y1 e$ m$ V85 out[0] = ntoh(y);
. |; A+ r5 R" D# T# c86 out[1] = ntoh(z);
+ W! j1 O2 v9 z. {87 }0 z. M; M8 g) Q2 }
& e% ^! {% e! M- r4 Y# \: S需要说明的是TEA的构造函数: ; O8 c' ?* q) q5 P
TEA(const byte *key, int round = 32, bool isNetByte = false); 9 Y0 C0 X2 E' b$ ?
1.key - 加密或解密用的128-bit(16byte)密钥。
: z3 B, `: B0 i: U" B2.round - 加密或解密的轮数,常用的有64,32,16。 6 z2 h4 T9 H& `
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! / ]/ F" E* _, u- U) O& T
( z1 I: c. _% R5 w; @最后当然少不了测试代码: |
|