88
99import argparse
1010import struct
11- from typing import List
11+ from typing import ClassVar
1212
1313
1414class 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