|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
, C/ |: z3 [6 v+ V( v5 d 2 #include <cstring> //for memcpy,memset
( [; k7 Y. g% s9 G O 3 + S8 V/ q8 ~6 A! `3 U9 Y
4 using namespace std; ) Q( X$ m" H a
5
( ~1 R; e; y' n8 ^" b" J* p 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 8 t: s. J, ~+ m) m0 \* J/ `6 _( O" @
7 :_round(round) 1 K8 {: b$ ~5 ~& v0 J0 O5 H- K
8 ,_isNetByte(isNetByte) { - B+ @" B# F+ a5 U4 M
9 if (key != 0) ( B- [+ _5 ~4 u$ f
10 memcpy(_key, key, 16);
: J/ ~6 ^! @+ Q3 S11 else ; R+ H) Y' B5 E9 h8 v8 b" V
12 memset(_key, 0, 16); 0 T# [4 A( B7 m* n$ v
13 } ) U$ S7 ? q, W# A0 Q9 ~
14
5 w6 }; i# \% z s: h+ l3 G3 w15 TEA::TEA(const TEA &rhs) ) W s! |0 {' L! K x! L
16 :_round(rhs._round) 3 l: v; h9 Y0 Y. H
17 ,_isNetByte(rhs._isNetByte) {
: Q5 y/ `+ ~# B' G, Q x' E' U18 memcpy(_key, rhs._key, 16); / S" v" b: c+ v. J$ I
19 }
# M6 k W, H5 H: U20 # r* d+ @4 U6 b! H* e+ ^# Y- s
21 TEA& TEA::operator=(const TEA &rhs) {
' N% R0 y# s. a q1 g* C3 e' J22 if (&rhs != this) { ( x) C& ^* Z9 [- I
23 _round = rhs._round; 8 ]( ?$ H* o7 J: n0 @" R
24 _isNetByte = rhs._isNetByte; - h1 t: K& k8 ?4 ?& Z% D, V
25 memcpy(_key, rhs._key, 16);
% L4 a" m$ H8 ~26 }
; m) U- W5 S& R27 return *this; $ U" e+ i* G- a
28 } $ U6 h# |1 Z0 h6 g! d
29 $ V3 {/ R. L- L4 [* z3 g9 w
30 void TEA::encrypt(const byte *in, byte *out) {
) B3 r7 U- a8 f! h, M31 encrypt((const ulong*)in, (ulong*)out); 3 x/ t5 v5 s0 @
32 }
/ _, G/ R+ D" g# x. {+ q33
+ s) @- z# x) k# e G" @1 l1 h34 void TEA::decrypt(const byte *in, byte *out) { . p) B/ d. t* F/ Z" i, ]8 V
35 decrypt((const ulong*)in, (ulong*)out); ' J6 K8 l, R& c/ _7 v# Y
36 } + C$ d1 l% B7 R# P! H
37
% R* u# l0 A% s+ J) S38 void TEA::encrypt(const ulong *in, ulong *out) { + ^% ]+ H5 {; U# H
39 6 }2 N" p4 c, w
40 ulong *k = (ulong*)_key; 5 g8 C! U9 r5 f* w5 [+ W
41 register ulong y = ntoh(in[0]);
8 x4 O# t4 }. Q5 i B42 register ulong z = ntoh(in[1]);
7 K0 r) L0 f/ m! c& V43 register ulong a = ntoh(k[0]);
: m/ h: a5 s+ n u+ }. ?, \& v44 register ulong b = ntoh(k[1]);
$ w" b' N& _0 P9 m0 j3 v. w45 register ulong c = ntoh(k[2]);
- F8 X! N, X6 `% h46 register ulong d = ntoh(k[3]); 9 C% z1 z9 X! J4 K1 O5 P. y5 [) W; o
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ( [3 w% B* j7 i( h
48 register int round = _round;
0 O2 R* ~, M; l0 f5 `/ o% ^49 register ulong sum = 0; 8 ]3 y8 m/ g3 t) C) K; G
50
5 J6 `7 m$ U! n! e; ~2 ]51 while (round--) { /* basic cycle start */
: r+ b3 J% W4 [& j52 sum += delta; ; C' P8 V4 P( b2 T5 l* T
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 2 T d! E3 Q! j) N' a8 z9 G J
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
4 C8 M6 o6 u4 U' ~2 [& c; f55 } /* end cycle */ 5 h% I/ a8 @3 }: Q2 G
56 out[0] = ntoh(y);
5 Q. F- [; K# A1 f5 I. Q57 out[1] = ntoh(z);
7 o, U4 P6 m, C# D/ D( p58 }
* q) ~) ~! X4 f6 A( H& D59 " M* ?5 z; g/ y3 J' Y- D$ a7 Z& N
60 void TEA::decrypt(const ulong *in, ulong *out) { 6 p' t1 q3 e5 h/ v T# f
61
; P6 u3 H. e. F" A62 ulong *k = (ulong*)_key;
5 n3 h; j1 R7 x/ v5 R% N2 x/ \% ~63 register ulong y = ntoh(in[0]);
) q A, U( O# \64 register ulong z = ntoh(in[1]);
6 ^ C* R9 I& u) V65 register ulong a = ntoh(k[0]);
) x% m# l7 m1 S% \9 I2 o+ t66 register ulong b = ntoh(k[1]); ) q) f, c5 m8 p3 p
67 register ulong c = ntoh(k[2]); 9 G5 H1 D, w- A; ~
68 register ulong d = ntoh(k[3]); , \5 o4 l! o' S
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
1 c S) R2 M6 W) D3 T( i h70 register int round = _round; % t% S9 y- Z. I+ n; { G5 X
71 register ulong sum = 0; , D! I* R" K( n1 S
72 * r2 ~/ h; B/ ?1 d/ u% K
73 if (round == 32) 6 Q& v. E$ X% C" P0 s2 Q4 u5 A6 Z6 ]
74 sum = 0xC6EF3720; /* delta << 5*/
" z9 ?% r& s( Z5 U8 P& x! j75 else if (round == 16)
7 B6 g$ T8 B6 s7 }& M u( `: T76 sum = 0xE3779B90; /* delta << 4*/
7 h4 x: Y D9 [" n; g) z4 n. o77 else
, J: m% z' m: _78 sum = delta << static_cast<int>(logbase(2, round));
5 m& t @6 X M0 G' Y79 7 s+ P7 Z4 ?7 h F5 m' h, u
80 while (round--) { /* basic cycle start */ ' y1 _; X! Z5 M
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ' ?% [1 U7 K8 a" x1 j) c" A
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
4 s8 C0 T0 P; W; @7 E% g83 sum -= delta; ) a- S% x: M' Y5 Z$ r
84 } /* end cycle */ . _: z3 C! N- S5 d, a+ Y9 o
85 out[0] = ntoh(y); * s t. c- \5 z4 T) P k" J
86 out[1] = ntoh(z);
0 w+ {% _. }. M87 }) q1 E4 E3 v( U9 {- S, e9 g3 G9 z
7 P, i/ b% f3 a; g( e& d5 y6 u& |
需要说明的是TEA的构造函数:
; `3 n+ O, H8 M, STEA(const byte *key, int round = 32, bool isNetByte = false);
8 d& j: C2 r2 [0 T1.key - 加密或解密用的128-bit(16byte)密钥。
- k$ M; u. V4 w2.round - 加密或解密的轮数,常用的有64,32,16。 . a4 J/ B9 A/ P7 M. H. }
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ) R6 b2 s; c5 V2 D& @" n) X' i* q
; L0 W7 c, ^! Z( D8 @# y( Z$ H最后当然少不了测试代码: |
|