diff --git a/adafruit_hashlib/__init__.py b/adafruit_hashlib/__init__.py index d0d11e6..633ceb5 100644 --- a/adafruit_hashlib/__init__.py +++ b/adafruit_hashlib/__init__.py @@ -48,9 +48,12 @@ __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_hashlib.git" # FIPS secure hash algorithms supported by this library -ALGOS_AVAIL = ["sha1", "md5", "sha224", "sha256", "sha384", "sha512"] +ALGOS_AVAIL = ["sha1", "MD5", "sha224", "sha256", "sha384", "sha512"] def init(): + """Imports the avaliable algorithm modules. Provides + backwards-compatibility with native hashlib c-module. + """ for i in ALGOS_AVAIL: hash_object = getattr(hashlib, i, None) if not hash_object: @@ -62,6 +65,10 @@ init() def new(algo, data=b""): + """Creates a new hashlib object. + :param str algo: Name of the desired algorithm. + :param str data: First parameter. + """ try: hash_object = globals()[algo] return hash_object(data) @@ -73,4 +80,4 @@ def algorithms_available(): """Returns a list containing the names of the hash algorithms that are available in this module. """ - return ALGOS_AVAIL \ No newline at end of file + return ALGOS_AVAIL diff --git a/adafruit_hashlib/_md5.py b/adafruit_hashlib/_md5.py index 0b9c3d2..ef61e0a 100644 --- a/adafruit_hashlib/_md5.py +++ b/adafruit_hashlib/_md5.py @@ -26,6 +26,8 @@ MD5 Hash Algorithm. * Author(s): Brent Rubell """ -class md5(object): +# pylint: disable=too-few-public-methods +class MD5(): + """RSA MD5 Algorithm class.""" def __init__(self, s=None): raise NotImplementedError("MD5 digests not currently implemented in this module.") diff --git a/adafruit_hashlib/_sha1.py b/adafruit_hashlib/_sha1.py index ded9c97..3e4a624 100755 --- a/adafruit_hashlib/_sha1.py +++ b/adafruit_hashlib/_sha1.py @@ -26,6 +26,8 @@ SHA1 Hash Algorithm. * Author(s): Brent Rubell """ -class sha1(object): +# pylint: disable=too-few-public-methods, invalid-name +class sha1(): + """SHA1 hash algorithm.""" def __init__(self, s=None): raise NotImplementedError("SHA1 digests not currently implemented in this module.") diff --git a/adafruit_hashlib/_sha224.py b/adafruit_hashlib/_sha224.py index 6a97418..341e2bb 100644 --- a/adafruit_hashlib/_sha224.py +++ b/adafruit_hashlib/_sha224.py @@ -26,4 +26,5 @@ SHA224 Hash Algorithm * Author(s): Paul Sokolovsky, Brent Rubell """ +# pylint: disable=unused-import from ._sha256 import sha224 diff --git a/adafruit_hashlib/_sha256.py b/adafruit_hashlib/_sha256.py index e5fb9f3..3212e3f 100644 --- a/adafruit_hashlib/_sha256.py +++ b/adafruit_hashlib/_sha256.py @@ -26,6 +26,7 @@ SHA-256 Hash Algorithm. * Author(s): Tom St Denis, Paul Sokolovsky, Brent Rubell """ +# pylint: disable=invalid-name, unnecessary-lambda, missing-docstring # SHA Block size and message digest sizes, in bytes. SHA_BLOCKSIZE = 64 @@ -54,18 +55,20 @@ Sigma1 = lambda x: (S(x, 6) ^ S(x, 11) ^ S(x, 25)) Gamma0 = lambda x: (S(x, 7) ^ S(x, 18) ^ R(x, 3)) Gamma1 = lambda x: (S(x, 17) ^ S(x, 19) ^ R(x, 10)) +# pylint: disable=too-many-statements def sha_transform(sha_info): W = [] d = sha_info['data'] for i in range(0,16): - W.append( (d[4*i]<<24) + (d[4*i+1]<<16) + (d[4*i+2]<<8) + d[4*i+3]) + W.append((d[4*i]<<24) + (d[4*i+1]<<16) + (d[4*i+2]<<8) + d[4*i+3]) for i in range(16,64): - W.append( (Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]) & 0xffffffff ) + W.append((Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]) & 0xffffffff ) ss = sha_info['digest'][:] + # pylint: disable=too-many-arguments, line-too-long def RND(a,b,c,d,e,f,g,h,i,ki): """Compress""" t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i] @@ -142,13 +145,14 @@ def sha_transform(sha_info): # Feedback dig = [] for i, x in enumerate(sha_info['digest']): - dig.append( (x + ss[i]) & 0xffffffff ) + dig.append((x + ss[i]) & 0xffffffff) sha_info['digest'] = dig def sha_init(): """Initialize the SHA digest.""" sha_info = new_shaobject() - sha_info['digest'] = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19] + sha_info['digest'] = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19] sha_info['count_lo'] = 0 sha_info['count_hi'] = 0 sha_info['local'] = 0 @@ -158,7 +162,8 @@ def sha_init(): def sha224_init(): """Initialize a SHA224 digest.""" sha_info = new_shaobject() - sha_info['digest'] = [0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4] + sha_info['digest'] = [0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4] sha_info['count_lo'] = 0 sha_info['count_hi'] = 0 sha_info['local'] = 0 @@ -168,8 +173,7 @@ def sha224_init(): def getbuf(s): if isinstance(s, str): return s.encode('ascii') - else: - return bytes(s) + return bytes(s) def sha_update(sha_info, buffer): """Update the SHA digest. @@ -184,36 +188,36 @@ def sha_update(sha_info, buffer): if clo < sha_info['count_lo']: sha_info['count_hi'] += 1 sha_info['count_lo'] = clo - + sha_info['count_hi'] += (count >> 29) - + if sha_info['local']: i = SHA_BLOCKSIZE - sha_info['local'] if i > count: i = count - + # copy buffer 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 - + sha_info['local'] += i if sha_info['local'] == SHA_BLOCKSIZE: sha_transform(sha_info) sha_info['local'] = 0 else: return - + while count >= SHA_BLOCKSIZE: # copy buffer sha_info['data'] = list(buffer[buffer_idx:buffer_idx + SHA_BLOCKSIZE]) count -= SHA_BLOCKSIZE buffer_idx += SHA_BLOCKSIZE sha_transform(sha_info) - - + + # copy buffer pos = sha_info['local'] sha_info['data'][pos:pos+count] = list(buffer[buffer_idx:buffer_idx + count]) @@ -234,7 +238,7 @@ def sha_final(sha_info): sha_info['data'] = [0] * SHA_BLOCKSIZE else: sha_info['data'] = sha_info['data'][:count] + ([0] * (SHA_BLOCKSIZE - count)) - + sha_info['data'][56] = (hi_bit_count >> 24) & 0xff sha_info['data'][57] = (hi_bit_count >> 16) & 0xff sha_info['data'][58] = (hi_bit_count >> 8) & 0xff @@ -243,46 +247,64 @@ def sha_final(sha_info): sha_info['data'][61] = (lo_bit_count >> 16) & 0xff sha_info['data'][62] = (lo_bit_count >> 8) & 0xff sha_info['data'][63] = (lo_bit_count >> 0) & 0xff - + sha_transform(sha_info) - + dig = [] for i in sha_info['digest']: - dig.extend([ ((i>>24) & 0xff), ((i>>16) & 0xff), ((i>>8) & 0xff), (i & 0xff) ]) + dig.extend([((i>>24) & 0xff), ((i>>16) & 0xff), ((i>>8) & 0xff), (i & 0xff)]) return bytes(dig) -class sha256(object): +# pylint: disable=protected-access +class sha256(): digest_size = digestsize = SHA_DIGESTSIZE block_size = SHA_BLOCKSIZE + name = "sha256" def __init__(self, s=None): + """Constructs a SHA256 hash object. + """ self._sha = sha_init() if s: sha_update(self._sha, getbuf(s)) - + def update(self, s): + """Updates the hash object with a bytes-like object, s.""" sha_update(self._sha, getbuf(s)) - + def digest(self): + """Returns the digest of the data passed to the update() + method so far.""" return sha_final(self._sha.copy())[:self._sha['digestsize']] - + def hexdigest(self): + """Like digest() except the digest is returned as a string object of + double length, containing only hexadecimal digits. + """ return ''.join(['%.2x' % i for i in self.digest()]) def copy(self): + """Return a copy (“clone”) of the hash object. + """ new = sha256() new._sha = self._sha.copy() return new +# pylint: disable=protected-access, (super-init-not-called) class sha224(sha256): digest_size = digestsize = 28 + name = "sha224" def __init__(self, s=None): + """Constructs a SHA224 hash object. + """ self._sha = sha224_init() if s: sha_update(self._sha, getbuf(s)) def copy(self): + """Return a copy (“clone”) of the hash object. + """ new = sha224() new._sha = self._sha.copy() return new