Skip to content

Commit 752c145

Browse files
admin-slushpfalcon
authored andcommitted
hashlib: Port pure-Python algos of sha224, sha256, sha384, sha512 to uPy.
1 parent 6c0c7f8 commit 752c145

File tree

8 files changed

+49
-24
lines changed

8 files changed

+49
-24
lines changed

hashlib/hashlib.py

Whitespace-only changes.

hashlib/hashlib/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .sha256 import *
2+
from .sha512 import *

hashlib/hashlib/sha224.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .sha256 import sha224

hashlib/hashlib/sha256.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ def sha224_init():
129129
sha_info['digestsize'] = 28
130130
return sha_info
131131

132+
def getbuf(s):
133+
if isinstance(s, str):
134+
return s.encode('ascii')
135+
else:
136+
return bytes(s)
137+
132138
def sha_update(sha_info, buffer):
133139
if isinstance(buffer, str):
134140
raise TypeError("Unicode strings must be encoded before hashing")
@@ -147,7 +153,8 @@ def sha_update(sha_info, buffer):
147153
i = count
148154

149155
# copy buffer
150-
sha_info['data'][sha_info['local']:sha_info['local']+i] = buffer[buffer_idx:buffer_idx+i]
156+
for x in enumerate(buffer[buffer_idx:buffer_idx+i]):
157+
sha_info['data'][sha_info['local']+x[0]] = x[1]
151158

152159
count -= i
153160
buffer_idx += i
@@ -169,7 +176,7 @@ def sha_update(sha_info, buffer):
169176

170177
# copy buffer
171178
pos = sha_info['local']
172-
sha_info['data'][pos:pos+count] = buffer[buffer_idx:buffer_idx + count]
179+
sha_info['data'][pos:pos+count] = list(buffer[buffer_idx:buffer_idx + count])
173180
sha_info['local'] = count
174181

175182
def sha_final(sha_info):
@@ -201,7 +208,7 @@ def sha_final(sha_info):
201208
dig = []
202209
for i in sha_info['digest']:
203210
dig.extend([ ((i>>24) & 0xff), ((i>>16) & 0xff), ((i>>8) & 0xff), (i & 0xff) ])
204-
return ''.join([chr(i) for i in dig])
211+
return bytes(dig)
205212

206213
class sha256(object):
207214
digest_size = digestsize = SHA_DIGESTSIZE
@@ -210,19 +217,19 @@ class sha256(object):
210217
def __init__(self, s=None):
211218
self._sha = sha_init()
212219
if s:
213-
sha_update(self._sha, s)
220+
sha_update(self._sha, getbuf(s))
214221

215222
def update(self, s):
216-
sha_update(self._sha, s)
223+
sha_update(self._sha, getbuf(s))
217224

218225
def digest(self):
219226
return sha_final(self._sha.copy())[:self._sha['digestsize']]
220227

221228
def hexdigest(self):
222-
return ''.join(['%.2x' % ord(i) for i in self.digest()])
229+
return ''.join(['%.2x' % i for i in self.digest()])
223230

224231
def copy(self):
225-
new = sha256.__new__(sha256)
232+
new = sha256()
226233
new._sha = self._sha.copy()
227234
return new
228235

@@ -232,16 +239,17 @@ class sha224(sha256):
232239
def __init__(self, s=None):
233240
self._sha = sha224_init()
234241
if s:
235-
sha_update(self._sha, s)
242+
sha_update(self._sha, getbuf(s))
236243

237244
def copy(self):
238-
new = sha224.__new__(sha224)
245+
new = sha224()
239246
new._sha = self._sha.copy()
240247
return new
241248

242249
def test():
243250
a_str = "just a test string"
244251

252+
assert b"\xe3\xb0\xc4B\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99o\xb9$'\xaeA\xe4d\x9b\x93L\xa4\x95\x99\x1bxR\xb8U" == sha256().digest()
245253
assert 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' == sha256().hexdigest()
246254
assert 'd7b553c6f09ac85d142415f857c5310f3bbbe7cdd787cce4b985acedd585266f' == sha256(a_str).hexdigest()
247255
assert '8113ebf33c97daa9998762aacafe750c7cefc2b2f173c90c59663a57fe626f21' == sha256(a_str*7).hexdigest()

hashlib/hashlib/sha384.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .sha512 import sha384

hashlib/hashlib/sha512.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ def sha384_init():
149149
sha_info['digestsize'] = 48
150150
return sha_info
151151

152+
def getbuf(s):
153+
if isinstance(s, str):
154+
return s.encode('ascii')
155+
else:
156+
return bytes(s)
157+
152158
def sha_update(sha_info, buffer):
153159
if isinstance(buffer, str):
154160
raise TypeError("Unicode strings must be encoded before hashing")
@@ -167,7 +173,8 @@ def sha_update(sha_info, buffer):
167173
i = count
168174

169175
# copy buffer
170-
sha_info['data'][sha_info['local']:sha_info['local']+i] = buffer[buffer_idx:buffer_idx+i]
176+
for x in enumerate(buffer[buffer_idx:buffer_idx+i]):
177+
sha_info['data'][sha_info['local']+x[0]] = x[1]
171178

172179
count -= i
173180
buffer_idx += i
@@ -188,7 +195,7 @@ def sha_update(sha_info, buffer):
188195

189196
# copy buffer
190197
pos = sha_info['local']
191-
sha_info['data'][pos:pos+count] = buffer[buffer_idx:buffer_idx + count]
198+
sha_info['data'][pos:pos+count] = list(buffer[buffer_idx:buffer_idx + count])
192199
sha_info['local'] = count
193200

194201
def sha_final(sha_info):
@@ -238,10 +245,10 @@ class sha512(object):
238245
def __init__(self, s=None):
239246
self._sha = sha_init()
240247
if s:
241-
sha_update(self._sha, s)
248+
sha_update(self._sha, getbuf(s))
242249

243250
def update(self, s):
244-
sha_update(self._sha, s)
251+
sha_update(self._sha, getbuf(s))
245252

246253
def digest(self):
247254
return sha_final(self._sha.copy())[:self._sha['digestsize']]
@@ -250,7 +257,7 @@ def hexdigest(self):
250257
return ''.join(['%.2x' % i for i in self.digest()])
251258

252259
def copy(self):
253-
new = sha512.__new__(sha512)
260+
new = sha512()
254261
new._sha = self._sha.copy()
255262
return new
256263

@@ -260,25 +267,24 @@ class sha384(sha512):
260267
def __init__(self, s=None):
261268
self._sha = sha384_init()
262269
if s:
263-
sha_update(self._sha, s)
270+
sha_update(self._sha, getbuf(s))
264271

265272
def copy(self):
266-
new = sha384.__new__(sha384)
273+
new = sha384()
267274
new._sha = self._sha.copy()
268275
return new
269276

270277
def test():
271-
import _sha512
272-
273278
a_str = "just a test string"
274279

275-
assert _sha512.sha512().hexdigest() == sha512().hexdigest()
276-
assert _sha512.sha512(a_str).hexdigest() == sha512(a_str).hexdigest()
277-
assert _sha512.sha512(a_str*7).hexdigest() == sha512(a_str*7).hexdigest()
280+
assert sha512().digest() == b"\xcf\x83\xe15~\xef\xb8\xbd\xf1T(P\xd6m\x80\x07\xd6 \xe4\x05\x0bW\x15\xdc\x83\xf4\xa9!\xd3l\xe9\xceG\xd0\xd1<]\x85\xf2\xb0\xff\x83\x18\xd2\x87~\xec/c\xb91\xbdGAz\x81\xa582z\xf9'\xda>"
281+
assert sha512().hexdigest() == 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
282+
assert sha512(a_str).hexdigest() == '68be4c6664af867dd1d01c8d77e963d87d77b702400c8fabae355a41b8927a5a5533a7f1c28509bbd65c5f3ac716f33be271fbda0ca018b71a84708c9fae8a53'
283+
assert sha512(a_str*7).hexdigest() == '3233acdbfcfff9bff9fc72401d31dbffa62bd24e9ec846f0578d647da73258d9f0879f7fde01fe2cc6516af3f343807fdef79e23d696c923d79931db46bf1819'
278284

279285
s = sha512(a_str)
280286
s.update(a_str)
281-
assert _sha512.sha512(a_str+a_str).hexdigest() == s.hexdigest()
287+
assert s.hexdigest() == '341aeb668730bbb48127d5531115f3c39d12cb9586a6ca770898398aff2411087cfe0b570689adf328cddeb1f00803acce6737a19f310b53bbdb0320828f75bb'
282288

283289
if __name__ == "__main__":
284290
test()

hashlib/setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77

88
setup(name='micropython-hashlib',
99
version='0.0.1',
10-
description='Dummy hashlib module for MicroPython',
10+
description='Implementation of basic hashlib functions for MicroPython',
1111
long_description='This is a dummy implementation of a module for MicroPython standard library.\nIt contains zero or very little functionality, and primarily intended to\navoid import errors (using idea that even if an application imports a\nmodule, it may be not using it onevery code path, so may work at least\npartially). It is expected that more complete implementation of the module\nwill be provided later. Please help with the development if you are\ninterested in this module.',
1212
url='https://github.com/micropython/micropython/issues/405',
1313
author='MicroPython Developers',
1414
author_email='[email protected]',
1515
maintainer='MicroPython Developers',
1616
maintainer_email='[email protected]',
1717
license='MIT',
18-
py_modules=['hashlib'])
18+
packages=['hashlib'])

hashlib/test_hashlib.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from hashlib.sha256 import test as sha256_test
2+
from hashlib.sha512 import test as sha512_test
3+
4+
5+
sha256_test()
6+
sha512_test()
7+
print("OK")

0 commit comments

Comments
 (0)