-
Notifications
You must be signed in to change notification settings - Fork 1
/
xxtea.go
117 lines (108 loc) · 2.35 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
package utils
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]
y = v[0]
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
z = v[n]
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 Encrypt(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 Decrypt(data []byte, key []byte) []byte {
if data == nil || len(data) == 0 {
return data
}
return toBytes(decrypt(toUint32s(data, false), toUint32s(key, false)), true)
}