|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ! s2 C7 K, d* y
2 #include <cstring> //for memcpy,memset , m5 A7 \% w/ a
3
& @% j8 [6 o2 o6 r. I 4 using namespace std;
1 a* l9 k, R1 r$ G1 U" I7 [+ k' z 5 6 d, z5 I9 X# _, ?- ?
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
* H2 b" v. S: G7 C, w m) d3 Q 7 :_round(round) 2 G1 v+ K( L# @& _# N+ N2 _
8 ,_isNetByte(isNetByte) { 4 M6 ~# @" t8 S& n; {+ a1 _: W
9 if (key != 0) % X6 x) K0 |, T' a* ~) \
10 memcpy(_key, key, 16);
5 z& i5 q* k7 T4 F* ]11 else
# ~" E6 ?$ r2 t+ L! I& W2 ]3 C12 memset(_key, 0, 16); S' Y) \6 c4 z- Z& b8 {
13 } , W% g9 }9 u2 o& t \8 Z E
14 : Z3 Q& z& Z* A( n! L
15 TEA::TEA(const TEA &rhs) ( k0 J g0 U/ V! E7 k# P% C2 Z
16 :_round(rhs._round) # X7 o& W/ \8 k! N
17 ,_isNetByte(rhs._isNetByte) { ) S6 H3 ~; V) t" ]" P2 w+ H% ^
18 memcpy(_key, rhs._key, 16);
' a# X9 f1 H% Z/ e# f19 }
; q8 U7 R, y: c6 a' E( K% ] l20
" C1 o, M& q f7 |21 TEA& TEA::operator=(const TEA &rhs) { 5 u6 t/ f) G6 y% X7 v6 }
22 if (&rhs != this) {
% V: p3 X1 d% M23 _round = rhs._round;
9 y, O% U" i3 B9 I0 j' _1 C3 }24 _isNetByte = rhs._isNetByte; / ]& W+ p, @- R( L6 M4 H& @
25 memcpy(_key, rhs._key, 16);
! m0 \. r8 X; A26 } 6 {& h3 x" n' F/ P
27 return *this; " q9 Q! y5 W, Q# p, K
28 }
+ e, C- z X; t! X `29 " k8 Z& W$ t% ]7 b+ d
30 void TEA::encrypt(const byte *in, byte *out) { 1 N2 R3 T: S$ }: A! O
31 encrypt((const ulong*)in, (ulong*)out); 7 |( N$ a- y( t
32 } $ l5 R3 @) ]' U- I- P" x- E
33 6 e$ S6 Q* I* ?6 v; d6 V) h
34 void TEA::decrypt(const byte *in, byte *out) { , ~7 V& w$ p! G
35 decrypt((const ulong*)in, (ulong*)out); D8 n& U$ f# Q2 A# P) [
36 } + L; o' L' \4 C$ v! u
37 ; X' W1 t: b2 v( J+ v. k2 {
38 void TEA::encrypt(const ulong *in, ulong *out) {
* \% T' F( i, g2 s39 9 Y/ v- f+ Z" H) @& P, j0 i
40 ulong *k = (ulong*)_key;
, E( K/ e$ r& q8 W. j41 register ulong y = ntoh(in[0]);
7 v+ t m! e2 X" @% n# r42 register ulong z = ntoh(in[1]); . W" I( @* u. R
43 register ulong a = ntoh(k[0]); ) s8 o; @7 ~. ] `7 u% `$ w; J; d( G
44 register ulong b = ntoh(k[1]); * O. s l2 ?7 x
45 register ulong c = ntoh(k[2]);
: a" N& W+ p' r& g& ?! X46 register ulong d = ntoh(k[3]); ! j8 Z$ y. D3 b& a5 K: d8 D
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ) v0 N! L( B$ c) N9 W& S4 I1 G
48 register int round = _round;
* B/ ^: K: w$ i w49 register ulong sum = 0;
' z5 s9 S( d2 ^ H" f9 r9 ?& B6 H50 + [' {+ N$ O8 \! B' d1 J
51 while (round--) { /* basic cycle start */ & ]* Z! n+ e( ]6 U" X" Q+ A
52 sum += delta; + m8 I( ~7 W7 x Z
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); - |8 k, e0 u7 c; i& C
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); , F( L* N) g* y1 K @( {5 v
55 } /* end cycle */ / x7 j8 }5 U4 B
56 out[0] = ntoh(y);
2 {$ K) B& L) | @7 a( M5 k; R57 out[1] = ntoh(z);
" e' I, x2 R& \: l58 }
6 E. z2 q8 W5 ~! M9 i59
U# X; _1 c5 P& e& g1 o60 void TEA::decrypt(const ulong *in, ulong *out) { . @) h! S% s. K, u R1 @8 o
61
. }& A) B) Q9 T( l* z! A* v62 ulong *k = (ulong*)_key;
7 |) U) k: q$ i' l' l63 register ulong y = ntoh(in[0]); ) F! E9 s# P% N+ G+ H7 O& P
64 register ulong z = ntoh(in[1]);
/ {1 u8 r3 ]* v0 S65 register ulong a = ntoh(k[0]); : U$ @* u/ R- v7 L) F5 w
66 register ulong b = ntoh(k[1]);
( [8 f" i7 T+ d2 J& O7 J, d1 o67 register ulong c = ntoh(k[2]);
, {# ?7 q" V+ U0 o% i68 register ulong d = ntoh(k[3]);
% a8 U1 m8 E: P7 C3 Q+ w69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
/ r Y4 `1 n5 l; W/ p: Y70 register int round = _round; / v4 Z# F6 r5 _# R3 R: M, q% O5 |$ h
71 register ulong sum = 0; 7 C, {! S% \$ D8 i7 H% c
72
+ K4 {$ H* B# w9 Y7 P$ b73 if (round == 32) & k5 Z8 h. }7 ?) z# b! p/ J
74 sum = 0xC6EF3720; /* delta << 5*/ / K4 H1 S( p# b Z
75 else if (round == 16)
6 l) @$ x4 N- l7 F/ Z3 e2 q76 sum = 0xE3779B90; /* delta << 4*/ / B3 ^7 G* K" G8 d; }# M' h8 ]5 j
77 else
0 z' q1 |' P3 n6 R) v: L& h* h- h78 sum = delta << static_cast<int>(logbase(2, round));
6 X5 E9 H% c2 x6 P79 " j9 s* J5 F- H; Y+ A
80 while (round--) { /* basic cycle start */ - Z# s; v y5 D h+ i3 v# p
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
+ P- B! l- p* }4 ]( k5 H82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
5 Y3 n1 x5 |$ V8 }9 z" W/ X) K83 sum -= delta;
4 x2 y0 B3 u! P8 a/ U( i4 D84 } /* end cycle */
# W( C; C, n( w! s! c85 out[0] = ntoh(y); , r1 [5 K: P, R8 j, M
86 out[1] = ntoh(z);
/ z' \" M; `. Y7 j0 t$ i87 }
4 g2 n1 s9 i# K4 O7 w4 r& z1 _
1 U$ z! N# ?0 r6 R) p+ Z需要说明的是TEA的构造函数: % P0 d/ T7 {6 W6 G
TEA(const byte *key, int round = 32, bool isNetByte = false); 7 |# ?, E8 {. M# I I D) F
1.key - 加密或解密用的128-bit(16byte)密钥。 3 b( b5 s- Z2 R o
2.round - 加密或解密的轮数,常用的有64,32,16。 - L. l6 S, X; E- L9 w; J2 l
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
! Z7 b) u" p8 s {7 M
$ K4 o& i2 _# h) M" H4 x6 Z# @% h最后当然少不了测试代码: |
|