|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" . Q# q# X& x6 U
2 #include <cstring> //for memcpy,memset
( Y, H) v0 F& t e 3
5 _% x" [0 g% ^9 R& c" O% m 4 using namespace std; 8 q, [8 B5 b9 K0 h B% v
5
# Q- |: ]% V3 S1 p 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 2 |; A( {3 B2 y) f2 O' h
7 :_round(round)
- R; q3 B( O! G8 j4 D7 {. f0 @ 8 ,_isNetByte(isNetByte) { : A' s8 ]1 I! z+ L/ l
9 if (key != 0) % \, `- ?: D9 C |/ c
10 memcpy(_key, key, 16); [/ N1 Y/ N0 s; b
11 else
0 }1 l0 q( }+ R/ `$ l3 ~) f12 memset(_key, 0, 16); 6 M0 b; ^- b/ o$ ~+ ^
13 } ( ?* S! ^+ I% C7 J
14
+ e' K; t& a% ?- i V15 TEA::TEA(const TEA &rhs)
+ x4 ?9 B$ G0 q: b4 f16 :_round(rhs._round)
# ^ r% j, y1 m: w) j' p17 ,_isNetByte(rhs._isNetByte) {
( h" k9 F$ I- Q18 memcpy(_key, rhs._key, 16); , c' y2 c- z! {
19 }
" e8 e1 V& y/ Y; h( S2 {% l20 5 o: S* B7 U1 g$ I
21 TEA& TEA::operator=(const TEA &rhs) {
. P+ w/ P* @3 I7 {22 if (&rhs != this) { 5 v1 b# w3 k0 ]2 U8 {5 y; [( }# J
23 _round = rhs._round;
/ w7 D% {% v0 N3 ?24 _isNetByte = rhs._isNetByte; 0 K" U1 Z8 M6 \! N* h/ q
25 memcpy(_key, rhs._key, 16);
4 ~2 W( O& Q; e" x% y26 }
J3 J9 z# H7 z: ~) D! ?27 return *this; ' R6 d0 l& n* h6 v0 ~& u7 A1 M
28 }
, X; ?5 Y' x/ u( |7 f( Z29 ) ]# R/ x. W Z& D, J9 o
30 void TEA::encrypt(const byte *in, byte *out) {
@8 z3 w+ i7 O& Z9 N1 Q3 M31 encrypt((const ulong*)in, (ulong*)out);
6 U0 \) M1 ?% }# N6 h$ z8 B& ]32 } 8 h$ \! [- z* w! O
33
- h& h# F4 E2 x2 c$ J( U) A$ b34 void TEA::decrypt(const byte *in, byte *out) { . m* h( c4 z9 ^$ v* ~" W. u
35 decrypt((const ulong*)in, (ulong*)out);
6 @, \. {, ^. K36 } % ^. l4 }7 e" a$ U, {- w
37
0 t. T* d2 }, G% T! K# ~5 E38 void TEA::encrypt(const ulong *in, ulong *out) {
, J0 y5 R9 s1 ~39
& p( c7 Y, K8 M! [+ ]40 ulong *k = (ulong*)_key; 7 h' Y. |# ?$ M: E. |
41 register ulong y = ntoh(in[0]);
0 C# N m: Q9 T- K0 I1 p: O42 register ulong z = ntoh(in[1]);
" m/ |4 t( s/ b43 register ulong a = ntoh(k[0]);
8 w F: _4 G& R* \/ K. w+ p/ o44 register ulong b = ntoh(k[1]);
5 p0 a9 ?5 l* d, p/ S( l% H45 register ulong c = ntoh(k[2]);
: o* ], ^! L v! t46 register ulong d = ntoh(k[3]);
4 o4 d$ R% b8 J47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
* |3 z% j. ]7 M3 V( Y48 register int round = _round; 1 F$ u- ~- n) z3 ^( \7 a }2 Q
49 register ulong sum = 0; ) ?. G; i A) a5 e8 I
50
; m, I) D: E. Q& G; p) y51 while (round--) { /* basic cycle start */ 6 v% V0 J; r7 T4 i8 h
52 sum += delta;
Y- Q: S( i+ A53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); & v9 `+ }, j' n* ]5 l- n! B
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
; T5 ?. C6 s1 k' q* A55 } /* end cycle */
7 `# y& F9 {$ J( y. F* H: X) Q2 _56 out[0] = ntoh(y); 0 s5 N$ `" D! P; z& E) Q
57 out[1] = ntoh(z);
+ `3 r0 {0 M& \- \8 E58 } % q6 Z, z0 _3 V5 F/ m; E2 y9 C0 ]
59
% |! U$ w. r- @3 N60 void TEA::decrypt(const ulong *in, ulong *out) {
7 @0 F6 [: J' g61
* L. `' o+ P- d62 ulong *k = (ulong*)_key;
8 X) H' Z. ~9 r$ C63 register ulong y = ntoh(in[0]); 4 ]' v, _2 e6 W* {+ o
64 register ulong z = ntoh(in[1]);
$ }+ ?$ D" a8 t% t2 a* K4 [* Y65 register ulong a = ntoh(k[0]); 9 J/ t3 J; y+ [6 T! ~0 e6 Q2 n* T
66 register ulong b = ntoh(k[1]); & u& R) h" g* R( A4 F
67 register ulong c = ntoh(k[2]);
3 {! T3 x' g1 Z2 ?68 register ulong d = ntoh(k[3]);
( g& W& i8 j; [# }69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
! o& F0 O" u- `7 _' O70 register int round = _round;
& L6 y6 q5 O. M" p6 E& X8 m, i" M& z# G71 register ulong sum = 0; U8 q; R2 [+ Z8 M9 l8 r
72
4 C6 m5 W+ r; U7 M1 y73 if (round == 32)
0 j; M3 o! f/ }; R4 s% r. u; H74 sum = 0xC6EF3720; /* delta << 5*/ - b6 E- s h- u) }! y+ y
75 else if (round == 16) " d1 {( N8 E E# h$ O
76 sum = 0xE3779B90; /* delta << 4*/
$ {7 m$ b" B7 d5 t* m77 else $ h, w) z4 F$ Z# `" l$ D
78 sum = delta << static_cast<int>(logbase(2, round));
/ J% e! `! c S$ J7 C) K6 U79 % d& |! Q' [) Q
80 while (round--) { /* basic cycle start */ + `# D- J9 m7 ?7 v; o5 J
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
% o1 t, Z5 {& K4 h1 U82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 4 w) z: P& w0 K7 K) Q. X; l- |
83 sum -= delta;
4 `) [7 O* J9 [( _' M S84 } /* end cycle */ & G( y6 u$ q" V% e5 i3 n
85 out[0] = ntoh(y);
# t% g% d1 Z! R8 p86 out[1] = ntoh(z); 3 w8 [: G; e( k) g
87 }
, k. r4 V0 r- v9 n. r8 ?- C c8 E- J# }
需要说明的是TEA的构造函数:
. @" _; z; e6 D5 H5 fTEA(const byte *key, int round = 32, bool isNetByte = false); 9 u8 e P& a2 y: O3 s
1.key - 加密或解密用的128-bit(16byte)密钥。 9 i8 J0 e/ k* w! h& T& ~5 f, K! A) Z
2.round - 加密或解密的轮数,常用的有64,32,16。
# ?% G+ c& _( o2 B8 ~' }3 T) i3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! & ~6 O. z4 z4 X6 S; G8 Y" K$ S& t
2 G% d2 V; y9 N4 Y9 f! I8 E I最后当然少不了测试代码: |
|