# -*- coding: utf-8 -*- # # =================================================================== # The contents of this file are dedicated to the public domain. To # the extent that dedication to the public domain is not available, # everyone is granted a worldwide, perpetual, royalty-free, # non-exclusive license to exercise all rights associated with the # contents of this file for any purpose whatsoever. # No rights are reserved. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # =================================================================== """Hashing algorithms Hash functions take arbitrary binary strings as input, and produce a random-like output of fixed size that is dependent on the input; it should be practically infeasible to derive the original input data given only the hash function's output. In other words, the hash function is *one-way*. It should also not be practically feasible to find a second piece of data (a *second pre-image*) whose hash is the same as the original message (*weak collision resistance*). Finally, it should not be feasible to find two arbitrary messages with the same hash (*strong collision resistance*). The output of the hash function is called the *digest* of the input message. In general, the security of a hash function is related to the length of the digest. If the digest is *n* bits long, its security level is roughly comparable to the the one offered by an *n/2* bit encryption algorithm. Hash functions can be used simply as a integrity check, or, in association with a public-key algorithm, can be used to implement digital signatures. The hashing modules here all support the interface described in `PEP 247`_ , "API for Cryptographic Hash Functions". .. _`PEP 247` : http://www.python.org/dev/peps/pep-0247/ :undocumented: _MD2, _MD4, _RIPEMD160, _SHA224, _SHA256, _SHA384, _SHA512 """ __all__ = ['HMAC', 'MD2', 'MD4', 'MD5', 'RIPEMD160', 'SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'CMAC'] __revision__ = "$Id$" import sys if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * def new(algo, *args): """Initialize a new hash object. The first argument to this function may be an algorithm name or another hash object. This function has significant overhead. It's recommended that you instead import and use the individual hash modules directly. """ # Try just invoking algo.new() # We do this first so that this is the fastest. try: new_func = algo.new except AttributeError: pass else: return new_func(*args) # Try getting the algorithm name. if isinstance(algo, str): name = algo else: try: name = algo.name except AttributeError: raise ValueError("unsupported hash type %r" % (algo,)) # Got the name. Let's see if we have a PyCrypto implementation. try: new_func = _new_funcs[name] except KeyError: # No PyCrypto implementation. Try hashlib. try: import hashlib except ImportError: # There is no hashlib. raise ValueError("unsupported hash type %s" % (name,)) return hashlib.new(name, *args) else: # We have a PyCrypto implementation. Instantiate it. return new_func(*args) # This dict originally gets the following _*_new methods, but its members get # replaced with the real new() methods of the various hash modules as they are # used. We do it without locks to improve performance, which is safe in # CPython because dict access is atomic in CPython. This might break PyPI. _new_funcs = {} def _md2_new(*args): from Crypto.Hash import MD2 _new_funcs['MD2'] = _new_funcs['md2'] = MD2.new return MD2.new(*args) _new_funcs['MD2'] = _new_funcs['md2'] = _md2_new del _md2_new def _md4_new(*args): from Crypto.Hash import MD4 _new_funcs['MD4'] = _new_funcs['md4'] = MD4.new return MD4.new(*args) _new_funcs['MD4'] = _new_funcs['md4'] = _md4_new del _md4_new def _md5_new(*args): from Crypto.Hash import MD5 _new_funcs['MD5'] = _new_funcs['md5'] = MD5.new return MD5.new(*args) _new_funcs['MD5'] = _new_funcs['md5'] = _md5_new del _md5_new def _ripemd160_new(*args): from Crypto.Hash import RIPEMD160 _new_funcs['RIPEMD160'] = _new_funcs['ripemd160'] = \ _new_funcs['RIPEMD'] = _new_funcs['ripemd'] = RIPEMD160.new return RIPEMD160.new(*args) _new_funcs['RIPEMD160'] = _new_funcs['ripemd160'] = \ _new_funcs['RIPEMD'] = _new_funcs['ripemd'] = _ripemd160_new del _ripemd160_new def _sha1_new(*args): from Crypto.Hash import SHA1 _new_funcs['SHA1'] = _new_funcs['sha1'] = \ _new_funcs['SHA'] = _new_funcs['sha'] = SHA1.new return SHA1.new(*args) _new_funcs['SHA1'] = _new_funcs['sha1'] = \ _new_funcs['SHA'] = _new_funcs['sha'] = _sha1_new del _sha1_new def _sha224_new(*args): from Crypto.Hash import SHA224 _new_funcs['SHA224'] = _new_funcs['sha224'] = SHA224.new return SHA224.new(*args) _new_funcs['SHA224'] = _new_funcs['sha224'] = _sha224_new del _sha224_new def _sha256_new(*args): from Crypto.Hash import SHA256 _new_funcs['SHA256'] = _new_funcs['sha256'] = SHA256.new return SHA256.new(*args) _new_funcs['SHA256'] = _new_funcs['sha256'] = _sha256_new del _sha256_new def _sha384_new(*args): from Crypto.Hash import SHA384 _new_funcs['SHA384'] = _new_funcs['sha384'] = SHA384.new return SHA384.new(*args) _new_funcs['SHA384'] = _new_funcs['sha384'] = _sha384_new del _sha384_new def _sha512_new(*args): from Crypto.Hash import SHA512 _new_funcs['SHA512'] = _new_funcs['sha512'] = SHA512.new return SHA512.new(*args) _new_funcs['SHA512'] = _new_funcs['sha512'] = _sha512_new del _sha512_new