-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathxxtea.py
62 lines (49 loc) · 1.52 KB
/
xxtea.py
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
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import struct
import numpy as np
def b2i(b):
length = (len(b) + 3) // 4
b = b.ljust(length * 4, b'\x00')
return struct.unpack('<' + str(length) + 'I', b)
def i2b(i):
return struct.pack('<' + str(len(i)) + 'I', *i)
def encode(b, k):
v = list(b2i(b))
v.append(len(b))
v = np.array(v, dtype=np.uint32)
length = len(v)
k = b2i(k)
k = np.array(k, dtype=np.uint32)
rounds = 6 + 52 // length
magic = np.uint32(0x9e3779b9)
for r in range(rounds):
r_sum = magic * np.uint32(r + 1)
r_key = r_sum >> 2 & 3
for i in range(length):
prv = v[(i - 1) % length]
nex = v[(i + 1) % length]
v[i] += ((prv >> 5 ^ nex << 2)
+ (prv << 4 ^ nex ^ nex >> 3 ^ r_sum)
+ (k[i % 4 ^ r_key] ^ prv))
return i2b(v)
def decode(b, k):
v = b2i(b)
v = np.array(v, dtype=np.uint32)
length = len(v)
k = b2i(k)
k = np.array(k, dtype=np.uint32)
rounds = 6 + 52 // length
magic = np.uint32(0x9e3779b9)
for r in range(rounds - 1, -1, -1):
r_sum = magic * np.uint32(r + 1)
r_key = r_sum >> 2 & 3
for i in range(length - 1, -1, -1):
prv = v[(i - 1) % length]
nex = v[(i + 1) % length]
v[i] -= ((prv >> 5 ^ nex << 2)
+ (prv << 4 ^ nex ^ nex >> 3 ^ r_sum)
+ (k[i % 4 ^ r_key] ^ prv))
b = i2b(v[:-1])
assert not any(b[v[-1]:])
return b[:v[-1]]