aeslua/util.lua

1
local bit = require("bit");
2
 
3
local public = {};
4
local private = {};
5
 
6
local aeslua = require("aeslua");
7
aeslua.util = public;
8
 
9
--
10
-- calculate the parity of one byte
11
--
12
function public.byteParity(byte)
13
    byte = bit.bxor(byte, bit.rshift(byte, 4));
14
    byte = bit.bxor(byte, bit.rshift(byte, 2));
15
    byte = bit.bxor(byte, bit.rshift(byte, 1));
16
    return bit.band(byte, 1);
17
end
18
 
19
-- 
20
-- get byte at position index
21
--
22
function public.getByte(number, index)
23
    if (index == 0) then
24
        return bit.band(number,0xff);
25
    else
26
        return bit.band(bit.rshift(number, index*8),0xff);
27
    end
28
end
29
 
30
 
31
--
32
-- put number into int at position index
33
--
34
function public.putByte(number, index)
35
    if (index == 0) then
36
        return bit.band(number,0xff);
37
    else
38
        return bit.lshift(bit.band(number,0xff),index*8);
39
    end
40
end
41
 
42
--
43
-- convert byte array to int array
44
--
45
function public.bytesToInts(bytes, start, n)
46
    local ints = {};
47
    for i = 0, n - 1 do
48
        ints[i] = public.putByte(bytes[start + (i*4)    ], 3)
49
                + public.putByte(bytes[start + (i*4) + 1], 2) 
50
                + public.putByte(bytes[start + (i*4) + 2], 1)    
51
                + public.putByte(bytes[start + (i*4) + 3], 0);
52
    end
53
    return ints;
54
end
55
 
56
--
57
-- convert int array to byte array
58
--
59
function public.intsToBytes(ints, output, outputOffset, n)
60
    n = n or #ints;
61
    for i = 0, n do
62
        for j = 0,3 do
63
            output[outputOffset + i*4 + (3 - j)] = public.getByte(ints[i], j);
64
        end
65
    end
66
    return output;
67
end
68
 
69
--
70
-- convert bytes to hexString
71
--
72
function private.bytesToHex(bytes)
73
    local hexBytes = "";
74
    
75
    for i,byte in ipairs(bytes) do 
76
        hexBytes = hexBytes .. string.format("%02x ", byte);
77
    end
78
 
79
    return hexBytes;
80
end
81
 
82
--
83
-- convert data to hex string
84
--
85
function public.toHexString(data)
86
    local type = type(data);
87
    if (type == "number") then
88
        return string.format("%08x",data);
89
    elseif (type == "table") then
90
        return private.bytesToHex(data);
91
    elseif (type == "string") then
92
        local bytes = {string.byte(data, 1, #data)}; 
93
 
94
        return private.bytesToHex(bytes);
95
    else
96
        return data;
97
    end
98
end
99
 
100
function public.padByteString(data)
101
    local dataLength = #data;
102
    
103
    local random1 = math.random(0,255);
104
    local random2 = math.random(0,255);
105
 
106
    local prefix = string.char(random1,
107
                               random2,
108
                               random1,
109
                               random2,
110
                               public.getByte(dataLength, 3),
111
                               public.getByte(dataLength, 2),
112
                               public.getByte(dataLength, 1),
113
                               public.getByte(dataLength, 0));
114
 
115
    data = prefix .. data;
116
 
117
    local paddingLength = math.ceil(#data/16)*16 - #data;
118
    local padding = "";
119
    for i=1,paddingLength do
120
        padding = padding .. string.char(math.random(0,255));
121
    end 
122
 
123
    return data .. padding;
124
end
125
 
126
function private.properlyDecrypted(data)
127
    local random = {string.byte(data,1,4)};
128
 
129
    if (random[1] == random[3] and random[2] == random[4]) then
130
        return true;
131
    end
132
    
133
    return false;
134
end
135
 
136
function public.unpadByteString(data)
137
    if (not private.properlyDecrypted(data)) then
138
        return nil;
139
    end
140
 
141
    local dataLength = public.putByte(string.byte(data,5), 3)
142
                     + public.putByte(string.byte(data,6), 2) 
143
                     + public.putByte(string.byte(data,7), 1)    
144
                     + public.putByte(string.byte(data,8), 0);
145
    
146
    return string.sub(data,9,8+dataLength);
147
end
148
 
149
function public.xorIV(data, iv)
150
    for i = 1,16 do
151
        data[i] = bit.bxor(data[i], iv[i]);
152
    end 
153
end
154
 
155
return public;