diff --git a/hashlib/hashlib.py b/hashlib/hashlib.py deleted file mode 100644 index e69de29b..00000000 diff --git a/hashlib/hashlib/__init__.py b/hashlib/hashlib/__init__.py new file mode 100644 index 00000000..2d2c0b19 --- /dev/null +++ b/hashlib/hashlib/__init__.py @@ -0,0 +1,2 @@ +from .sha256 import * +from .sha512 import * diff --git a/hashlib/hashlib/sha224.py b/hashlib/hashlib/sha224.py new file mode 100644 index 00000000..e413a1a5 --- /dev/null +++ b/hashlib/hashlib/sha224.py @@ -0,0 +1 @@ +from .sha256 import sha224 diff --git a/hashlib/hashlib/sha256.py b/hashlib/hashlib/sha256.py index 5fcf13d5..8c013b5f 100644 --- a/hashlib/hashlib/sha256.py +++ b/hashlib/hashlib/sha256.py @@ -129,6 +129,12 @@ def sha224_init(): sha_info['digestsize'] = 28 return sha_info +def getbuf(s): + if isinstance(s, str): + return s.encode('ascii') + else: + return bytes(s) + def sha_update(sha_info, buffer): if isinstance(buffer, str): raise TypeError("Unicode strings must be encoded before hashing") @@ -147,7 +153,8 @@ def sha_update(sha_info, buffer): i = count # copy buffer - sha_info['data'][sha_info['local']:sha_info['local']+i] = buffer[buffer_idx:buffer_idx+i] + for x in enumerate(buffer[buffer_idx:buffer_idx+i]): + sha_info['data'][sha_info['local']+x[0]] = x[1] count -= i buffer_idx += i @@ -169,7 +176,7 @@ def sha_update(sha_info, buffer): # copy buffer pos = sha_info['local'] - sha_info['data'][pos:pos+count] = buffer[buffer_idx:buffer_idx + count] + sha_info['data'][pos:pos+count] = list(buffer[buffer_idx:buffer_idx + count]) sha_info['local'] = count def sha_final(sha_info): @@ -201,7 +208,7 @@ def sha_final(sha_info): dig = [] for i in sha_info['digest']: dig.extend([ ((i>>24) & 0xff), ((i>>16) & 0xff), ((i>>8) & 0xff), (i & 0xff) ]) - return ''.join([chr(i) for i in dig]) + return bytes(dig) class sha256(object): digest_size = digestsize = SHA_DIGESTSIZE @@ -210,19 +217,19 @@ class sha256(object): def __init__(self, s=None): self._sha = sha_init() if s: - sha_update(self._sha, s) + sha_update(self._sha, getbuf(s)) def update(self, s): - sha_update(self._sha, s) + sha_update(self._sha, getbuf(s)) def digest(self): return sha_final(self._sha.copy())[:self._sha['digestsize']] def hexdigest(self): - return ''.join(['%.2x' % ord(i) for i in self.digest()]) + return ''.join(['%.2x' % i for i in self.digest()]) def copy(self): - new = sha256.__new__(sha256) + new = sha256() new._sha = self._sha.copy() return new @@ -232,16 +239,17 @@ class sha224(sha256): def __init__(self, s=None): self._sha = sha224_init() if s: - sha_update(self._sha, s) + sha_update(self._sha, getbuf(s)) def copy(self): - new = sha224.__new__(sha224) + new = sha224() new._sha = self._sha.copy() return new def test(): a_str = "just a test string" + 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() assert 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' == sha256().hexdigest() assert 'd7b553c6f09ac85d142415f857c5310f3bbbe7cdd787cce4b985acedd585266f' == sha256(a_str).hexdigest() assert '8113ebf33c97daa9998762aacafe750c7cefc2b2f173c90c59663a57fe626f21' == sha256(a_str*7).hexdigest() diff --git a/hashlib/hashlib/sha384.py b/hashlib/hashlib/sha384.py new file mode 100644 index 00000000..5a9fd1df --- /dev/null +++ b/hashlib/hashlib/sha384.py @@ -0,0 +1 @@ +from .sha512 import sha384 diff --git a/hashlib/hashlib/sha512.py b/hashlib/hashlib/sha512.py index 98ed0b94..8875db2e 100644 --- a/hashlib/hashlib/sha512.py +++ b/hashlib/hashlib/sha512.py @@ -149,6 +149,12 @@ def sha384_init(): sha_info['digestsize'] = 48 return sha_info +def getbuf(s): + if isinstance(s, str): + return s.encode('ascii') + else: + return bytes(s) + def sha_update(sha_info, buffer): if isinstance(buffer, str): raise TypeError("Unicode strings must be encoded before hashing") @@ -167,7 +173,8 @@ def sha_update(sha_info, buffer): i = count # copy buffer - sha_info['data'][sha_info['local']:sha_info['local']+i] = buffer[buffer_idx:buffer_idx+i] + for x in enumerate(buffer[buffer_idx:buffer_idx+i]): + sha_info['data'][sha_info['local']+x[0]] = x[1] count -= i buffer_idx += i @@ -188,7 +195,7 @@ def sha_update(sha_info, buffer): # copy buffer pos = sha_info['local'] - sha_info['data'][pos:pos+count] = buffer[buffer_idx:buffer_idx + count] + sha_info['data'][pos:pos+count] = list(buffer[buffer_idx:buffer_idx + count]) sha_info['local'] = count def sha_final(sha_info): @@ -238,10 +245,10 @@ class sha512(object): def __init__(self, s=None): self._sha = sha_init() if s: - sha_update(self._sha, s) + sha_update(self._sha, getbuf(s)) def update(self, s): - sha_update(self._sha, s) + sha_update(self._sha, getbuf(s)) def digest(self): return sha_final(self._sha.copy())[:self._sha['digestsize']] @@ -250,7 +257,7 @@ class sha512(object): return ''.join(['%.2x' % i for i in self.digest()]) def copy(self): - new = sha512.__new__(sha512) + new = sha512() new._sha = self._sha.copy() return new @@ -260,25 +267,24 @@ class sha384(sha512): def __init__(self, s=None): self._sha = sha384_init() if s: - sha_update(self._sha, s) + sha_update(self._sha, getbuf(s)) def copy(self): - new = sha384.__new__(sha384) + new = sha384() new._sha = self._sha.copy() return new def test(): - import _sha512 - a_str = "just a test string" - assert _sha512.sha512().hexdigest() == sha512().hexdigest() - assert _sha512.sha512(a_str).hexdigest() == sha512(a_str).hexdigest() - assert _sha512.sha512(a_str*7).hexdigest() == sha512(a_str*7).hexdigest() + 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>" + assert sha512().hexdigest() == 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e' + assert sha512(a_str).hexdigest() == '68be4c6664af867dd1d01c8d77e963d87d77b702400c8fabae355a41b8927a5a5533a7f1c28509bbd65c5f3ac716f33be271fbda0ca018b71a84708c9fae8a53' + assert sha512(a_str*7).hexdigest() == '3233acdbfcfff9bff9fc72401d31dbffa62bd24e9ec846f0578d647da73258d9f0879f7fde01fe2cc6516af3f343807fdef79e23d696c923d79931db46bf1819' s = sha512(a_str) s.update(a_str) - assert _sha512.sha512(a_str+a_str).hexdigest() == s.hexdigest() + assert s.hexdigest() == '341aeb668730bbb48127d5531115f3c39d12cb9586a6ca770898398aff2411087cfe0b570689adf328cddeb1f00803acce6737a19f310b53bbdb0320828f75bb' if __name__ == "__main__": test() diff --git a/hashlib/setup.py b/hashlib/setup.py index 3de13d5a..de463a01 100644 --- a/hashlib/setup.py +++ b/hashlib/setup.py @@ -7,7 +7,7 @@ from setuptools import setup setup(name='micropython-hashlib', version='0.0.1', - description='Dummy hashlib module for MicroPython', + description='Implementation of basic hashlib functions for MicroPython', 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.', url='https://github.com/micropython/micropython/issues/405', author='MicroPython Developers', @@ -15,4 +15,4 @@ setup(name='micropython-hashlib', maintainer='MicroPython Developers', maintainer_email='micro-python@googlegroups.com', license='MIT', - py_modules=['hashlib']) + packages=['hashlib']) diff --git a/hashlib/test_hashlib.py b/hashlib/test_hashlib.py new file mode 100644 index 00000000..9f8dec58 --- /dev/null +++ b/hashlib/test_hashlib.py @@ -0,0 +1,7 @@ +from hashlib.sha256 import test as sha256_test +from hashlib.sha512 import test as sha512_test + + +sha256_test() +sha512_test() +print("OK")