|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
) H8 z/ _* x! F' o& I1 M4 S. } 2 #include <cstring> //for memcpy,memset 8 a$ ]9 v$ d: Y0 O+ B4 U7 ]
3
' e: {: A3 `0 k7 l 4 using namespace std; 0 C$ `$ z# k, n0 I; t
5 : H' G' N ~; m5 L
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) $ T# W* Z; V$ A2 s5 \
7 :_round(round) 0 ?8 n/ W [2 ?+ D, y
8 ,_isNetByte(isNetByte) { % T3 ^* c9 H# s# R
9 if (key != 0)
3 g1 Q& N$ j4 F; `& Z% Y% w10 memcpy(_key, key, 16); ' I& o4 C; ^3 H( x& r8 b. c
11 else / v( X3 t+ }; o& o+ _
12 memset(_key, 0, 16); 2 |3 q+ m( K. I- y. r% v0 Z# Z: Z
13 } P5 S7 c9 A$ e0 d& f
14
8 f# l2 w& J" R: y1 ]15 TEA::TEA(const TEA &rhs) + }0 r2 t; ^1 [! F
16 :_round(rhs._round) 6 ?! A4 B) W, k( x. x
17 ,_isNetByte(rhs._isNetByte) {
; i9 f$ d3 y- Z+ W- l! r7 [18 memcpy(_key, rhs._key, 16);
- a- M# f$ N; z6 w19 } 0 [) e6 ~! C* ]1 ^* q* r( H
20
4 N$ M/ W8 X$ x3 Z H21 TEA& TEA::operator=(const TEA &rhs) {
. s5 E: T6 C5 o. q! a22 if (&rhs != this) { : ~$ ?2 F( `5 \8 ?
23 _round = rhs._round; # M2 o) k6 d" s8 [# k+ J+ @4 w$ v
24 _isNetByte = rhs._isNetByte;
- _ ]# \4 Q) ]2 E25 memcpy(_key, rhs._key, 16);
4 P" ]$ O& T- Z& v: @8 V5 I, O4 {26 }
8 _' R) Q! o6 `0 ?' s i27 return *this;
0 r! ?2 k {% `* F: U3 ?# B' |: @* e28 }
* `" e# L& D9 u29
" d. ` O9 D8 a; x2 c. Y, g: A30 void TEA::encrypt(const byte *in, byte *out) {
& c! ~6 l4 f0 Z! z31 encrypt((const ulong*)in, (ulong*)out);
! X" O" A! @1 g" T) z7 q3 l( W/ f* d32 }
3 R- K; \# J7 P# F3 x33 ~, C( x8 I' h0 x+ l" x" z% d
34 void TEA::decrypt(const byte *in, byte *out) { ' k( d! I# W/ g/ ^1 A2 p
35 decrypt((const ulong*)in, (ulong*)out);
, E4 ^3 P, l4 m& R9 b36 } " _& Q. Z7 n& c, H
37
& V% h: c; o: q! j38 void TEA::encrypt(const ulong *in, ulong *out) { ) X1 @8 w- D8 t5 z. e$ h
39
' Q, |& D: l. w7 {40 ulong *k = (ulong*)_key;
# L( G7 |5 a/ R( }, v C! E41 register ulong y = ntoh(in[0]); + V* Z) i3 l1 ?) h
42 register ulong z = ntoh(in[1]);
" c I( V6 U" ^- Y43 register ulong a = ntoh(k[0]);
& G8 ~' {& F/ y0 c; C" M44 register ulong b = ntoh(k[1]);
; g/ ]4 `( N. O45 register ulong c = ntoh(k[2]); 8 z2 v& U( \$ E
46 register ulong d = ntoh(k[3]);
2 _, u x# ~6 U _& c47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ $ ^3 x5 b. g/ u. e: F. a2 ^ m$ h9 e
48 register int round = _round;
( t$ R5 O i7 O/ K49 register ulong sum = 0; ) n3 H% j+ e" Z4 @4 a
50
5 x4 w0 l& n8 S, ]51 while (round--) { /* basic cycle start */
) [4 A0 o* v8 U `52 sum += delta; * Y& {3 q0 L( S. T, C3 a; Y2 Q% |8 N
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
; g4 q! h- X/ w: W54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); " f$ @6 s/ S; m
55 } /* end cycle */
" G' b) X5 v) k; f2 h2 N56 out[0] = ntoh(y);
1 C' v# \ m- E" i1 c# k5 T0 y6 Z4 D9 |57 out[1] = ntoh(z);
8 P, E" y1 j, A1 M58 }
3 z- a# m+ U3 i' U- T0 I/ I59
$ Z/ ~5 ?& W6 d# ~% J( w3 k1 u60 void TEA::decrypt(const ulong *in, ulong *out) {
, q4 ~/ A# E: x( F" o$ J61 2 h8 K0 h6 v" f. e
62 ulong *k = (ulong*)_key;
+ g5 F- a% C+ d( u( u/ m63 register ulong y = ntoh(in[0]); ; n9 ^. v3 f- V( s$ y3 K
64 register ulong z = ntoh(in[1]); , |' _4 ^$ h8 z! U% d
65 register ulong a = ntoh(k[0]);
9 `! v: [9 k% ~2 {$ T66 register ulong b = ntoh(k[1]);
8 W( y0 v: e& y' @) f, t5 T% p8 s67 register ulong c = ntoh(k[2]);
8 E; A" o: s7 P* [7 Q1 l" n6 G68 register ulong d = ntoh(k[3]); ! `- B& a0 {+ }0 T
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ / p/ ?+ l K- z2 }! |" k
70 register int round = _round;
& F: s5 N* ^% H9 c% j71 register ulong sum = 0; ! |' E t5 Q/ f
72
% m6 B9 z- x x/ m8 x7 ?73 if (round == 32)
( D) a/ t7 Z: A5 v74 sum = 0xC6EF3720; /* delta << 5*/ 3 i$ v4 j6 q. u. w* p
75 else if (round == 16)
7 o( ~. Y8 h. A76 sum = 0xE3779B90; /* delta << 4*/
" X P- R+ A2 i7 h2 L! `' j77 else
, F- }. ~ c* d6 l$ I; ]4 S78 sum = delta << static_cast<int>(logbase(2, round));
& |# ^( D8 ~' @ `, R2 k" `0 g+ E79 ( L7 Y' M# I$ b7 W6 `
80 while (round--) { /* basic cycle start */ , T6 N7 F# N* O! ]
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
7 A7 u& X5 B, R82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
! e" x$ \7 G% I83 sum -= delta;
$ b/ g/ M* v, B0 \! m; H0 L/ k84 } /* end cycle */ 1 z" p8 g3 \+ u( @1 }/ D/ C. k {' F5 K7 u
85 out[0] = ntoh(y);
- z, Q/ o( Y& V) \ d2 n86 out[1] = ntoh(z); 5 U, u. [7 e1 W6 e$ h0 ~
87 }4 P$ W6 G0 y+ w7 K8 S5 `6 ~' D
: `3 r) _' K5 p! x# S j
需要说明的是TEA的构造函数: ; X% m6 z, A4 W. v; J
TEA(const byte *key, int round = 32, bool isNetByte = false);
. W- w4 s0 a- d( s1.key - 加密或解密用的128-bit(16byte)密钥。 ! y3 Y, { d4 j5 a5 @9 N& z/ v8 h9 q1 n
2.round - 加密或解密的轮数,常用的有64,32,16。 0 D) V* b6 i' \1 @& k
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
8 y) ~' z* c- x' o- ~- Q7 I! ^. N C8 P+ z1 x6 C
最后当然少不了测试代码: |
|