|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
2 N2 L( l" h \0 j. M% P9 c 2 #include <cstring> //for memcpy,memset , k) N/ E) X# ]. H1 j. i2 x0 k D
3
' s$ }: {# Y) o 4 using namespace std;
/ h N% O2 I' t' t+ V 5 ) P# \ Q, ^2 h/ T2 }% }% O
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
8 y$ K: C) V: ^$ i ? 7 :_round(round) : U$ F, M6 Y" A: t0 F0 l$ s
8 ,_isNetByte(isNetByte) {
2 m9 ~) L* q. I( n$ e- M5 \ 9 if (key != 0)
5 |- V4 _$ m! g0 T- b8 E0 ^. ~10 memcpy(_key, key, 16);
1 E7 n" D. T6 v$ P11 else " N: t: G6 G! E2 S2 w2 y
12 memset(_key, 0, 16);
0 ]$ T m1 m+ c. ^* ^13 } : a- N2 W# Y1 A; `; S
14 0 f! I7 i. s4 }, z
15 TEA::TEA(const TEA &rhs)
1 K% Y; L7 @. J& h16 :_round(rhs._round)
7 D8 }- P' E) b" Q/ e: j17 ,_isNetByte(rhs._isNetByte) { / b7 a; e7 @8 s7 a, x
18 memcpy(_key, rhs._key, 16);
; x* v% M- q S0 i19 }
9 S9 [7 Y/ U$ [# R; |; F20 9 A; e3 {$ g$ J- h+ J! e+ {
21 TEA& TEA::operator=(const TEA &rhs) { 5 c$ t" u- f1 k8 j0 P Y
22 if (&rhs != this) { * [" F4 t( B; O: N
23 _round = rhs._round; 1 h- |) N- s$ c
24 _isNetByte = rhs._isNetByte; 8 U8 q7 a" p' Q( L. {
25 memcpy(_key, rhs._key, 16); / P: I- u& s' L0 P, Y) b2 E
26 } 5 H. C1 c! B4 g" \9 l5 |2 F" W
27 return *this;
. N: r' ?$ c$ d28 }
+ s& _1 Z3 ^* _* l/ Z; K29 3 a- ^0 F4 _5 X! v& ~& C
30 void TEA::encrypt(const byte *in, byte *out) { 6 E6 C1 E4 ^; \2 o- _
31 encrypt((const ulong*)in, (ulong*)out);
) t6 U4 q5 \- n% P8 w, [32 }
4 f' J7 D& g3 c! L! F1 j" E* a33 1 k0 I6 r- d$ k
34 void TEA::decrypt(const byte *in, byte *out) {
% ^" o: B4 W R, G/ b4 d. |35 decrypt((const ulong*)in, (ulong*)out); 4 U8 a- v+ K, O% E
36 }
- Q: p4 G* Q* t# x9 K0 F! h37 0 e, i6 a0 E6 `" h
38 void TEA::encrypt(const ulong *in, ulong *out) { ) _! O) U. m2 Q. r& O# ]1 I
39
9 ` r8 w0 f) e3 r6 ]) f3 J4 Y40 ulong *k = (ulong*)_key;
% j! z& P% G1 [" \1 t41 register ulong y = ntoh(in[0]);
4 K, P0 N, @: |1 J) \; ^42 register ulong z = ntoh(in[1]); 5 F2 ^( ~% H4 b" W* c( A
43 register ulong a = ntoh(k[0]); 0 i# |; r; b6 X& k
44 register ulong b = ntoh(k[1]);
6 P3 Q6 Y6 s+ R. L& u; F45 register ulong c = ntoh(k[2]);
7 u# i# K( O) w/ q& o5 l% P* ?46 register ulong d = ntoh(k[3]); ; z' \; @' y$ h& U: d- P2 B! d
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
+ Y0 Z* p7 d+ s) M [6 h" ~48 register int round = _round;
. D' |" [/ Y; Q6 S49 register ulong sum = 0; , H8 ~: z3 Y" {& t( \2 X
50
3 `* T! p! d- N) L/ O I51 while (round--) { /* basic cycle start */
. W) e0 n9 r1 D( A3 z52 sum += delta;
5 H: Q& p! U& A5 x; Y: [53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
; A- @! m" L9 @7 E, a! g( b54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 3 y* C0 k5 B) Y! M
55 } /* end cycle */ ( u9 x- A- i: q: g7 }. z
56 out[0] = ntoh(y);
* n3 o& X8 |7 P) R57 out[1] = ntoh(z); $ m K$ S2 n- J3 A
58 } 1 B" G% Y% u6 x/ @. R/ t
59
- e8 |4 F; F4 ~* Y, P60 void TEA::decrypt(const ulong *in, ulong *out) {
- u5 r" t' j$ b0 v1 z61 ) N$ Z% f0 A! p* ~ H4 _
62 ulong *k = (ulong*)_key;
% S, U1 m8 m% \1 ] Y4 B63 register ulong y = ntoh(in[0]); c3 y: |5 e; s0 ?
64 register ulong z = ntoh(in[1]); 5 G# k! b" ^: {1 k
65 register ulong a = ntoh(k[0]); 4 G1 C* Z* R( k4 f* L
66 register ulong b = ntoh(k[1]);
: ]8 H& D# A& N6 r% U5 M67 register ulong c = ntoh(k[2]); 2 v5 D4 x4 q/ b) y
68 register ulong d = ntoh(k[3]); 0 n6 h/ m1 ]' A3 u) i
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
" |' ^8 E; k6 U( ?9 J70 register int round = _round; ! o- t! o( X0 S
71 register ulong sum = 0;
! X, V- k1 b ^) N$ h72 + Y. U; ?& N4 ^( G
73 if (round == 32) 3 t) z( U% H" U" {
74 sum = 0xC6EF3720; /* delta << 5*/ 8 ^& m$ Y% y" `
75 else if (round == 16) * ]! }8 c4 T4 n( [) m7 A, g6 k) u
76 sum = 0xE3779B90; /* delta << 4*/ ; @2 W' a/ [5 j' [# x! p2 d) ?
77 else
}8 \* q4 c {2 l x: a3 z78 sum = delta << static_cast<int>(logbase(2, round));
a0 v, P2 ~- `6 M( i79 : q1 X5 j8 Q1 k# I& A+ a5 F. f2 Y' [
80 while (round--) { /* basic cycle start */ 6 F) V3 f$ C6 S/ [6 F9 r. I
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
2 e0 x+ X0 O* ^- i+ Z+ l82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
/ _0 _* {8 d, k+ m83 sum -= delta;
2 I" E. o( {# l# { f84 } /* end cycle */ & K2 N# D% L$ @6 A8 U6 \
85 out[0] = ntoh(y); , k3 h: t1 n; R# H9 a
86 out[1] = ntoh(z); - s7 ^9 S$ n6 y9 k; E
87 }' j# F! ~( h: D1 K( r4 |
0 @0 R5 G, r; K( {
需要说明的是TEA的构造函数:
6 U1 q5 U8 d6 I9 X+ a/ w5 CTEA(const byte *key, int round = 32, bool isNetByte = false); ) Z; ~" ~/ _- r7 N0 L
1.key - 加密或解密用的128-bit(16byte)密钥。 ! F+ Y- n |- i* a! |4 m
2.round - 加密或解密的轮数,常用的有64,32,16。
, d! M5 K4 @' H$ B3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
7 E- A4 j5 O+ m S3 W5 X# q% O, M6 ^" L
最后当然少不了测试代码: |
|