|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
6 h. F8 ?3 D5 k' P 2 #include <cstring> //for memcpy,memset * K0 G5 n3 T6 t9 i6 r2 E
3
8 o# {# \' k2 I p 4 using namespace std;
8 k6 o [9 u; r3 I$ f 5
/ m3 d" w% d' w$ }1 Q 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) / G& _( B$ L4 T0 ]- _
7 :_round(round)
7 e9 {) S7 H, Q 8 ,_isNetByte(isNetByte) { % b O% p" L' l! J* P5 F$ O; a' ?
9 if (key != 0)
5 e( z( |$ Q! W; \7 Q. K4 G10 memcpy(_key, key, 16);
! b6 |+ S9 M7 L, ^5 U9 n# \, J11 else & {: D% n0 M; e" Z4 D p
12 memset(_key, 0, 16);
& J" q; Y' U0 A; m13 } 7 A' c! \% I4 N f. u' ]
14 . y1 z- q) E, v
15 TEA::TEA(const TEA &rhs) 2 m H4 ^9 t8 F5 d# z
16 :_round(rhs._round) 5 Z- z8 j0 l1 S3 m0 J, U1 U/ x3 b
17 ,_isNetByte(rhs._isNetByte) {
% y; d8 k7 m) b: I18 memcpy(_key, rhs._key, 16); ! e. J F0 v+ M2 T, C
19 } ^" n3 v4 V3 e7 F1 O L
20
$ A6 w. S- R, `8 S x' ]21 TEA& TEA::operator=(const TEA &rhs) {
* F/ Y, I9 q5 M/ ^6 a5 `. ]3 K5 z22 if (&rhs != this) { " c% v' e1 F& o, ~$ l; t
23 _round = rhs._round;
9 K0 F' h& J4 |- R/ k+ g) w24 _isNetByte = rhs._isNetByte; 8 B6 }2 @# q& ?" A0 Y$ d
25 memcpy(_key, rhs._key, 16);
5 ~: |4 Y) D- U+ F* H+ c! ~26 }
, ?, e- h/ i2 e$ @$ w27 return *this;
! ^% `( [) l) e1 j2 W( p, E& L* Z28 }
: W' \# ]4 H x* p0 W0 n& s, \29 $ {9 W: j# P, |9 H# O) u
30 void TEA::encrypt(const byte *in, byte *out) {
( a+ } ]5 l. {) s' {' A31 encrypt((const ulong*)in, (ulong*)out); / b) W. F* J( _; K. ^# F
32 } ' K; ]8 G! D. |/ @: s* F; X
33
" e+ y! h5 {; a S4 U34 void TEA::decrypt(const byte *in, byte *out) { " A6 J+ }) s. Y
35 decrypt((const ulong*)in, (ulong*)out);
* p4 I/ H9 M" A" W36 } 6 I8 L% v6 o3 y* S! R& k! T! P
37 * P* s: K) @! H3 b
38 void TEA::encrypt(const ulong *in, ulong *out) {
) f ~7 k% t% F) b, i39
1 R5 U8 t8 d1 D* t40 ulong *k = (ulong*)_key;
" i& q+ N( B' Q/ o9 t' S9 C6 {/ c41 register ulong y = ntoh(in[0]); G o, [( Y y2 v1 {. w
42 register ulong z = ntoh(in[1]); 7 X+ b0 e' v. M* p& ^3 W
43 register ulong a = ntoh(k[0]);
1 f3 Y& G1 ~- w" T- b/ s44 register ulong b = ntoh(k[1]);
4 c/ }4 [3 R; ? F5 Z7 U. p45 register ulong c = ntoh(k[2]); 6 }1 ?: m% y. c5 g% \
46 register ulong d = ntoh(k[3]); % w5 P% U+ h- d7 R( d
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
$ S' J# x) v% R' M& s( r. |48 register int round = _round; - S( m. r" V' a8 z/ U/ _( ? G& a
49 register ulong sum = 0; . l1 N& X/ |* E6 F |
50 - y/ a+ @. V0 }/ _9 p1 m
51 while (round--) { /* basic cycle start */
* b. O) P, N$ J6 }* r0 I8 @52 sum += delta; $ V. p* w ]" S' o. C" k& J
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); . v4 O" t: y9 |$ d; @0 w
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
1 d- t( [% q+ B1 f1 \9 J; m55 } /* end cycle */ 9 N& f, V9 v+ x R- U0 |. a
56 out[0] = ntoh(y);
# D; }5 [$ T3 h( B) B57 out[1] = ntoh(z);
9 F/ c$ ^) F. m% a" g6 y58 } ! f8 l5 o( w( r/ v9 E' O
59 7 o, u8 {( v a/ H/ I- w e6 @
60 void TEA::decrypt(const ulong *in, ulong *out) {
2 M2 y3 j, l- N1 _# Y61 ' V* M5 V8 g5 T+ D
62 ulong *k = (ulong*)_key;
! M) H. }4 `7 w! w* _7 m63 register ulong y = ntoh(in[0]);
! s m0 s$ g. Y; e64 register ulong z = ntoh(in[1]); 8 ]5 C( x' E, k0 |; t; P
65 register ulong a = ntoh(k[0]);
$ t4 c* c, X! z0 k! }66 register ulong b = ntoh(k[1]);
8 A8 n4 J! O& i7 O8 {67 register ulong c = ntoh(k[2]); ! k7 l: y( c4 a" Z6 h" [
68 register ulong d = ntoh(k[3]); ; J) _; B8 e/ O' v( [8 c3 E4 U
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
% M. k2 ^) C. D- D/ D7 o70 register int round = _round; ) B6 K3 B' T9 o0 i, I
71 register ulong sum = 0;
- V) _% m, r9 K6 @( ~+ y72
" w2 F" k1 M1 M: e9 d. a- `73 if (round == 32) & u. T& H# r6 p8 O2 ~
74 sum = 0xC6EF3720; /* delta << 5*/
. D7 N2 S0 v1 `1 H* B9 q) g. {4 e75 else if (round == 16)
) M. s' C# `4 Z4 E0 n$ t4 p6 E5 Y76 sum = 0xE3779B90; /* delta << 4*/ 1 G" Q/ Z e: C9 y1 y6 {
77 else 9 t ]: `& w' Y% v) r
78 sum = delta << static_cast<int>(logbase(2, round)); ( U: w5 n$ |, n2 J, T# }. m( j
79
: }1 N h- ]) ~( U4 g2 [80 while (round--) { /* basic cycle start */ ; D4 y3 x+ s' y. u
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
# ~% g: t! p% |/ |6 v- \82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
' z* V k6 X" G9 o x5 J+ w83 sum -= delta;
1 R" @& w: K3 _ w9 h2 a84 } /* end cycle */
. Y+ _( Y' m4 h0 S/ ^85 out[0] = ntoh(y);
$ U- G+ [5 W+ G H8 {0 r86 out[1] = ntoh(z); : g( W7 J" O+ c
87 }; v6 y0 Z9 ?2 z% S5 |. E$ R
" J' V9 U, K/ p5 o4 h
需要说明的是TEA的构造函数:
( D7 T/ {) f2 cTEA(const byte *key, int round = 32, bool isNetByte = false);
6 D" T2 {9 o3 t) U6 s) Z% V2 f( K1.key - 加密或解密用的128-bit(16byte)密钥。
8 @# O! h8 f7 e0 R$ I8 _2.round - 加密或解密的轮数,常用的有64,32,16。 ) M* D- W+ M. q7 G
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
9 [0 j0 d; x y
( f0 R: P1 t( W# _, \, A最后当然少不了测试代码: |
|