Skip to content

Commit 51a7ec8

Browse files
committed
Added additional comments and formatting to S256SUM.LUA
1 parent f94f44e commit 51a7ec8

File tree

1 file changed

+162
-103
lines changed

1 file changed

+162
-103
lines changed

core/S256SUM.LUA

Lines changed: 162 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
---@param file file The file
55
---@return string SHA-256 checksum
66
function sha256_file(file)
7-
-- M = Maximum value of number (32-bits)
8-
-- K = SHA256 round constants
9-
local M, K = 0xFFFFFFFF, {
7+
8+
-- M = Maximum value of number (32-bits)
9+
-- K = SHA256 round constants
10+
local M, K = 0xFFFFFFFF, {
1011
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
1112
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
1213
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
@@ -20,110 +21,168 @@ function sha256_file(file)
2021
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
2122
}
2223

23-
---Right rotate a 32-bit value
24-
---@param x number The 32-bit value to be rotated
25-
---@param n number The number of rotations to the right that should be done
26-
---@return number The right shifted value
27-
local function RR(x, n)
28-
return (x >> n) | ((x & M) << (32 - n))
29-
end
30-
31-
---SHA-256 transformation function
32-
---@param k string A 64-byte chunk of the message
33-
---@param H table The current hash state (8 32-bit values)
34-
local function TF(k, H)
35-
local W = {}
36-
for i = 0, 15 do -- Convert chunk into 32-bit list
37-
local o = i * 4 + 1
38-
W[i] = string.byte(k, o) << 24 | string.byte(k, o + 1) << 16 | string.byte(k, o + 2) << 8 | string.byte(k, o + 3)
39-
end
40-
for i = 16, 63 do -- Message expansion
41-
local s0, s1 = RR(W[i - 15], 7) ~ RR(W[i - 15], 18) ~ (W[i - 15] >> 3), RR(W[i - 2], 17) ~ RR(W[i - 2], 19) ~ (W[i - 2] >> 10)
42-
W[i] = (W[i - 16] + s0 + W[i - 7] + s1) & M
43-
end
44-
local a, b, c, d, e, f, g, h = table.unpack(H)
45-
for i = 0, 63 do
46-
local S0, S1, ch, maj = RR(a, 2) ~ RR(a, 13) ~ RR(a, 22), RR(e, 6) ~ RR(e, 11) ~ RR(e, 25), (e & f) ~ ((~e) & g), (a & b) ~ (a & c) ~ (b & c)
47-
local t1, t2 = (h + S1 + ch + K[i + 1] + W[i]) & M, (S0 + maj) & M
48-
h = g
49-
g = f
50-
f = e
51-
e = (d + t1) & M
52-
d = c
53-
c = b
54-
b = a
55-
a = (t1 + t2) & M
56-
end
57-
H[1] = (H[1] + a) & M
58-
H[2] = (H[2] + b) & M
59-
H[3] = (H[3] + c) & M
60-
H[4] = (H[4] + d) & M
61-
H[5] = (H[5] + e) & M
62-
H[6] = (H[6] + f) & M
63-
H[7] = (H[7] + g) & M
64-
H[8] = (H[8] + h) & M
65-
end
66-
67-
---Create SHA-256 padding for message
68-
---@param l number The length of the message in bytes
69-
---@return string The padding string to append to the message
70-
local function P(l)
71-
local ml, p, pl = l * 8, "\128", 56 - (l % 64)
72-
if pl <= 0 then
73-
pl = pl + 64
74-
end
75-
p = p .. string.rep("\0", pl - 1)
76-
for i = 7, 0, -1 do
77-
p = p .. string.char((ml >> (i * 8)) & 0xFF)
78-
end
79-
return p
80-
end
81-
82-
local H, l = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }, 0
83-
while 1 do
84-
local c = file:read(64)
85-
if not c then
86-
break
87-
end
88-
l = l + #c
89-
if #c < 64 then
90-
c = c .. P(l)
91-
TF(c, H)
92-
break
93-
end
94-
TF(c, H)
95-
end
96-
local function h(x)
97-
return string.format("%08x", x)
98-
end
99-
l = {}
100-
for _, v in ipairs(H) do
101-
table.insert(l, h(v))
102-
end
103-
return table.concat(l)
24+
---Right rotate a 32-bit value
25+
---@param x number The 32-bit value to be rotated
26+
---@param n number The number of rotations to the right that should be done
27+
---@return number The right shifted value
28+
local function RR(x, n)
29+
return (x >> n) | ((x & M) << (32 - n))
30+
end
31+
32+
---SHA-256 transformation function
33+
---@param k string A 64-byte chunk of the message
34+
---@param H table The current hash state (8 32-bit values)
35+
local function TF(k, H)
36+
37+
-- W = list of 32-bit words
38+
local W = {}
39+
40+
for i = 0, 15 do -- Convert chunk into 32-bit list
41+
42+
-- o = Offset calculation
43+
local o = i * 4 + 1
44+
45+
W[i] = string.byte(k, o) << 24 | string.byte(k, o + 1) << 16 | string.byte(k, o + 2) << 8 | string.byte(k, o + 3)
46+
end
47+
for i = 16, 63 do -- Message expansion
48+
49+
-- s0 = Message schedule shift 0
50+
-- s1 = Message schedule shift 1
51+
local s0, s1 = RR(W[i - 15], 7) ~ RR(W[i - 15], 18) ~ (W[i - 15] >> 3), RR(W[i - 2], 17) ~ RR(W[i - 2], 19) ~ (W[i - 2] >> 10)
52+
53+
W[i] = (W[i - 16] + s0 + W[i - 7] + s1) & M
54+
end
55+
56+
-- 32-bit working variables initialized with the current hash values of H
57+
local a, b, c, d, e, f, g, h = table.unpack(H)
58+
59+
for i = 0, 63 do
60+
61+
-- S0 = Compression rotation variable 0
62+
-- S1 = Compression rotation variable 1
63+
-- ch = Choice function
64+
-- ma = Majority function
65+
local S0, S1, ch, ma = RR(a, 2) ~ RR(a, 13) ~ RR(a, 22), RR(e, 6) ~ RR(e, 11) ~ RR(e, 25), (e & f) ~ ((~e) & g), (a & b) ~ (a & c) ~ (b & c)
66+
67+
-- t1 = Temporary variable 1
68+
-- t2 = Temporary variable 2
69+
local t1, t2 = (h + S1 + ch + K[i + 1] + W[i]) & M, (S0 + ma) & M
70+
71+
-- Working variable update
72+
h = g
73+
g = f
74+
f = e
75+
e = (d + t1) & M
76+
d = c
77+
c = b
78+
b = a
79+
a = (t1 + t2) & M
80+
end
81+
82+
-- Update hash state with compressed block values
83+
H[1] = (H[1] + a) & M
84+
H[2] = (H[2] + b) & M
85+
H[3] = (H[3] + c) & M
86+
H[4] = (H[4] + d) & M
87+
H[5] = (H[5] + e) & M
88+
H[6] = (H[6] + f) & M
89+
H[7] = (H[7] + g) & M
90+
H[8] = (H[8] + h) & M
91+
end
92+
93+
---Create SHA-256 padding for message
94+
---@param l number The length of the message in bytes
95+
---@return string The padding string to append to the message
96+
local function P(l)
97+
98+
-- ml = Message length (in bits)
99+
-- p = Padding string
100+
-- pl = Padding length (in bytes)
101+
local ml, p, pl = l * 8, "\128", 56 - (l % 64)
102+
103+
-- Add enough room for padding if required
104+
if pl <= 0 then
105+
pl = pl + 64
106+
end
107+
108+
-- Zero out padding
109+
p = p .. string.rep("\0", pl - 1)
110+
111+
-- Append original message length
112+
for i = 7, 0, -1 do
113+
p = p .. string.char((ml >> (i * 8)) & 0xFF)
114+
end
115+
116+
return p
117+
end
118+
119+
-- H = Initial Hash values
120+
-- l = Total bytes of file processed
121+
local H, l = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }, 0
122+
123+
while 1 do
124+
125+
-- c = 64 byte chunk of file
126+
local c = file:read(64)
127+
128+
if not c then
129+
break
130+
end
131+
132+
l = l + #c
133+
134+
if #c < 64 then
135+
c = c .. P(l)
136+
TF(c, H)
137+
break
138+
end
139+
140+
TF(c, H)
141+
end
142+
143+
local function h(x)
144+
return string.format("%08x", x)
145+
end
146+
147+
-- l = Final hash string
148+
l = {}
149+
150+
for _, v in ipairs(H) do
151+
table.insert(l, h(v))
152+
end
153+
154+
return table.concat(l)
104155
end
105156

106157
if LIB then
107-
return -- Don't run below code if brought in as a library
158+
return -- Don't run below code if brought in as a library
108159
end
109160

110-
if #arg < 1 then
111-
print((arg[-1] or "?") .. " " .. (arg[0] or "?") .. " [FILE]...")
112-
os.exit(1)
161+
if #arg < 1 then -- Print help and exit if no arguments
162+
print((arg[-1] or "?") .. " " .. (arg[0] or "?") .. " [FILE]...")
163+
os.exit(1)
113164
else
114-
for i = 1, #arg do
115-
local f, e = io.open(arg[i], "rb")
116-
if not f then
117-
print(e)
118-
os.exit(1)
119-
end
120-
local sum = sha256_file(f)
121-
f:close()
122-
if sum then
123-
print(sum .. " " .. arg[i])
124-
else
125-
print(arg[i] .. ": " .. "Unknown error")
126-
os.exit(-1)
127-
end
128-
end
165+
for i = 1, #arg do
166+
167+
-- f = File to read
168+
-- e = Error message on failure to open
169+
local f, e = io.open(arg[i], "rb")
170+
171+
if not f then
172+
print(e)
173+
os.exit(1)
174+
end
175+
176+
-- s = SHA256 string of file
177+
local s = sha256_file(f)
178+
179+
f:close()
180+
181+
if s then -- Print hash and filename
182+
print(s .. " " .. arg[i])
183+
else
184+
print(arg[i] .. ": " .. "Unknown error")
185+
os.exit(-1)
186+
end
187+
end
129188
end

0 commit comments

Comments
 (0)