|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
" o- _) t0 X, b. j# U2 w( S 2 #include <cstring> //for memcpy,memset * G/ y6 Q/ J% m0 l( a9 L5 _
3 0 H4 e) v+ s8 c
4 using namespace std; ( ]! H- I" W- x- |; S: C! I
5
\% V5 R# e! d% ] 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
4 ?' {% ]5 T6 a 7 :_round(round)
6 t) R/ e8 A% i2 K& D2 v0 l2 }% W 8 ,_isNetByte(isNetByte) {
6 D0 r# j$ |8 }; b" M6 M 9 if (key != 0) ; B" t9 {8 @( r" e9 G7 U! Z9 z! k
10 memcpy(_key, key, 16); ' r( n: P t0 G# D. u
11 else 9 Z! E8 \3 c6 d+ \3 x
12 memset(_key, 0, 16);
' N: s* ]$ L/ u& U0 n13 }
* l. C8 l3 |1 i. ]1 c4 I2 p14 4 y. \ Z1 U# ^0 B' E2 l+ h
15 TEA::TEA(const TEA &rhs) ; U1 Q8 y7 J, T" n" U
16 :_round(rhs._round) ! g2 H& z& w# [* w
17 ,_isNetByte(rhs._isNetByte) {
/ \3 S+ m: Z1 a18 memcpy(_key, rhs._key, 16); 5 G" f' R7 a1 n' j/ b9 K$ C
19 }
4 d2 b) h; D; V0 |" P$ A, D20
4 x" [" c: k! G% }+ Q1 [21 TEA& TEA::operator=(const TEA &rhs) { 2 {- Z8 q+ M" l+ w* Y
22 if (&rhs != this) { 6 x m0 M" c' U/ {
23 _round = rhs._round; # E& A: Z" {. q. H
24 _isNetByte = rhs._isNetByte;
1 \8 h* Y& _& _. ?; j r25 memcpy(_key, rhs._key, 16);
- [% N5 [: d2 }. o% |; v8 L26 } ( W1 M; x6 ^) B) ~
27 return *this; % ?7 c: M9 C& A2 x
28 } $ s: E* T1 b0 p8 i* |7 i$ _
29
! P( V( g4 @1 l# W) l" h8 Y, n30 void TEA::encrypt(const byte *in, byte *out) {
8 |9 R3 ~+ S" Y, P5 r7 P1 f- W31 encrypt((const ulong*)in, (ulong*)out);
1 @* w" b' J$ Z32 } ; w& e% b; ~+ i X8 n0 r! k
33 4 M/ I3 q' I0 b: m# K; I0 w
34 void TEA::decrypt(const byte *in, byte *out) { % Q5 f2 c1 i# I! e8 o! T5 X) h
35 decrypt((const ulong*)in, (ulong*)out); 7 K. l/ C+ ^3 P6 `( h% M9 x/ ~
36 }
) c' {. u$ w0 ?7 V37 3 J) A) x/ r8 F* v- O7 K
38 void TEA::encrypt(const ulong *in, ulong *out) {
6 s; T- X8 v# S. m39
. z9 S$ y& B( }6 b; I40 ulong *k = (ulong*)_key; 0 s; c6 W: Q) c/ q9 O
41 register ulong y = ntoh(in[0]);
3 c0 R% O0 V& s1 n+ O42 register ulong z = ntoh(in[1]); % u9 w4 D8 [; v' [
43 register ulong a = ntoh(k[0]);
. ^! T% y1 L! c44 register ulong b = ntoh(k[1]);
; J7 R G+ `6 G: M9 `0 g. T45 register ulong c = ntoh(k[2]);
# T$ Q) }: n1 O% c& c46 register ulong d = ntoh(k[3]); 9 y6 {$ _/ {' j' |5 Y
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ - `& w! I; E3 j! a: a; E' [, u
48 register int round = _round; 8 U. l) M% z6 q# H! C! |
49 register ulong sum = 0; ]4 _3 k+ n4 P2 f' R& a; N: {
50 3 s( b' M; ^3 t
51 while (round--) { /* basic cycle start */ 7 h3 {$ i6 \# @2 r
52 sum += delta; m* u( B5 d2 a. H: h& X2 W
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
: b* ]+ R/ A3 w4 o/ x9 a2 ^54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); r8 o" d+ g7 H. G# @1 S0 H4 P
55 } /* end cycle */ 5 a1 j6 \) {7 w3 U
56 out[0] = ntoh(y); $ M! \# ^2 Y5 B2 W1 t1 c. f# R/ ]
57 out[1] = ntoh(z); 3 S' x: X3 y4 p
58 } 7 K7 C4 Y' ^% B
59
' x& {) F+ n/ E, w, c+ J60 void TEA::decrypt(const ulong *in, ulong *out) { ( G6 ~3 A/ E) e
61
# @" T: T. L3 E" v62 ulong *k = (ulong*)_key;
3 V0 e% E9 c$ O, U9 |# |63 register ulong y = ntoh(in[0]); - o! {3 }# A6 H2 X/ ]
64 register ulong z = ntoh(in[1]);
( m4 Z j7 H- I: |2 o2 L2 u65 register ulong a = ntoh(k[0]); 8 Q4 {7 q- B; i2 M
66 register ulong b = ntoh(k[1]);
# P7 R. j+ o9 t( r+ \# K: J9 p67 register ulong c = ntoh(k[2]);
4 {& u9 h0 a0 U8 g; ]68 register ulong d = ntoh(k[3]); ' W' m" Z; I% k% A6 Y+ ~2 d
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ % F" r4 n2 A( ~6 }/ O! N/ H$ ?" E
70 register int round = _round; * G9 A4 t: i# b& g: _- F
71 register ulong sum = 0;
5 O) b8 Q5 K0 L; A+ J72 & D, A! E: g6 k6 s+ d4 {$ n
73 if (round == 32)
% m9 B5 E! Q3 e74 sum = 0xC6EF3720; /* delta << 5*/ & B, g' o: H. O4 q9 K6 N
75 else if (round == 16) * T( s4 }' H/ q
76 sum = 0xE3779B90; /* delta << 4*/
$ i* e* {1 t2 \9 F$ X V77 else 2 c7 R* {' G3 U0 r! L a
78 sum = delta << static_cast<int>(logbase(2, round)); : R' }4 Y% r- Y0 Z* d1 h
79 6 ]& t& b9 b: Q% }
80 while (round--) { /* basic cycle start */
1 Q/ t5 _! k4 f3 S4 Q8 r9 V% h81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
. T; j9 z x! Z9 a82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
* W2 U9 Y6 F3 w" P' t' Z83 sum -= delta;
% b" e; _2 U9 w" H84 } /* end cycle */
) C# M) Z6 ]& ]) ~) n85 out[0] = ntoh(y); ' y/ o5 ^% Z' z/ H6 _) v: b9 I& ^2 r
86 out[1] = ntoh(z); , V: {7 D6 r4 j0 l
87 }
3 A2 o, \6 X- d9 B9 ^: U# ?
( L5 d- _& n% {4 {( M5 E5 X需要说明的是TEA的构造函数: 5 a. Z0 T- w: V# _; l: k; t' }
TEA(const byte *key, int round = 32, bool isNetByte = false); , l0 ]% } f# T$ U, l/ X- _
1.key - 加密或解密用的128-bit(16byte)密钥。
S# l9 K& N4 r/ _+ i+ c& }/ Y' Y# v2.round - 加密或解密的轮数,常用的有64,32,16。
8 L% @5 a$ o9 N* F- P' d: r2 ?, ]3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! $ a2 W( G7 ?3 `0 j% h
, E+ n9 j! N+ k* G5 _3 M/ a最后当然少不了测试代码: |
|