-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxxtea.go
130 lines (120 loc) · 3.18 KB
/
xxtea.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package kbutils
/**********************************************************\
| |
| xxtea.go |
| |
| XXTEA encryption algorithm library for Golang. |
| |
| Encryption Algorithm Authors: |
| David J. Wheeler |
| Roger M. Needham |
| |
| Code Author: Ma Bingyao <mabingyao@gmail.com> |
| LastModified: Mar 10, 2015 |
| |
\**********************************************************/
const delta = 0x9E3779B9
func toBytes(v []uint32, includeLength bool) []byte {
length := uint32(len(v))
n := length << 2
if includeLength {
m := v[length-1]
n -= 4
if (m < n-3) || (m > n) {
return nil
}
n = m
}
bytes := make([]byte, n)
for i := uint32(0); i < n; i++ {
bytes[i] = byte(v[i>>2] >> ((i & 3) << 3))
}
return bytes
}
func toUint32s(bytes []byte, includeLength bool) (v []uint32) {
length := uint32(len(bytes))
n := length >> 2
if length&3 != 0 {
n++
}
if includeLength {
v = make([]uint32, n+1)
v[n] = length
} else {
v = make([]uint32, n)
}
for i := uint32(0); i < length; i++ {
v[i>>2] |= uint32(bytes[i]) << ((i & 3) << 3)
}
return v
}
func mx(sum uint32, y uint32, z uint32, p uint32, e uint32, k []uint32) uint32 {
return ((z>>5 ^ y<<2) + (y>>3 ^ z<<4)) ^ ((sum ^ y) + (k[p&3^e] ^ z))
}
func fixk(k []uint32) []uint32 {
if len(k) < 4 {
key := make([]uint32, 4)
copy(key, k)
return key
}
return k
}
func encrypt(v []uint32, k []uint32) []uint32 {
length := uint32(len(v))
n := length - 1
k = fixk(k)
var y, z, sum, e, p, q uint32
z = v[n]
sum = 0
for q = 6 + 52/length; q > 0; q-- {
sum += delta
e = sum >> 2 & 3
for p = 0; p < n; p++ {
y = v[p+1]
v[p] += mx(sum, y, z, p, e, k)
z = v[p]
}
y = v[0]
v[n] += mx(sum, y, z, p, e, k)
z = v[n]
}
return v
}
func decrypt(v []uint32, k []uint32) []uint32 {
length := uint32(len(v))
n := length - 1
k = fixk(k)
var y, z, sum, e, p, q uint32
y = v[0]
q = 6 + 52/length
for sum = q * delta; sum != 0; sum -= delta {
e = sum >> 2 & 3
for p = n; p > 0; p-- {
z = v[p-1]
v[p] -= mx(sum, y, z, p, e, k)
y = v[p]
}
z = v[n]
v[0] -= mx(sum, y, z, p, e, k)
y = v[0]
}
return v
}
// Encrypt the data with key.
// data is the bytes to be encrypted.
// key is the encrypt key. It is the same as the decrypt key.
func XXTeaEncrypt(data []byte, key []byte) []byte {
if data == nil || len(data) == 0 {
return data
}
return toBytes(encrypt(toUint32s(data, true), toUint32s(key, false)), false)
}
// Decrypt the data with key.
// data is the bytes to be decrypted.
// key is the decrypted key. It is the same as the encrypt key.
func XXTeaDecrypt(data []byte, key []byte) []byte {
if data == nil || len(data) == 0 {
return data
}
return toBytes(decrypt(toUint32s(data, false), toUint32s(key, false)), true)
}