sha1.py
1 def left_rotate(n: int, b: int) -> int: 2 return ((n << b) | (n >> (32 - b))) & 0xffffffff 3 4 5 def sha1(data: bytes) -> bytes: 6 h = [ 7 0x67452301, 8 0xEFCDAB89, 9 0x98BADCFE, 10 0x10325476, 11 0xC3D2E1F0 12 ] 13 message = data + b'\x80' 14 message += b'\x00' * ((56 - len(message) % 64) % 64) 15 message += (len(data) * 8).to_bytes(8, 'big') 16 for i_ in range(len(message) // 64): 17 chunk = message[i_ * 64:(i_ + 1) * 64] 18 w = [int.from_bytes(chunk[i * 4:(i + 1) * 4], 'big') for i in range(16)] 19 for i in range(64): 20 w.append(left_rotate(w[-3] ^ w[-8] ^ w[-14] ^ w[-16], 1)) 21 a, b, c, d, e = h 22 for i in range(80): 23 if i < 20: 24 f = d ^ (b & (c ^ d)) 25 k = 0x5A827999 26 elif i < 40: 27 f = b ^ c ^ d 28 k = 0x6ED9EBA1 29 elif i < 60: 30 f = (b & c) | (b & d) | (c & d) 31 k = 0x8F1BBCDC 32 else: 33 f = b ^ c ^ d 34 k = 0xCA62C1D6 35 a, b, c, d, e = (left_rotate(a, 5) + f + e + k + w[i]) & 0xffffffff, a, left_rotate(b, 30), c, d 36 h = [(x + y) & 0xffffffff for x, y in zip(h, [a, b, c, d, e])] 37 return b''.join([x.to_bytes(4, 'big') for x in h])