|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" / Z5 q6 d8 ~4 l
2 #include <cstring> //for memcpy,memset
2 C7 o }& ~) E4 x* `) F3 M2 s 3
% r# T4 W& b# ?! O) q! |& H1 V 4 using namespace std; + ^% ]; F8 ?0 X9 f1 O% S
5
5 W3 t. {- B; E- ?! @, n: a' ]! p 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) " `2 T3 Y* W+ j: z
7 :_round(round) 9 r' g( O; C& C" c& r7 E8 ?
8 ,_isNetByte(isNetByte) {
0 s3 p( T! e" i 9 if (key != 0)
4 @) r! j9 _1 [0 w5 ?10 memcpy(_key, key, 16); 8 k. G8 @7 B8 D$ `4 X
11 else . a4 _' t7 W$ L9 L% w
12 memset(_key, 0, 16);
4 j+ `3 o& J" ^+ Q13 }
9 y' Q7 ?' x5 i0 K" m/ E* `2 s14 $ R4 I! A8 q7 }1 i
15 TEA::TEA(const TEA &rhs) * Y* H* r, c t; g
16 :_round(rhs._round) $ A; ]! w6 Y. U- b* W% A
17 ,_isNetByte(rhs._isNetByte) { 9 `) C& i3 O8 H! \8 X3 Y( l% ]+ r z
18 memcpy(_key, rhs._key, 16); 5 X/ S4 A/ g# V4 h! i# K( ^7 }
19 } 4 ?" e1 Q |6 @4 G
20
! p, h2 O% x( W0 ~21 TEA& TEA::operator=(const TEA &rhs) { " B& N- z0 N5 u4 C! e1 R
22 if (&rhs != this) {
: T& B7 ?/ f; ^0 y& `23 _round = rhs._round;
! S/ V$ V, A9 F24 _isNetByte = rhs._isNetByte; , g3 h5 d; w7 \$ j! H" G! M
25 memcpy(_key, rhs._key, 16); ( v5 p6 z3 W5 b+ `$ d0 o
26 } 4 W- D4 M- i( R( _5 S4 X
27 return *this;
" H1 [0 i- ]' ?% T) y- Y28 } 7 c/ p3 |; p; M, g
29 $ F' a! o6 x# M
30 void TEA::encrypt(const byte *in, byte *out) { : O! Z- d: W8 J1 U2 `
31 encrypt((const ulong*)in, (ulong*)out); ' Q3 F! g& m9 q p* s5 f$ R1 h B
32 }
+ z; u" }! F) i6 w* N: L33
( F- X) c% w+ e+ v# M34 void TEA::decrypt(const byte *in, byte *out) {
3 _9 z7 |: d& Q2 d( A! e$ h35 decrypt((const ulong*)in, (ulong*)out);
5 s: M5 g; j1 q36 }
1 n* v+ `) y8 N37
. V$ B$ r* a; w5 v, I. b38 void TEA::encrypt(const ulong *in, ulong *out) { , F5 v& R' G9 {7 N* C
39
3 u, d- e, G' o0 ]40 ulong *k = (ulong*)_key; " s# @& J3 J, x: i: `
41 register ulong y = ntoh(in[0]);
: I& M# L! ]! g; ^ w/ u42 register ulong z = ntoh(in[1]); ( j- s4 |# r3 m( y; c
43 register ulong a = ntoh(k[0]);
- ~2 m+ H/ H M* w7 s# u44 register ulong b = ntoh(k[1]); % Y; y1 J |6 m+ ?: g
45 register ulong c = ntoh(k[2]);
* p0 [& q0 p5 C( W% P; U0 y+ B$ a46 register ulong d = ntoh(k[3]);
; n8 ?2 C: A6 u2 {3 m; V" a5 ?47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
' N; J$ T7 a% P) Z. A% V48 register int round = _round; / C8 {- \ Y' W, [6 S
49 register ulong sum = 0;
% |' e/ J9 |3 u' C7 d50 ! ]# m0 g- K7 h
51 while (round--) { /* basic cycle start */
. J5 O `) Y$ E6 L( t; W' w9 d52 sum += delta;
. F$ w5 H, x6 A0 J53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
. Z9 D% @. s7 l' G+ ^54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
% }6 c7 b+ c# f6 H; O. v55 } /* end cycle */ % a3 R3 A- P* N) p" t/ {4 X: y
56 out[0] = ntoh(y); ; G+ Q2 {" S0 n+ O! g3 N
57 out[1] = ntoh(z);
& U0 |5 ]! ~$ W4 k58 }
6 J# H& t' {5 w; _59 1 L& f& ^# w0 |$ ^
60 void TEA::decrypt(const ulong *in, ulong *out) {
# Y. ^2 T8 J7 c" c+ U! f61 * `; `2 }/ h! y" s* ~/ t
62 ulong *k = (ulong*)_key;
5 b0 S# O# J# O9 }; S" x& G/ \63 register ulong y = ntoh(in[0]);
7 H; j4 M% Y) \. p) ]" {64 register ulong z = ntoh(in[1]);
* u6 n) t, v ?( }65 register ulong a = ntoh(k[0]);
* v% ~ O1 k6 m. i66 register ulong b = ntoh(k[1]);
' k) Z0 z* f' Z" r1 z67 register ulong c = ntoh(k[2]);
9 [% O6 t) w" c; r7 t) K68 register ulong d = ntoh(k[3]); 1 w9 G, f& }3 H" C6 e9 h; h! [0 j! _
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ & V1 l7 E9 _# w$ c1 Z9 t
70 register int round = _round; ) k! t, z$ X8 t9 T
71 register ulong sum = 0;
6 v, @( ^8 _. {: K. D# z72
; ~& s( t9 @2 n73 if (round == 32)
) n- B' @ v" O9 e7 ]74 sum = 0xC6EF3720; /* delta << 5*/
; A5 E# T- @! N! [, z/ z75 else if (round == 16) ) h/ R, q7 e. ]3 `- c
76 sum = 0xE3779B90; /* delta << 4*/ 1 f K# \: t- Q5 d, v4 v
77 else
, g6 [* L2 V* \; g) F0 w78 sum = delta << static_cast<int>(logbase(2, round)); + c2 _; M$ o4 }$ l' S1 G- L7 O
79 & l1 V; s1 x! u
80 while (round--) { /* basic cycle start */
+ @1 v" v8 ~! Y. u$ G81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
7 f8 a2 E7 ^" O& G; k$ z0 Q/ ~82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
- D2 s5 d1 F) _% r* p3 w83 sum -= delta; ! f/ L& b' g) h
84 } /* end cycle */ + o# E* E4 ^! x; o* Z
85 out[0] = ntoh(y);
3 c6 l; s% t% r5 r$ m86 out[1] = ntoh(z);
& ^- F9 w8 D& w% M" d: n: l [87 }
3 V2 @0 s( S2 G$ F% |' J0 _. U! u& C* N" [1 R% z( m9 P
需要说明的是TEA的构造函数: - v5 Z$ a8 B$ e0 ]% M4 t" m
TEA(const byte *key, int round = 32, bool isNetByte = false);
$ ~3 ^1 v" ~+ B) C3 J1.key - 加密或解密用的128-bit(16byte)密钥。
% x% z% k- P" I! L2.round - 加密或解密的轮数,常用的有64,32,16。
- f# s$ b7 o" G7 g3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! & }2 ^ r* A8 H% ~
8 E: f. R+ r- ]/ z/ H! E- p最后当然少不了测试代码: |
|