|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
# A7 U7 D1 M p8 P6 {4 f, } 2 #include <cstring> //for memcpy,memset $ p9 L$ Z; z+ j* [
3 ; I0 X u) z* l7 `" T% O% X
4 using namespace std;
7 w8 ~7 x* E; [ 5
5 v. g& p' {. Z# b/ P4 ? 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
. U3 C3 B' y/ ?2 i( R2 u 7 :_round(round) R+ s% J4 ~9 ^3 Y( s. ]! t
8 ,_isNetByte(isNetByte) { 3 `/ w" {" Q$ ~ m- ~
9 if (key != 0) ' B2 R# H# ^, `5 b
10 memcpy(_key, key, 16); 2 H+ p# Z8 S$ u& `* U" c5 G6 [
11 else 9 Q( A* P! C% x# F5 d' w8 _
12 memset(_key, 0, 16); 4 v5 L: a) M+ i0 J% S& [) ^
13 }
2 h$ a4 S( I! W5 e1 q14
$ s# u K. O7 e4 `: E+ k! j15 TEA::TEA(const TEA &rhs) * k/ Y: \. ]/ m! N& {; p% o
16 :_round(rhs._round) # y& h" q1 |# B8 X" N$ W
17 ,_isNetByte(rhs._isNetByte) { / L* M; q) F: v( K
18 memcpy(_key, rhs._key, 16); / y# @4 H( W' V! [
19 } $ O; P# S" _! S
20
. C. b% i! N D8 F$ o21 TEA& TEA::operator=(const TEA &rhs) {
$ ^/ v, p, {, K! G3 w22 if (&rhs != this) {
# Y! R" z |1 a" _& @23 _round = rhs._round; ) T& f' {7 M' N9 V
24 _isNetByte = rhs._isNetByte; + R# k3 [2 p0 f9 ]0 ?
25 memcpy(_key, rhs._key, 16);
: P5 P# d1 U4 A% A" i26 }
3 @+ j2 J4 B2 r( w) @; p# }27 return *this;
; D6 E% n2 B- s( O28 }
" l5 n3 x e3 i0 D( Q* C29
! T* N; c1 L3 G: Z) d30 void TEA::encrypt(const byte *in, byte *out) { + |& k- ?% J" F1 |
31 encrypt((const ulong*)in, (ulong*)out); % Z) A7 S5 R' c
32 } , B# H! M& ?: A
33 / d" I; _' S& _& p+ D% f
34 void TEA::decrypt(const byte *in, byte *out) { $ ]3 V6 z3 ^, W* t+ d
35 decrypt((const ulong*)in, (ulong*)out); . o& A8 T" n! @( Q$ C3 ]
36 } . ?' v% ]4 r6 i- |% i( o
37
: L9 Y% D, F) q8 r! Y4 N38 void TEA::encrypt(const ulong *in, ulong *out) { " b0 _; w0 j* ]" n# U
39 2 B# O5 x1 W: ?0 l4 ^1 Q
40 ulong *k = (ulong*)_key;
2 L3 H1 |# t& p7 T41 register ulong y = ntoh(in[0]); # ^0 M( |( G. ^; G, T5 n$ u
42 register ulong z = ntoh(in[1]);
( N Q6 q" a8 o8 u43 register ulong a = ntoh(k[0]);
, y2 x8 h, h. r# m( I, A2 z44 register ulong b = ntoh(k[1]);
: m0 s) _# A: o3 }* J; ^45 register ulong c = ntoh(k[2]); ! E, o6 X/ q! q R! x& ] _
46 register ulong d = ntoh(k[3]);
] ]: U- X6 a47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ " _7 a, w# X3 [# ^6 O* L* T
48 register int round = _round;
i; ?# G. @8 O9 p- v* b; P49 register ulong sum = 0;
3 h& h- h% q$ Q+ G* z50
# i& h) ^5 f7 s2 D2 n, x N51 while (round--) { /* basic cycle start */ ; _' {3 R( w, s, U$ Z
52 sum += delta; & d+ b5 W' k! R& x% F/ \
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 4 ?3 Y% \" o( Y8 ?- n
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
/ `9 D1 j1 d- F) u0 ~55 } /* end cycle */ 4 v0 r E3 {% z, [% J: _4 a1 V$ O
56 out[0] = ntoh(y);
3 Z0 [$ z- B" Y" E4 R/ \" W57 out[1] = ntoh(z); * z% U& p% z5 ~* W% r7 |" v( O1 D3 u
58 } 4 o5 k f7 F: Z8 Z( w2 t
59
Y8 a& P. Y$ ]( O" b' ~60 void TEA::decrypt(const ulong *in, ulong *out) { . u6 j) N. \' x0 z5 B1 x: ]9 t. e, M
61 5 T8 q# z$ V! A; g
62 ulong *k = (ulong*)_key;
0 p; ]; |: N, Z; p, a2 C63 register ulong y = ntoh(in[0]);
" @" u+ ~! w- _6 U# B7 @64 register ulong z = ntoh(in[1]); ) ]/ R) p q: O4 P7 z! U
65 register ulong a = ntoh(k[0]); " g% G3 g* M! B' _! ]
66 register ulong b = ntoh(k[1]);
7 k+ c+ [ Q$ f; X2 k. M67 register ulong c = ntoh(k[2]);
3 `( s1 A+ q, p3 P% ]* j68 register ulong d = ntoh(k[3]);
/ o! ]' |8 L8 n( M o8 c69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ & ]# \' I' z8 \$ z& F
70 register int round = _round;
/ U3 l0 B( z) E5 q71 register ulong sum = 0;
4 F0 j/ F: ~; ]& v/ y72 $ u/ X; P ~9 D
73 if (round == 32) 0 C* n5 g' z+ h$ Y ?' F5 w
74 sum = 0xC6EF3720; /* delta << 5*/
9 ~* @, F6 D0 Y! j# i t75 else if (round == 16)
: ^! \& [9 ^% l4 F- J76 sum = 0xE3779B90; /* delta << 4*/
. E4 F, \6 w. j% V5 o/ F. [77 else 6 d( }2 d+ W& L5 O
78 sum = delta << static_cast<int>(logbase(2, round));
: |! ]+ @- s# {: q4 p79 , J9 }( B4 ^* w y2 q
80 while (round--) { /* basic cycle start */
w2 m) H* q+ r% U) Y81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
: [0 T0 J' h- J) p! H- A4 a+ q82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); " L. \1 V( c% n5 }/ @, w6 N! c; @
83 sum -= delta;
. d+ N( p* `! h* J" X8 {84 } /* end cycle */ " h, J' E; h" F$ M4 l
85 out[0] = ntoh(y); " ]2 u, E2 ~+ i$ }. y
86 out[1] = ntoh(z); 9 u% d% ` x& X ?2 M* K
87 }
( C$ y) j& g2 ^. _9 I) X& N; n3 _0 p
需要说明的是TEA的构造函数: + V& {# F7 E L6 n
TEA(const byte *key, int round = 32, bool isNetByte = false); 3 P% _# m/ h1 v
1.key - 加密或解密用的128-bit(16byte)密钥。 S! Y0 ~8 a! e3 D% a
2.round - 加密或解密的轮数,常用的有64,32,16。
& V% @- F: g b# }* G- Z: k* v) {; ^3 t3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 0 A* y) b" W- d0 c
( z1 f2 [; o3 ?7 `' O
最后当然少不了测试代码: |
|