Skip to content

Commit f7d0640

Browse files
author
brentru
committed
lintin
1 parent 08e679e commit f7d0640

File tree

1 file changed

+147
-140
lines changed

1 file changed

+147
-140
lines changed

adafruit_hashlib/_sha1.py

Lines changed: 147 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@
3333
* Author(s): AJ Alt, Brent Rubell
3434
"""
3535
import struct
36-
from micropython import const
3736
from io import BytesIO
37+
from micropython import const
38+
3839

3940
SHA_BLOCKSIZE = 64
4041
SHA_DIGESTSIZE = 20
@@ -45,153 +46,159 @@
4546
K2 = const(0x8F1BBCDC)
4647
K3 = const(0xCA62C1D6)
4748

48-
def _getbuf(s):
49-
if isinstance(s, str):
50-
return s.encode('ascii')
51-
return bytes(s)
49+
def _getbuf(data):
50+
"""Converts data into ascii,
51+
returns bytes of data
52+
"""
53+
if isinstance(data, str):
54+
return data.encode('ascii')
55+
return bytes(data)
5256

5357

5458
def _left_rotate(n, b):
55-
"""Left rotate a 32-bit integer, n, by b bits.
56-
:param int n: 32-bit integer
57-
:param int b: Desired rotation amount, in bits.
58-
"""
59-
return ((n << b) | (n >> (32 - b))) & 0xffffffff
60-
59+
"""Left rotate a 32-bit integer, n, by b bits.
60+
:param int n: 32-bit integer
61+
:param int b: Desired rotation amount, in bits.
62+
"""
63+
return ((n << b) | (n >> (32 - b))) & 0xffffffff
6164

65+
# pylint: disable=invalid-name, too-many-arguments
6266
def _hash_computation(chunk, h0, h1, h2, h3, h4):
63-
"""Processes 64-bit chunk of data and returns new digest variables.
64-
Per FIPS [6.1.2]
65-
:param bytes bytearray chunk: 64-bit bytearray
66-
:param list h_tuple: List of hash values for the chunk
67-
"""
68-
assert len(chunk) == 64, "Chunk should be 64-bits"
69-
70-
w = [0] * 80
71-
72-
# Break chunk into sixteen 4-byte big-endian words w[i]
73-
for i in range(16):
74-
w[i] = struct.unpack(b'>I', chunk[i * 4:i * 4 + 4])[0]
75-
76-
# Extend the sixteen 4-byte words into eighty 4-byte words
77-
for i in range(16, 80):
78-
w[i] = _left_rotate(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1)
79-
80-
# Init. hash values for chunk
81-
a = h0
82-
b = h1
83-
c = h2
84-
d = h3
85-
e = h4
86-
87-
for i in range(80):
88-
if 0 <= i <= 19:
89-
# Use alternative 1 for f from FIPS PB 180-1 to avoid bitwise not
90-
f = d ^ (b & (c ^ d))
91-
k = K0
92-
elif 20 <= i <= 39:
93-
f = b ^ c ^ d
94-
k = K1
95-
elif 40 <= i <= 59:
96-
f = (b & c) | (b & d) | (c & d)
97-
k = K2
98-
elif 60 <= i <= 79:
99-
f = b ^ c ^ d
100-
k = K3
101-
102-
a, b, c, d, e = ((_left_rotate(a, 5) + f + e + k + w[i]) & 0xffffffff,
103-
a, _left_rotate(b, 30), c, d)
104-
105-
# Add to chunk's hash result so far
106-
h0 = (h0 + a) & 0xffffffff
107-
h1 = (h1 + b) & 0xffffffff
108-
h2 = (h2 + c) & 0xffffffff
109-
h3 = (h3 + d) & 0xffffffff
110-
h4 = (h4 + e) & 0xffffffff
111-
112-
return h0, h1, h2, h3, h4
67+
"""Processes 64-bit chunk of data and returns new digest variables.
68+
Per FIPS [6.1.2]
69+
:param bytes bytearray chunk: 64-bit bytearray
70+
:param list h_tuple: List of hash values for the chunk
71+
"""
72+
assert len(chunk) == 64, "Chunk should be 64-bits"
73+
74+
w = [0] * 80
75+
76+
# Break chunk into sixteen 4-byte big-endian words w[i]
77+
for i in range(16):
78+
w[i] = struct.unpack(b'>I', chunk[i * 4:i * 4 + 4])[0]
79+
80+
# Extend the sixteen 4-byte words into eighty 4-byte words
81+
for i in range(16, 80):
82+
w[i] = _left_rotate(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1)
83+
84+
# Init. hash values for chunk
85+
a = h0
86+
b = h1
87+
c = h2
88+
d = h3
89+
e = h4
90+
91+
for i in range(80):
92+
if 0 <= i <= 19:
93+
# Use alternative 1 for f from FIPS PB 180-1 to avoid bitwise not
94+
f = d ^ (b & (c ^ d))
95+
k = K0
96+
elif 20 <= i <= 39:
97+
f = b ^ c ^ d
98+
k = K1
99+
elif 40 <= i <= 59:
100+
f = (b & c) | (b & d) | (c & d)
101+
k = K2
102+
elif 60 <= i <= 79:
103+
f = b ^ c ^ d
104+
k = K3
105+
106+
a, b, c, d, e = ((_left_rotate(a, 5) + f + e + k + w[i]) & 0xffffffff,
107+
a, _left_rotate(b, 30), c, d)
108+
109+
# Add to chunk's hash result so far
110+
h0 = (h0 + a) & 0xffffffff
111+
h1 = (h1 + b) & 0xffffffff
112+
h2 = (h2 + c) & 0xffffffff
113+
h3 = (h3 + d) & 0xffffffff
114+
h4 = (h4 + e) & 0xffffffff
115+
116+
return h0, h1, h2, h3, h4
113117

114118

115119
# pylint: disable=too-few-public-methods, invalid-name
116120
class sha1():
117-
digest_size = SHA_DIGESTSIZE
118-
block_size = SHA_BLOCKSIZE
119-
name = "sha1"
120-
def __init__(self, s=None):
121-
"""Construct a SHA-1 hash object.
122-
123-
"""
124-
# Initial Digest Variables
125-
self._h = (0x67452301,
126-
0xEFCDAB89,
127-
0x98BADCFE,
128-
0x10325476,
129-
0xC3D2E1F0)
130-
131-
self._unprocessed = b''
132-
self._msg_byte_len = 0
133-
134-
def _create_digest(self):
135-
"""Returns finalized digest variables for the data processed so far.
136-
137-
"""
138-
# pre-processing
139-
message = self._unprocessed
140-
message_len = self._msg_byte_len + len(message)
141-
142-
# add trailing '1' bit (+ 0's padding) to string [§5.1.1]
143-
message += b'\x80'
144-
145-
# append 0 <= k < 512 bits '0', so that the resulting message length (in bytes)
146-
# is congruent to 56 (mod 64)
147-
message += b'\x00' * ((56 - (message_len + 1) % 64) % 64)
148-
149-
150-
# append ml, the original message length, as a 64-bit big-endian integer.
151-
message_bit_length = message_len * 8
152-
message += struct.pack(b'>Q', message_bit_length)
153-
154-
# Process the final chunk
155-
# At this point, the length of the message is either 64 or 128 bytes.
156-
h = _hash_computation(message[:64], *self._h)
157-
if len(message) == 64:
158-
return h
159-
return _hash_computation(message[64:], *h)
160-
161-
def update(self, data):
162-
"""Updates the hash object with bytes-like object, data.
163-
:param bytes data: bytearray or bytes object
164-
165-
"""
166-
# if we get a string, convert to a bytearray objects
167-
data = _getbuf(data)
168-
169-
# switch input to bytesio api for easier reading
170-
if isinstance(data, (bytes, bytearray)):
171-
data = BytesIO(data)
172-
173-
# Try to build a chunk out of the unprocessed data, if any
174-
chunk = self._unprocessed + data.read(64 - len(self._unprocessed))
175-
176-
while len(chunk) == 64:
177-
self._h = _hash_computation(chunk, *self._h)
178-
self._msg_byte_len += 64
179-
# read the next 64 bytes
180-
chunk = data.read(64)
181-
182-
self._unprocessed = chunk
183-
return self
184-
185-
def digest(self):
186-
"""Returns the digest of the data passed to the update()
187-
method so far.
188-
189-
"""
190-
return b''.join(struct.pack(b'>I', h) for h in self._create_digest())
191-
192-
def hexdigest(self):
193-
"""Like digest() except the digest is returned as a string object of
194-
double length, containing only hexadecimal digits.
121+
"""SHA-1 Hash Object
195122
196123
"""
197-
return ''.join(['%.2x' % i for i in self.digest()])
124+
digest_size = SHA_DIGESTSIZE
125+
block_size = SHA_BLOCKSIZE
126+
name = "sha1"
127+
def __init__(self):
128+
"""Construct a SHA-1 hash object.
129+
130+
"""
131+
# Initial Digest Variables
132+
self._h = (0x67452301,
133+
0xEFCDAB89,
134+
0x98BADCFE,
135+
0x10325476,
136+
0xC3D2E1F0)
137+
138+
self._unprocessed = b''
139+
self._msg_byte_len = 0
140+
141+
def _create_digest(self):
142+
"""Returns finalized digest variables for the data processed so far.
143+
144+
"""
145+
# pre-processing
146+
message = self._unprocessed
147+
message_len = self._msg_byte_len + len(message)
148+
149+
# add trailing '1' bit (+ 0's padding) to string [§5.1.1]
150+
message += b'\x80'
151+
152+
# append 0 <= k < 512 bits '0', so that the resulting message length (in bytes)
153+
# is congruent to 56 (mod 64)
154+
message += b'\x00' * ((56 - (message_len + 1) % 64) % 64)
155+
156+
157+
# append ml, the original message length, as a 64-bit big-endian integer.
158+
message_bit_length = message_len * 8
159+
message += struct.pack(b'>Q', message_bit_length)
160+
161+
# Process the final chunk
162+
# At this point, the length of the message is either 64 or 128 bytes.
163+
h = _hash_computation(message[:64], *self._h)
164+
if len(message) == 64:
165+
return h
166+
return _hash_computation(message[64:], *h)
167+
168+
def update(self, data):
169+
"""Updates the hash object with bytes-like object, data.
170+
:param bytes data: bytearray or bytes object
171+
172+
"""
173+
# if we get a string, convert to a bytearray objects
174+
data = _getbuf(data)
175+
176+
# switch input to bytesio api for easier reading
177+
if isinstance(data, (bytes, bytearray)):
178+
data = BytesIO(data)
179+
180+
# Try to build a chunk out of the unprocessed data, if any
181+
chunk = self._unprocessed + data.read(64 - len(self._unprocessed))
182+
183+
while len(chunk) == 64:
184+
self._h = _hash_computation(chunk, *self._h)
185+
self._msg_byte_len += 64
186+
# read the next 64 bytes
187+
chunk = data.read(64)
188+
189+
self._unprocessed = chunk
190+
return self
191+
192+
def digest(self):
193+
"""Returns the digest of the data passed to the update()
194+
method so far.
195+
196+
"""
197+
return b''.join(struct.pack(b'>I', h) for h in self._create_digest())
198+
199+
def hexdigest(self):
200+
"""Like digest() except the digest is returned as a string object of
201+
double length, containing only hexadecimal digits.
202+
203+
"""
204+
return ''.join(['%.2x' % i for i in self.digest()])

0 commit comments

Comments
 (0)