diff options
Diffstat (limited to 'Lib/hashlib.py')
-rw-r--r-- | Lib/hashlib.py | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/Lib/hashlib.py b/Lib/hashlib.py index 316cece..053a7ad 100644 --- a/Lib/hashlib.py +++ b/Lib/hashlib.py @@ -4,14 +4,15 @@ __doc__ = """hashlib module - A common interface to many hash functions. -new(name, data=b'') - returns a new hash object implementing the - given hash function; initializing the hash - using the given binary data. +new(name, data=b'', **kwargs) - returns a new hash object implementing the + given hash function; initializing the hash + using the given binary data. Named constructor functions are also available, these are faster than using new(name): -md5(), sha1(), sha224(), sha256(), sha384(), and sha512() +md5(), sha1(), sha224(), sha256(), sha384(), sha512(), blake2b(), blake2s(), +sha3_224, sha3_256, sha3_384, sha3_512, shake_128, and shake_256. More algorithms may be available on your platform but the above are guaranteed to exist. See the algorithms_guaranteed and algorithms_available attributes @@ -54,7 +55,11 @@ More condensed: # This tuple and __get_builtin_constructor() must be modified if a new # always available algorithm is added. -__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512') +__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', + 'blake2b', 'blake2s', + 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', + 'shake_128', 'shake_256') + algorithms_guaranteed = set(__always_supported) algorithms_available = set(__always_supported) @@ -85,6 +90,19 @@ def __get_builtin_constructor(name): import _sha512 cache['SHA384'] = cache['sha384'] = _sha512.sha384 cache['SHA512'] = cache['sha512'] = _sha512.sha512 + elif name in ('blake2b', 'blake2s'): + import _blake2 + cache['blake2b'] = _blake2.blake2b + cache['blake2s'] = _blake2.blake2s + elif name in {'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', + 'shake_128', 'shake_256'}: + import _sha3 + cache['sha3_224'] = _sha3.sha3_224 + cache['sha3_256'] = _sha3.sha3_256 + cache['sha3_384'] = _sha3.sha3_384 + cache['sha3_512'] = _sha3.sha3_512 + cache['shake_128'] = _sha3.shake_128 + cache['shake_256'] = _sha3.shake_256 except ImportError: pass # no extension module, this hash is unsupported. @@ -96,6 +114,9 @@ def __get_builtin_constructor(name): def __get_openssl_constructor(name): + if name in {'blake2b', 'blake2s'}: + # Prefer our blake2 implementation. + return __get_builtin_constructor(name) try: f = getattr(_hashlib, 'openssl_' + name) # Allow the C module to raise ValueError. The function will be @@ -107,17 +128,23 @@ def __get_openssl_constructor(name): return __get_builtin_constructor(name) -def __py_new(name, data=b''): - """new(name, data=b'') - Return a new hashing object using the named algorithm; - optionally initialized with data (which must be bytes). +def __py_new(name, data=b'', **kwargs): + """new(name, data=b'', **kwargs) - Return a new hashing object using the + named algorithm; optionally initialized with data (which must be bytes). """ - return __get_builtin_constructor(name)(data) + return __get_builtin_constructor(name)(data, **kwargs) -def __hash_new(name, data=b''): +def __hash_new(name, data=b'', **kwargs): """new(name, data=b'') - Return a new hashing object using the named algorithm; optionally initialized with data (which must be bytes). """ + if name in {'blake2b', 'blake2s'}: + # Prefer our blake2 implementation. + # OpenSSL 1.1.0 comes with a limited implementation of blake2b/s. + # It does neither support keyed blake2 nor advanced features like + # salt, personal, tree hashing or SSE. + return __get_builtin_constructor(name)(data, **kwargs) try: return _hashlib.new(name, data) except ValueError: @@ -202,6 +229,12 @@ except ImportError: return dkey[:dklen] +try: + # OpenSSL's scrypt requires OpenSSL 1.1+ + from _hashlib import scrypt +except ImportError: + pass + for __func_name in __always_supported: # try them all, some may not work due to the OpenSSL @@ -212,6 +245,7 @@ for __func_name in __always_supported: import logging logging.exception('code for hash %s was not found.', __func_name) + # Cleanup locals() del __always_supported, __func_name, __get_hash del __py_new, __hash_new, __get_openssl_constructor |