|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 3 J+ t0 t2 n) Q Z8 p$ O2 L' K
2 #include <cstring> //for memcpy,memset
% b- K2 V- \0 H) c" o/ Y 3 % b* s% J, S7 s( K
4 using namespace std; . O+ r3 ~5 g2 z/ N* e* U6 P3 g
5 2 X; x; }. j# ?) |8 D4 z
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
% _) j0 ^* G6 k1 i$ W& Q 7 :_round(round)
8 g) ^ i* m7 G: t 8 ,_isNetByte(isNetByte) {
4 m9 P* i% {, O1 @3 J 9 if (key != 0)
3 _% v% H3 W8 }" b/ }10 memcpy(_key, key, 16);
0 e! N6 x8 v! {5 \. }11 else
. _6 y/ u- o' _7 I* v% |12 memset(_key, 0, 16);
! I9 ?2 D" r* \13 }
' C3 _! O. f7 i6 i14
! [+ [8 P* ?+ Q. o s6 H15 TEA::TEA(const TEA &rhs) 8 d! R O2 M* R+ ~$ p
16 :_round(rhs._round)
' Y: W# g) ^- L. ?, a7 E# K) j, \17 ,_isNetByte(rhs._isNetByte) { 2 T$ ^/ F. Y) v
18 memcpy(_key, rhs._key, 16);
% s' K& ?& S; ?" w19 }
* D1 ^. ]2 d! p4 k20
0 f4 @" z, N# d; F2 p: i$ g5 I! F21 TEA& TEA::operator=(const TEA &rhs) {
& l( z" _ u+ Y0 B+ X _' Y22 if (&rhs != this) {
; F0 M' `3 Q0 y8 ], N! c23 _round = rhs._round; $ I( \# l, q2 l _# R
24 _isNetByte = rhs._isNetByte;
; C+ v/ }( K; H1 S25 memcpy(_key, rhs._key, 16);
) g) L9 w+ I" X L2 |! F26 }
6 T5 q5 ^; K# J; ?- R27 return *this; % c) |" |5 L! I
28 }
+ q( k7 Q$ [ `. B29 8 |, F* `( `: I' C! L+ J
30 void TEA::encrypt(const byte *in, byte *out) { , c& D/ ?0 x9 H
31 encrypt((const ulong*)in, (ulong*)out); $ \& V* e% k) v7 q L% J
32 } 0 ]% r4 Y! |2 A) y5 e- ]: |
33 C$ r9 P- ^0 F3 S
34 void TEA::decrypt(const byte *in, byte *out) {
5 m' E7 a5 j% g' a35 decrypt((const ulong*)in, (ulong*)out); % x) J: U9 N6 P
36 }
0 s/ v) t* C; U S) ^8 S37
* C4 }& X* q+ A) f' ~& L38 void TEA::encrypt(const ulong *in, ulong *out) { 0 i) F0 T( I6 X# N& G2 B
39 - n6 V, ?" }4 [1 S
40 ulong *k = (ulong*)_key; * y9 [ Y, d- \- U% E. q
41 register ulong y = ntoh(in[0]); 2 A7 d- p7 s6 {% x% W: R
42 register ulong z = ntoh(in[1]);
( H3 j; j3 L9 o" V43 register ulong a = ntoh(k[0]);
% B5 R# h) R; f7 k. ]. }44 register ulong b = ntoh(k[1]);
, X. x* a3 t! P1 Q3 O45 register ulong c = ntoh(k[2]);
2 p0 M1 p3 ^5 U4 c0 [5 b46 register ulong d = ntoh(k[3]);
3 c1 I7 T1 \6 \5 ]" o: {47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ * E6 h) J' F" A2 F* c
48 register int round = _round;
3 m0 N% R. f% g6 e49 register ulong sum = 0; 7 F1 g* j6 N" N, B
50
& g8 L7 M2 y9 @: P7 u51 while (round--) { /* basic cycle start */ # X& } d; R: z9 ]% l) M
52 sum += delta; # m( C& o: ?3 h
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); & J4 Q: E: W# K
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); " G0 M) f% m8 C7 N1 n5 K9 t
55 } /* end cycle */
% o$ I/ q& A, p/ S! g/ h* V; E9 k56 out[0] = ntoh(y); 2 k& _& q3 M- t, Y8 v
57 out[1] = ntoh(z);
$ J0 B5 v4 s5 _7 `1 ]4 d: I6 w" j58 } 5 ]: V+ H0 |9 z+ ] v
59
1 B- C L8 w `/ b( \' V( [60 void TEA::decrypt(const ulong *in, ulong *out) { & O b8 {" G4 d2 y: _5 y Q, T g
61
. B1 S% z6 Y# M) M7 e) v62 ulong *k = (ulong*)_key; 1 Z( \9 H7 ]; r! E! M+ n b2 C
63 register ulong y = ntoh(in[0]);
( b$ E3 U- a! s ^64 register ulong z = ntoh(in[1]); # d3 Z4 h6 r$ k/ ?. ?" [# ~
65 register ulong a = ntoh(k[0]);
5 V D& ]- x5 O) L6 X66 register ulong b = ntoh(k[1]); 4 G6 m# H( O+ F) C; Q" T( \# I
67 register ulong c = ntoh(k[2]);
/ n T- N2 Q: {8 r9 h" @* j& ?- }68 register ulong d = ntoh(k[3]);
7 d- o, H5 v$ @% h3 j69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ) ~9 u$ {6 K+ x! ]
70 register int round = _round;
2 K( r. U+ [0 D6 }9 R6 K71 register ulong sum = 0;
8 O! T# n: x! N% u! p2 J72 " g0 N) z: ?/ r. p
73 if (round == 32) 2 o; j+ P) j0 ]9 {, v6 L
74 sum = 0xC6EF3720; /* delta << 5*/
# x7 a) X# z, C- ?$ T- v, s1 u75 else if (round == 16)
' r6 N9 U4 v) d0 {$ H7 a76 sum = 0xE3779B90; /* delta << 4*/
: ] |2 b! e. b0 D6 B77 else
; z! `- c6 d [6 }! \8 Q78 sum = delta << static_cast<int>(logbase(2, round)); 8 g. }3 Z' N4 Z" A! @4 Z' d( C0 R
79
+ `: n7 S4 n Q8 T5 Y& K: y80 while (round--) { /* basic cycle start */ " L$ S- F P/ {8 W- U( P
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); # [* V; u" e" B6 T" g
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
- J$ f" ?! C! N7 W+ F% M- v) B; I83 sum -= delta;
1 v( {, s5 ]" o' ?- _84 } /* end cycle */ . {2 X# V& C7 P7 ~# X) a
85 out[0] = ntoh(y); 0 O6 T0 E) E! |" z9 R) C
86 out[1] = ntoh(z);
& ^. S; {: _; K% N* v: ?87 }
& z# y! v3 X3 n) l, m' C
; V5 i6 Y* n& L6 U需要说明的是TEA的构造函数:
2 v9 w& n2 R( gTEA(const byte *key, int round = 32, bool isNetByte = false);
7 u I, J- ], m5 E7 O1.key - 加密或解密用的128-bit(16byte)密钥。 $ R5 z+ R9 y# ^# e/ C6 ^
2.round - 加密或解密的轮数,常用的有64,32,16。
6 W3 S n' Z$ w/ `: }3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
* O# d5 |# h5 b9 j) M' S
# V4 b0 D5 I( z/ i% R7 H最后当然少不了测试代码: |
|