|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
' ?/ k1 w( G9 O- X, i4 w 2 #include <cstring> //for memcpy,memset / k- N% Z# }9 s+ u
3 9 w2 |" k2 o& O
4 using namespace std; 2 h" y* v9 W6 m0 G- a6 s0 Q/ O
5
8 B, }, y* l O$ ~ X; t( Q; u 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
- @! o' j5 z! B3 c' s" \% A 7 :_round(round) " q0 V: s! g1 p9 W8 p& X$ F
8 ,_isNetByte(isNetByte) { 0 R& _1 K/ b# J! Q
9 if (key != 0)
0 w! r( B9 E+ D10 memcpy(_key, key, 16);
7 ^0 U: q( |4 F. U+ l11 else
! n$ k. M2 B4 d: i& G( ]12 memset(_key, 0, 16); % G" R6 ~# h" X8 R5 [) y; N
13 }
$ E3 ^( n# [: @4 M, {* U6 x14
* ^; m g& k, p7 |) `15 TEA::TEA(const TEA &rhs)
6 i# k! u/ C/ Q# K+ O8 [. f6 |16 :_round(rhs._round) # J7 [& C2 ]9 Q; W; w% z4 {* y
17 ,_isNetByte(rhs._isNetByte) { $ j" g% u! t1 J/ S) \9 q. L
18 memcpy(_key, rhs._key, 16);
: R" O* l9 I( Q u% v$ W4 d8 D19 } 7 p' d4 e" {: b: X
20
% i* ^% m; [9 _/ v) J0 a21 TEA& TEA::operator=(const TEA &rhs) {
& |* } X8 J' h! h8 M' v22 if (&rhs != this) {
# q4 s, f, p% x; y23 _round = rhs._round; 1 K1 A: }4 a( e) e: b, q/ a
24 _isNetByte = rhs._isNetByte; [7 F# M( E/ s& d2 d
25 memcpy(_key, rhs._key, 16);
- X- N0 _: j/ p* g0 m9 Y0 N26 }
; x" \- y) L7 b* _; L- w27 return *this;
! k' A5 a5 u f+ l& N28 }
8 E" i' ^# {! S. A: ~5 m& x( s i29
5 K5 m' ? [/ C: P+ k% s30 void TEA::encrypt(const byte *in, byte *out) { : r% e/ Q5 v1 g, Q _) Q" P
31 encrypt((const ulong*)in, (ulong*)out);
; X3 i5 V. U5 p1 p$ } r' O32 } 0 A0 k2 p! \' G6 E* P% r7 W
33
, d# s; B% w" N( b; D* Y34 void TEA::decrypt(const byte *in, byte *out) {
3 c3 O# F3 f4 R/ Z, |- \4 j" ~35 decrypt((const ulong*)in, (ulong*)out); 7 R S( |+ I. D1 s7 v( ~3 g
36 } ' _( B9 t# m1 [# w( N4 i
37
, D8 c" w0 g7 A38 void TEA::encrypt(const ulong *in, ulong *out) {
, y( c# n% i( Y4 F4 J39
2 a) y3 h9 p4 H! z( M4 E' M40 ulong *k = (ulong*)_key;
4 p+ C9 r' X( v& [$ d8 e( B3 l. t41 register ulong y = ntoh(in[0]);
' }" P; P( q' T: Q42 register ulong z = ntoh(in[1]);
! X* _+ {$ H' p43 register ulong a = ntoh(k[0]);
, `, Y; [! n- ]( y44 register ulong b = ntoh(k[1]);
$ `6 d3 _( s& X w% H45 register ulong c = ntoh(k[2]); ) y" F2 J1 q( @" Y$ L
46 register ulong d = ntoh(k[3]);
+ G6 Q( o, G0 o47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ % Q; M' v9 A% t ~# x
48 register int round = _round;
3 l9 w; g; a) _8 i+ H49 register ulong sum = 0; 8 K0 V3 w4 Q: U! F; [) I( v; ^$ i
50 6 f& M6 N! G9 T8 h
51 while (round--) { /* basic cycle start */ 8 b% n7 z& P+ S$ m }
52 sum += delta;
" K* l: i* y' R53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
( m- t& `- ^$ |! g6 w54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
' F6 I" e. M. O$ V55 } /* end cycle */ + m2 Z; d0 }* H0 P6 G! f$ y% U
56 out[0] = ntoh(y);
; b& ^: f1 \; \& m1 K* M57 out[1] = ntoh(z); - q5 j+ s9 V6 z+ s, F8 {0 ]
58 } : w+ A! B5 k) v/ _
59
. m" r- r$ M1 a, R0 w60 void TEA::decrypt(const ulong *in, ulong *out) { $ B" t o7 m, H" m) c
61 # |+ d7 i4 m* j: ?; F6 d& T
62 ulong *k = (ulong*)_key; : ]4 v2 [( t2 C f) J. q
63 register ulong y = ntoh(in[0]);
/ ?% M: l, t7 C8 e, E64 register ulong z = ntoh(in[1]);
2 ` {+ K) e/ s: G65 register ulong a = ntoh(k[0]);
# t6 g7 y; w0 |" }" C66 register ulong b = ntoh(k[1]);
6 F8 D: z$ B7 X4 \5 l* r. Q9 X67 register ulong c = ntoh(k[2]); % D. u0 d+ a0 d" o% S6 `" l
68 register ulong d = ntoh(k[3]);
}4 g5 n; p$ \0 z( d8 E& H: O l69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 5 t0 m) a' W O% ?1 I
70 register int round = _round; 7 |1 l3 W9 J& B
71 register ulong sum = 0; ; m$ F: J; s2 i% Q+ @( S8 ]2 X
72 1 Q* C/ o4 l4 N- n9 }# t
73 if (round == 32)
( [, q* v9 K V7 o( {74 sum = 0xC6EF3720; /* delta << 5*/ . n" q$ c1 b w6 }
75 else if (round == 16)
3 v5 W( y& N7 }: Z" |76 sum = 0xE3779B90; /* delta << 4*/
; ?* j3 ?1 O& z$ @: g77 else 4 ?4 k8 e0 h( z5 N- b4 p
78 sum = delta << static_cast<int>(logbase(2, round));
: N6 F4 }5 o1 O A3 G$ D( L79 + y4 M: R! f* _
80 while (round--) { /* basic cycle start */
5 p8 ?5 f w% w81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); , o& L2 X1 h3 S6 A- F
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); $ L% C! \6 ]& k7 J ~- W
83 sum -= delta;
2 Y% c C9 g( |" K0 A84 } /* end cycle */
5 ^. n, E) q. { e6 L( k85 out[0] = ntoh(y); ! J q) O1 O! Z T& @
86 out[1] = ntoh(z);
7 n, T2 u k# ^+ J! E8 r% ]8 c87 }
A$ S# O. i# @: J6 N. ^- ?7 m
* W) X7 n0 S y2 i6 v+ ~# Y" W需要说明的是TEA的构造函数: & X9 Y; _: ^( W, ]/ x$ v ]
TEA(const byte *key, int round = 32, bool isNetByte = false); - |1 M5 `( Q5 w% M
1.key - 加密或解密用的128-bit(16byte)密钥。
4 i7 h$ @) U: x7 j; n2.round - 加密或解密的轮数,常用的有64,32,16。
6 x! ^2 O, o2 e2 u6 u3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ' l9 d& z) c6 z0 M/ L1 P
- k1 s( B6 L' T
最后当然少不了测试代码: |
|