Skip to content

Commit 1072462

Browse files
committed
added sha3
1 parent 1bfe1d6 commit 1072462

File tree

1 file changed

+41
-53
lines changed

1 file changed

+41
-53
lines changed

hashes/sha3.py

Lines changed: 41 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,23 @@
88

99
import argparse
1010
import struct
11-
from typing import List
11+
from typing import ClassVar
1212

1313

1414
class KeccakSHA3:
1515
# Round constants
16-
_RC = [
17-
0x0000000000000001,
18-
0x0000000000008082,
19-
0x800000000000808A,
20-
0x8000000080008000,
21-
0x000000000000808B,
22-
0x0000000080000001,
23-
0x8000000080008081,
24-
0x8000000000008009,
25-
0x000000000000008A,
26-
0x0000000000000088,
27-
0x0000000080008009,
28-
0x000000008000000A,
29-
0x000000008000808B,
30-
0x800000000000008B,
31-
0x8000000000008089,
32-
0x8000000000008003,
33-
0x8000000000008002,
34-
0x8000000000000080,
35-
0x000000000000800A,
36-
0x800000008000000A,
37-
0x8000000080008081,
38-
0x8000000000008080,
39-
0x0000000080000001,
40-
0x8000000080008008,
16+
_RC: ClassVar[list[int]] = [
17+
0x0000000000000001, 0x0000000000008082, 0x800000000000808A,
18+
0x8000000080008000, 0x000000000000808B, 0x0000000080000001,
19+
0x8000000080008081, 0x8000000000008009, 0x000000000000008A,
20+
0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
21+
0x000000008000808B, 0x800000000000008B, 0x8000000000008089,
22+
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
23+
0x000000000000800A, 0x800000008000000A, 0x8000000080008081,
24+
0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
4125
]
4226

43-
_ROT = [
27+
_ROT: ClassVar[list[list[int]]] = [
4428
[0, 36, 3, 41, 18],
4529
[1, 44, 10, 45, 2],
4630
[62, 6, 43, 15, 61],
@@ -67,62 +51,63 @@ def _rol(x: int, n: int) -> int:
6751
n %= 64
6852
return ((x << n) | (x >> (64 - n))) & 0xFFFFFFFFFFFFFFFF
6953

70-
def _permute(self):
71-
A = self.state
54+
def _permute(self) -> None:
55+
a = self.state
7256

7357
for rnd in range(24):
74-
# θ
75-
C = [A[x][0] ^ A[x][1] ^ A[x][2] ^ A[x][3] ^ A[x][4] for x in range(5)]
76-
D = [C[(x - 1) % 5] ^ self._rol(C[(x + 1) % 5], 1) for x in range(5)]
58+
# theta
59+
c = [a[x][0] ^ a[x][1] ^ a[x][2] ^ a[x][3] ^ a[x][4] for x in range(5)]
60+
d = [c[(x - 1) % 5] ^ self._rol(c[(x + 1) % 5], 1) for x in range(5)]
61+
7762
for x in range(5):
7863
for y in range(5):
79-
A[x][y] ^= D[x]
64+
a[x][y] ^= d[x]
8065

81-
# ρ + π
82-
B = [[0] * 5 for _ in range(5)]
66+
# rho + pi
67+
b = [[0] * 5 for _ in range(5)]
8368
for x in range(5):
8469
for y in range(5):
85-
B[y][(2 * x + 3 * y) % 5] = self._rol(A[x][y], self._ROT[x][y])
70+
b[y][(2 * x + 3 * y) % 5] = self._rol(a[x][y], self._ROT[x][y])
8671

87-
# χ
72+
# chi
8873
for x in range(5):
8974
for y in range(5):
90-
A[x][y] = B[x][y] ^ ((~B[(x + 1) % 5][y]) & B[(x + 2) % 5][y])
75+
a[x][y] = b[x][y] ^ ((~b[(x + 1) % 5][y]) & b[(x + 2) % 5][y])
9176

92-
# ι
93-
A[0][0] ^= self._RC[rnd]
77+
# iota
78+
a[0][0] ^= self._RC[rnd]
9479

9580
# ================= SPONGE =================
9681

9782
def _pad(self, data: bytes) -> bytes:
98-
r = self.rate // 8
83+
rate_bytes = self.rate // 8
9984
buf = bytearray(data)
10085
buf.append(0x06)
101-
while len(buf) % r != r - 1:
86+
while len(buf) % rate_bytes != rate_bytes - 1:
10287
buf.append(0x00)
10388
buf.append(0x80)
10489
return bytes(buf)
10590

106-
def _absorb(self):
107-
r = self.rate // 8
91+
def _absorb(self) -> None:
92+
rate_bytes = self.rate // 8
10893
padded = self._pad(self.msg)
10994

110-
for off in range(0, len(padded), r):
111-
block = padded[off : off + r]
112-
for i in range(0, r, 8):
113-
lane = struct.unpack("<Q", block[i : i + 8])[0]
95+
for off in range(0, len(padded), rate_bytes):
96+
block = padded[off:off + rate_bytes]
97+
for i in range(0, rate_bytes, 8):
98+
lane = struct.unpack("<Q", block[i:i + 8])[0]
11499
x = (i // 8) % 5
115100
y = (i // 8) // 5
116101
self.state[x][y] ^= lane
117102
self._permute()
118103

119104
def _squeeze(self) -> bytes:
120105
out = bytearray()
121-
r = self.rate // 8
106+
rate_bytes = self.rate // 8
122107
need = self.out_bits // 8
123108

124109
while len(out) < need:
125-
for i in range(0, r, 8):
110+
for i in range(0, rate_bytes, 8):
126111
x = (i // 8) % 5
127112
y = (i // 8) // 5
128113
out.extend(struct.pack("<Q", self.state[x][y]))
@@ -134,13 +119,16 @@ def _squeeze(self) -> bytes:
134119

135120
# ================= CLI =================
136121

137-
138-
def main():
122+
def main() -> None:
139123
parser = argparse.ArgumentParser(description="SHA-3 hashing tool")
140124
parser.add_argument("-s", "--string", help="String input")
141125
parser.add_argument("-f", "--file", help="File input")
142126
parser.add_argument(
143-
"-l", "--length", type=int, default=256, choices=[224, 256, 384, 512]
127+
"-l",
128+
"--length",
129+
type=int,
130+
default=256,
131+
choices=[224, 256, 384, 512],
144132
)
145133

146134
args = parser.parse_args()

0 commit comments

Comments
 (0)