diff options
-rw-r--r-- | lib/Crypto/Hash/MD2.py | 81 | ||||
-rw-r--r-- | lib/Crypto/Hash/MD4.py | 81 | ||||
-rw-r--r-- | lib/Crypto/Hash/MD5.py | 90 | ||||
-rw-r--r-- | lib/Crypto/Hash/RIPEMD160.py | 84 | ||||
-rw-r--r-- | lib/Crypto/Hash/SHA1.py | 91 | ||||
-rw-r--r-- | lib/Crypto/Hash/SHA224.py | 85 | ||||
-rw-r--r-- | lib/Crypto/Hash/SHA256.py | 85 | ||||
-rw-r--r-- | lib/Crypto/Hash/SHA384.py | 86 | ||||
-rw-r--r-- | lib/Crypto/Hash/SHA512.py | 85 | ||||
-rw-r--r-- | lib/Crypto/Hash/hashalgo.py | 120 | ||||
-rw-r--r-- | lib/Crypto/SelfTest/Hash/common.py | 26 | ||||
-rw-r--r-- | lib/Crypto/Signature/PKCS1_PSS.py | 19 | ||||
-rw-r--r-- | setup.py | 14 | ||||
-rw-r--r-- | src/MD2.c | 29 | ||||
-rw-r--r-- | src/MD4.c | 20 | ||||
-rw-r--r-- | src/RIPEMD160.c | 23 | ||||
-rw-r--r-- | src/SHA224.c | 19 | ||||
-rw-r--r-- | src/SHA256.c | 21 | ||||
-rw-r--r-- | src/SHA384.c | 19 | ||||
-rw-r--r-- | src/SHA512.c | 19 | ||||
-rw-r--r-- | src/hash_template.c | 22 |
21 files changed, 274 insertions, 845 deletions
diff --git a/lib/Crypto/Hash/MD2.py b/lib/Crypto/Hash/MD2.py deleted file mode 100644 index a2e8b31..0000000 --- a/lib/Crypto/Hash/MD2.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- 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. -# =================================================================== - -"""MD2 cryptographic hash algorithm. - -MD2 is specified in RFC1319_ and it produces the 128 bit digest of a message. - - >>> from Crypto.Hash import MD2 - >>> - >>> h = MD2.new() - >>> h.update(b'Hello') - >>> print h.hexdigest() - -MD2 stand for Message Digest version 2, and it was invented by Rivest in 1989. - -This algorithm is both slow and insecure. Do not use it for new designs. - -.. _RFC1319: http://tools.ietf.org/html/rfc1319 -""" - -_revision__ = "$Id$" - -__all__ = ['new', 'digest_size', 'MD2Hash' ] - -from Crypto.Util.py3compat import * -from Crypto.Hash.hashalgo import HashAlgo - -import Crypto.Hash._MD2 as _MD2 -hashFactory = _MD2 - -class MD2Hash(HashAlgo): - """Class that implements an MD2 hash - - :undocumented: block_size - """ - - digest_size = 16 - block_size = 16 - - def __init__(self, data=None): - HashAlgo.__init__(self, hashFactory, data) - - def new(self, data=None): - return MD2Hash(data) - -def new(data=None): - """Return a fresh instance of the hash object. - - :Parameters: - data : byte string - The very first chunk of the message to hash. - It is equivalent to an early call to `MD2Hash.update()`. - Optional. - - :Return: An `MD2Hash` object - """ - return MD2Hash().new(data) - -#: The size of the resulting hash in bytes. -digest_size = MD2Hash.digest_size - -#: The internal block size of the hash algorithm in bytes. -block_size = MD2Hash.block_size - diff --git a/lib/Crypto/Hash/MD4.py b/lib/Crypto/Hash/MD4.py deleted file mode 100644 index 4f0b6bb..0000000 --- a/lib/Crypto/Hash/MD4.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- 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. -# =================================================================== - -"""MD4 cryptographic hash algorithm. - -MD4 is specified in RFC1320_ and produces the 128 bit digest of a message. - - >>> from Crypto.Hash import MD4 - >>> - >>> h = MD4.new() - >>> h.update(b'Hello') - >>> print h.hexdigest() - -MD4 stand for Message Digest version 4, and it was invented by Rivest in 1990. - -This algorithm is insecure. Do not use it for new designs. - -.. _RFC1320: http://tools.ietf.org/html/rfc1320 -""" - -_revision__ = "$Id$" - -__all__ = ['new', 'digest_size', 'MD4Hash' ] - -from Crypto.Util.py3compat import * -from Crypto.Hash.hashalgo import HashAlgo - -import Crypto.Hash._MD4 as _MD4 -hashFactory = _MD4 - -class MD4Hash(HashAlgo): - """Class that implements an MD4 hash - - :undocumented: block_size - """ - - digest_size = 16 - block_size = 64 - - def __init__(self, data=None): - HashAlgo.__init__(self, hashFactory, data) - - def new(self, data=None): - return MD4Hash(data) - -def new(data=None): - """Return a fresh instance of the hash object. - - :Parameters: - data : byte string - The very first chunk of the message to hash. - It is equivalent to an early call to `MD4Hash.update()`. - Optional. - - :Return: A `MD4Hash` object - """ - return MD4Hash().new(data) - -#: The size of the resulting hash in bytes. -digest_size = MD4Hash.digest_size - -#: The internal block size of the hash algorithm in bytes. -block_size = MD4Hash.block_size - diff --git a/lib/Crypto/Hash/MD5.py b/lib/Crypto/Hash/MD5.py index 2e6a01b..c5df793 100644 --- a/lib/Crypto/Hash/MD5.py +++ b/lib/Crypto/Hash/MD5.py @@ -35,54 +35,58 @@ This algorithm is insecure. Do not use it for new designs. .. _RFC1321: http://tools.ietf.org/html/rfc1321 """ +from __future__ import nested_scopes + _revision__ = "$Id$" -__all__ = ['new', 'digest_size', 'MD5Hash' ] +__all__ = ['new', 'block_size', 'digest_size'] from Crypto.Util.py3compat import * -from Crypto.Hash.hashalgo import HashAlgo - -try: - # The md5 module is deprecated in Python 2.6, so use hashlib when possible. - import hashlib - hashFactory = hashlib.md5 - -except ImportError: - import md5 - hashFactory = md5 - -class MD5Hash(HashAlgo): - """Class that implements an MD5 hash - - :undocumented: block_size - """ - - digest_size = 16 - block_size = 64 - - def __init__(self, data=None): - self.name = "MD5" - HashAlgo.__init__(self, hashFactory, data) - - def new(self, data=None): - return MD5Hash(data) - -def new(data=None): - """Return a fresh instance of the hash object. - - :Parameters: - data : byte string - The very first chunk of the message to hash. - It is equivalent to an early call to `MD5Hash.update()`. - Optional. - - :Return: A `MD5Hash` object - """ - return MD5Hash().new(data) +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * + +def __make_constructor(): + try: + # The md5 module is deprecated in Python 2.6, so use hashlib when possible. + from hashlib import md5 as _hash_new + except ImportError: + from md5 import new as _hash_new + + h = _hash_new() + if hasattr(h, 'new') and hasattr(h, 'name') and hasattr(h, 'digest_size') and hasattr(h, 'block_size'): + # The module from stdlib has the API that we need. Just use it. + return _hash_new + else: + # Wrap the hash object in something that gives us the expected API. + _copy_sentinel = object() + class _MD5(object): + digest_size = 16 + block_size = 64 + name = "md5" + def __init__(self, *args): + if args and args[0] is _copy_sentinel: + self._h = args[1] + else: + self._h = _hash_new(*args) + def copy(self): + return _MD5(_copy_sentinel, self._h.copy()) + def update(self, *args): + f = self.update = self._h.update + f(*args) + def digest(self): + f = self.digest = self._h.digest + return f() + def hexdigest(self): + f = self.hexdigest = self._h.hexdigest + return f() + _MD5.new = _MD5 + return _MD5 + +new = __make_constructor() +del __make_constructor #: The size of the resulting hash in bytes. -digest_size = MD5Hash.digest_size +digest_size = new().digest_size #: The internal block size of the hash algorithm in bytes. -block_size = MD5Hash.block_size - +block_size = new().block_size diff --git a/lib/Crypto/Hash/RIPEMD160.py b/lib/Crypto/Hash/RIPEMD160.py deleted file mode 100644 index 2bfb26d..0000000 --- a/lib/Crypto/Hash/RIPEMD160.py +++ /dev/null @@ -1,84 +0,0 @@ -# -*- 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. -# =================================================================== - -"""RIPEMD-160 cryptographic hash algorithm. - -RIPEMD-160_ produces the 160 bit digest of a message. - - >>> from Crypto.Hash import RIPEMD160 - >>> - >>> h = RIPEMD160.new() - >>> h.update(b'Hello') - >>> print h.hexdigest() - -RIPEMD-160 stands for RACE Integrity Primitives Evaluation Message Digest -with a 160 bit digest. It was invented by Dobbertin, Bosselaers, and Preneel. - -This algorithm is considered secure, although it has not been scrutinized as -extensively as SHA-1. Moreover, it provides an informal security level of just -80bits. - -.. _RIPEMD-160: http://homes.esat.kuleuven.be/~bosselae/ripemd160.html -""" - -_revision__ = "$Id$" - -__all__ = ['new', 'digest_size', 'RIPEMD160Hash' ] - -from Crypto.Util.py3compat import * -from Crypto.Hash.hashalgo import HashAlgo - -import Crypto.Hash._RIPEMD160 as _RIPEMD160 -hashFactory = _RIPEMD160 - -class RIPEMD160Hash(HashAlgo): - """Class that implements a RIPMD-160 hash - - :undocumented: block_size - """ - - digest_size = 20 - block_size = 64 - - def __init__(self, data=None): - HashAlgo.__init__(self, hashFactory, data) - - def new(self, data=None): - return RIPEMD160Hash(data) - -def new(data=None): - """Return a fresh instance of the hash object. - - :Parameters: - data : byte string - The very first chunk of the message to hash. - It is equivalent to an early call to `RIPEMD160Hash.update()`. - Optional. - - :Return: A `RIPEMD160Hash` object - """ - return RIPEMD160Hash().new(data) - -#: The size of the resulting hash in bytes. -digest_size = RIPEMD160Hash.digest_size - -#: The internal block size of the hash algorithm in bytes. -block_size = RIPEMD160Hash.block_size - diff --git a/lib/Crypto/Hash/SHA1.py b/lib/Crypto/Hash/SHA1.py index afddf1a..9ad9f1e 100644 --- a/lib/Crypto/Hash/SHA1.py +++ b/lib/Crypto/Hash/SHA1.py @@ -35,55 +35,58 @@ This algorithm is not considered secure. Do not use it for new designs. .. _SHA-1: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf """ +from __future__ import nested_scopes + _revision__ = "$Id$" -__all__ = ['new', 'digest_size', 'SHA1Hash' ] +__all__ = ['new', 'block_size', 'digest_size'] from Crypto.Util.py3compat import * -from Crypto.Hash.hashalgo import HashAlgo - -try: - # The sha module is deprecated in Python 2.6, so use hashlib when possible. - import hashlib - hashFactory = hashlib.sha1 - -except ImportError: - import sha - hashFactory = sha - -class SHA1Hash(HashAlgo): - """Class that implements a SHA-1 hash - - :undocumented: block_size - """ - - digest_size = 20 - block_size = 64 - - def __init__(self, data=None): - self.name = "SHA1" - HashAlgo.__init__(self, hashFactory, data) - - def new(self, data=None): - return SHA1Hash(data) - -def new(data=None): - """Return a fresh instance of the hash object. - - :Parameters: - data : byte string - The very first chunk of the message to hash. - It is equivalent to an early call to `SHA1Hash.update()`. - Optional. - - :Return: A `SHA1Hash` object - """ - return SHA1Hash().new(data) +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * + +def __make_constructor(): + try: + # The sha module is deprecated in Python 2.6, so use hashlib when possible. + from hashlib import sha1 as _hash_new + except ImportError: + from sha import new as _hash_new + + h = _hash_new() + if hasattr(h, 'new') and hasattr(h, 'name') and hasattr(h, 'digest_size') and hasattr(h, 'block_size'): + # The module from stdlib has the API that we need. Just use it. + return _hash_new + else: + # Wrap the hash object in something that gives us the expected API. + _copy_sentinel = object() + class _SHA1(object): + digest_size = 20 + block_size = 64 + name = "sha1" + def __init__(self, *args): + if args and args[0] is _copy_sentinel: + self._h = args[1] + else: + self._h = _hash_new(*args) + def copy(self): + return _SHA1(_copy_sentinel, self._h.copy()) + def update(self, *args): + f = self.update = self._h.update + f(*args) + def digest(self): + f = self.digest = self._h.digest + return f() + def hexdigest(self): + f = self.hexdigest = self._h.hexdigest + return f() + _SHA1.new = _SHA1 + return _SHA1 + +new = __make_constructor() +del __make_constructor #: The size of the resulting hash in bytes. -digest_size = SHA1Hash.digest_size +digest_size = new().digest_size #: The internal block size of the hash algorithm in bytes. -block_size = SHA1Hash.block_size - - +block_size = new().block_size diff --git a/lib/Crypto/Hash/SHA224.py b/lib/Crypto/Hash/SHA224.py deleted file mode 100644 index 379bbb2..0000000 --- a/lib/Crypto/Hash/SHA224.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- 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. -# =================================================================== - -"""SHA-224 cryptographic hash algorithm. - -SHA-224 belongs to the SHA-2_ family of cryptographic hashes. -It produces the 224 bit digest of a message. - - >>> from Crypto.Hash import SHA224 - >>> - >>> h = SHA224.new() - >>> h.update(b'Hello') - >>> print h.hexdigest() - -*SHA* stands for Secure Hash Algorithm. - -.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf -""" - -_revision__ = "$Id$" - -__all__ = ['new', 'digest_size', 'SHA224Hash' ] - -from Crypto.Util.py3compat import * -from Crypto.Hash.hashalgo import HashAlgo - -try: - import hashlib - hashFactory = hashlib.sha224 - -except ImportError: - from Crypto.Hash import _SHA224 - hashFactory = _SHA224 - -class SHA224Hash(HashAlgo): - """Class that implements a SHA-224 hash - - :undocumented: block_size - """ - - digest_size = 28 - block_size = 64 - - def __init__(self, data=None): - HashAlgo.__init__(self, hashFactory, data) - - def new(self, data=None): - return SHA224Hash(data) - -def new(data=None): - """Return a fresh instance of the hash object. - - :Parameters: - data : byte string - The very first chunk of the message to hash. - It is equivalent to an early call to `SHA224Hash.update()`. - Optional. - - :Return: A `SHA224Hash` object - """ - return SHA224Hash().new(data) - -#: The size of the resulting hash in bytes. -digest_size = SHA224Hash.digest_size - -#: The internal block size of the hash algorithm in bytes. -block_size = SHA224Hash.block_size - diff --git a/lib/Crypto/Hash/SHA256.py b/lib/Crypto/Hash/SHA256.py deleted file mode 100644 index 46b7861..0000000 --- a/lib/Crypto/Hash/SHA256.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- 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. -# =================================================================== - -"""SHA-256 cryptographic hash algorithm. - -SHA-256 belongs to the SHA-2_ family of cryptographic hashes. -It produces the 256 bit digest of a message. - - >>> from Crypto.Hash import SHA256 - >>> - >>> h = SHA256.new() - >>> h.update(b'Hello') - >>> print h.hexdigest() - -*SHA* stands for Secure Hash Algorithm. - -.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf -""" - -_revision__ = "$Id$" - -__all__ = ['new', 'digest_size', 'SHA256Hash' ] - -from Crypto.Util.py3compat import * -from Crypto.Hash.hashalgo import HashAlgo - -try: - import hashlib - hashFactory = hashlib.sha256 - -except ImportError: - from Crypto.Hash import _SHA256 - hashFactory = _SHA256 - -class SHA256Hash(HashAlgo): - """Class that implements a SHA-256 hash - - :undocumented: block_size - """ - - digest_size = 32 - block_size = 64 - - def __init__(self, data=None): - HashAlgo.__init__(self, hashFactory, data) - - def new(self, data=None): - return SHA256Hash(data) - -def new(data=None): - """Return a fresh instance of the hash object. - - :Parameters: - data : byte string - The very first chunk of the message to hash. - It is equivalent to an early call to `SHA256Hash.update()`. - Optional. - - :Return: A `SHA256Hash` object - """ - return SHA256Hash().new(data) - -#: The size of the resulting hash in bytes. -digest_size = SHA256Hash.digest_size - -#: The internal block size of the hash algorithm in bytes. -block_size = SHA256Hash.block_size - diff --git a/lib/Crypto/Hash/SHA384.py b/lib/Crypto/Hash/SHA384.py deleted file mode 100644 index da6aca1..0000000 --- a/lib/Crypto/Hash/SHA384.py +++ /dev/null @@ -1,86 +0,0 @@ -# -*- 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. -# =================================================================== - -"""SHA-384 cryptographic hash algorithm. - -SHA-384 belongs to the SHA-2_ family of cryptographic hashes. -It produces the 384 bit digest of a message. - - >>> from Crypto.Hash import SHA384 - >>> - >>> h = SHA384.new() - >>> h.update(b'Hello') - >>> print h.hexdigest() - -*SHA* stands for Secure Hash Algorithm. - -.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf -""" - -_revision__ = "$Id$" - -__all__ = ['new', 'digest_size', 'SHA384Hash' ] - -from Crypto.Util.py3compat import * -from Crypto.Hash.hashalgo import HashAlgo - -try: - import hashlib - hashFactory = hashlib.sha384 - -except ImportError: - from Crypto.Hash import _SHA384 - hashFactory = _SHA384 - -class SHA384Hash(HashAlgo): - """Class that implements a SHA-384 hash - - :undocumented: block_size - """ - - digest_size = 48 - block_size = 128 - - def __init__(self, data=None): - HashAlgo.__init__(self, hashFactory, data) - - def new(self, data=None): - return SHA384Hash(data) - -def new(data=None): - """Return a fresh instance of the hash object. - - :Parameters: - data : byte string - The very first chunk of the message to hash. - It is equivalent to an early call to `SHA384Hash.update()`. - Optional. - - :Return: A `SHA384Hash` object - """ - return SHA384Hash().new(data) - -#: The size of the resulting hash in bytes. -digest_size = SHA384Hash.digest_size - -#: The internal block size of the hash algorithm in bytes. -block_size = SHA384Hash.block_size - - diff --git a/lib/Crypto/Hash/SHA512.py b/lib/Crypto/Hash/SHA512.py deleted file mode 100644 index d8a4c3a..0000000 --- a/lib/Crypto/Hash/SHA512.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- 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. -# =================================================================== - -"""SHA-512 cryptographic hash algorithm. - -SHA-512 belongs to the SHA-2_ family of cryptographic hashes. -It produces the 512 bit digest of a message. - - >>> from Crypto.Hash import SHA512 - >>> - >>> h = SHA512.new() - >>> h.update(b'Hello') - >>> print h.hexdigest() - -*SHA* stands for Secure Hash Algorithm. - -.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf -""" - -_revision__ = "$Id$" - -__all__ = ['new', 'digest_size', 'SHA512Hash' ] - -from Crypto.Util.py3compat import * -from Crypto.Hash.hashalgo import HashAlgo - -try: - import hashlib - hashFactory = hashlib.sha512 - -except ImportError: - from Crypto.Hash import _SHA512 - hashFactory = _SHA512 - -class SHA512Hash(HashAlgo): - """Class that implements a SHA-512 hash - - :undocumented: block_size - """ - - digest_size = 64 - block_size = 128 - - def __init__(self, data=None): - HashAlgo.__init__(self, hashFactory, data) - - def new(self, data=None): - return SHA512Hash(data) - -def new(data=None): - """Return a fresh instance of the hash object. - - :Parameters: - data : byte string - The very first chunk of the message to hash. - It is equivalent to an early call to `SHA512Hash.update()`. - Optional. - - :Return: A `SHA512Hash` object - """ - return SHA512Hash().new(data) - -#: The size of the resulting hash in bytes. -digest_size = SHA512Hash.digest_size - -#: The internal block size of the hash algorithm in bytes. -block_size = SHA512Hash.block_size - diff --git a/lib/Crypto/Hash/hashalgo.py b/lib/Crypto/Hash/hashalgo.py deleted file mode 100644 index a778bf4..0000000 --- a/lib/Crypto/Hash/hashalgo.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- 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. -# =================================================================== - -from binascii import hexlify - -class HashAlgo: - """A generic class for an abstract cryptographic hash algorithm. - - :undocumented: block_size - """ - - #: The size of the resulting hash in bytes. - digest_size = None - #: The internal block size of the hash algorithm in bytes. - block_size = None - - def __init__(self, hashFactory, data=None): - """Initialize the hash object. - - :Parameters: - hashFactory : callable - An object that will generate the actual hash implementation. - *hashFactory* must have a *new()* method, or must be directly - callable. - data : byte string - The very first chunk of the message to hash. - It is equivalent to an early call to `update()`. - """ - if hasattr(hashFactory, 'new'): - self._hash = hashFactory.new() - else: - self._hash = hashFactory() - try: - self.name = self._hash.name - except AttributeError: - pass - if data: - self.update(data) - - def update(self, data): - """Continue hashing of a message by consuming the next chunk of data. - - Repeated calls are equivalent to a single call with the concatenation - of all the arguments. In other words: - - >>> m.update(a); m.update(b) - - is equivalent to: - - >>> m.update(a+b) - - :Parameters: - data : byte string - The next chunk of the message being hashed. - """ - return self._hash.update(data) - - def digest(self): - """Return the **binary** (non-printable) digest of the message that has been hashed so far. - - This method does not change the state of the hash object. - You can continue updating the object after calling this function. - - :Return: A byte string of `digest_size` bytes. It may contain non-ASCII - characters, including null bytes. - """ - return self._hash.digest() - - def hexdigest(self): - """Return the **printable** digest of the message that has been hashed so far. - - This method does not change the state of the hash object. - - :Return: A string of 2* `digest_size` characters. It contains only - hexadecimal ASCII digits. - """ - return self._hash.hexdigest() - - def copy(self): - """Return a copy ("clone") of the hash object. - - The copy will have the same internal state as the original hash - object. - This can be used to efficiently compute the digests of strings that - share a common initial substring. - - :Return: A hash object of the same type - """ - return self._hash.copy() - - def new(self, data=None): - """Return a fresh instance of the hash object. - - Unlike the `copy` method, the internal state of the object is empty. - - :Parameters: - data : byte string - The next chunk of the message being hashed. - - :Return: A hash object of the same type - """ - pass - diff --git a/lib/Crypto/SelfTest/Hash/common.py b/lib/Crypto/SelfTest/Hash/common.py index 487e2cb..e722800 100644 --- a/lib/Crypto/SelfTest/Hash/common.py +++ b/lib/Crypto/SelfTest/Hash/common.py @@ -31,6 +31,8 @@ import unittest import binascii import Crypto.Hash from Crypto.Util.py3compat import * +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * # For compatibility with Python 2.1 and Python 2.2 if sys.hexversion < 0x02030000: @@ -95,11 +97,14 @@ class HashSelfTest(unittest.TestCase): self.assertEqual(self.expected.decode(), out3) # h = .new(data); h.hexdigest() self.assertEqual(self.expected, out4) # h = .new(data); h.digest() - # Verify that new() object method produces a fresh hash object - h2 = h.new() - h2.update(self.input) - out5 = binascii.b2a_hex(h2.digest()) - self.assertEqual(self.expected, out5) + # Verify that the .new() method produces a fresh hash object, except + # for MD5 and SHA1, which are hashlib objects. (But test any .new() + # method that does exist.) + if self.hashmod.__name__ not in ('Crypto.Hash.MD5', 'Crypto.Hash.SHA1') or hasattr(h, 'new'): + h2 = h.new() + h2.update(self.input) + out5 = binascii.b2a_hex(h2.digest()) + self.assertEqual(self.expected, out5) # Verify that Crypto.Hash.new(h) produces a fresh hash object h3 = Crypto.Hash.new(h) @@ -125,6 +130,16 @@ class HashTestOID(unittest.TestCase): h = self.hashmod.new() self.assertEqual(PKCS1_v1_5._HASH_OIDS[h.name], self.oid) +class HashDocStringTest(unittest.TestCase): + def __init__(self, hashmod): + unittest.TestCase.__init__(self) + self.hashmod = hashmod + + def runTest(self): + docstring = self.hashmod.__doc__ + self.assert_(hasattr(self.hashmod, '__doc__')) + self.assert_(isinstance(self.hashmod.__doc__, str)) + class GenericHashConstructorTest(unittest.TestCase): def __init__(self, hashmod): unittest.TestCase.__init__(self) @@ -208,6 +223,7 @@ def make_hash_tests(module, module_name, test_data, digest_size, oid=None): tests.append(HashDigestSizeSelfTest(module, name, digest_size)) if oid is not None: tests.append(HashTestOID(module, b(oid))) + tests.append(HashDocStringTest(module)) if getattr(module, 'name', None) is not None: tests.append(GenericHashConstructorTest(module)) return tests diff --git a/lib/Crypto/Signature/PKCS1_PSS.py b/lib/Crypto/Signature/PKCS1_PSS.py index cd9eaf3..3840959 100644 --- a/lib/Crypto/Signature/PKCS1_PSS.py +++ b/lib/Crypto/Signature/PKCS1_PSS.py @@ -72,6 +72,7 @@ if sys.version_info[0] == 2 and sys.version_info[1] == 1: import Crypto.Util.number from Crypto.Util.number import ceil_shift, ceil_div, long_to_bytes from Crypto.Util.strxor import strxor +from Crypto.Hash import new as Hash_new class PSS_SigScheme: """This signature scheme can perform PKCS#1 PSS RSA signature or verification.""" @@ -203,7 +204,11 @@ def MGF1(mgfSeed, maskLen, hash): T = b("") for counter in xrange(ceil_div(maskLen, hash.digest_size)): c = long_to_bytes(counter, 4) - T = T + hash.new(mgfSeed + c).digest() + try: + T = T + hash.new(mgfSeed + c).digest() + except AttributeError: + # hash object doesn't have a "new" method. Use Crypto.Hash.new() to instantiate it + T = T + Hash_new(hash, mgfSeed + c).digest() assert(len(T)>=maskLen) return T[:maskLen] @@ -253,7 +258,11 @@ def EMSA_PSS_ENCODE(mhash, emBits, randFunc, mgf, sLen): if randFunc and sLen>0: salt = randFunc(sLen) # Step 5 and 6 - h = mhash.new(bchr(0x00)*8 + mhash.digest() + salt) + try: + h = mhash.new(bchr(0x00)*8 + mhash.digest() + salt) + except AttributeError: + # hash object doesn't have a "new" method. Use Crypto.Hash.new() to instantiate it + h = Hash_new(mhash, bchr(0x00)*8 + mhash.digest() + salt) # Step 7 and 8 db = bchr(0x00)*(emLen-sLen-mhash.digest_size-2) + bchr(0x01) + salt # Step 9 @@ -328,7 +337,11 @@ def EMSA_PSS_VERIFY(mhash, em, emBits, mgf, sLen): salt = b("") if sLen: salt = db[-sLen:] # Step 12 and 13 - hp = mhash.new(bchr(0x00)*8 + mhash.digest() + salt).digest() + try: + hp = mhash.new(bchr(0x00)*8 + mhash.digest() + salt).digest() + except AttributeError: + # hash object doesn't have a "new" method. Use Crypto.Hash.new() to instantiate it + hp = Hash_new(mhash, bchr(0x00)*8 + mhash.digest() + salt).digest() # Step 14 if h!=hp: return False @@ -399,25 +399,25 @@ kw = {'name':"pycrypto", sources=["src/_fastmath.c"]), # Hash functions - Extension("Crypto.Hash._MD2", + Extension("Crypto.Hash.MD2", include_dirs=['src/'], sources=["src/MD2.c"]), - Extension("Crypto.Hash._MD4", + Extension("Crypto.Hash.MD4", include_dirs=['src/'], sources=["src/MD4.c"]), - Extension("Crypto.Hash._SHA256", + Extension("Crypto.Hash.SHA256", include_dirs=['src/'], sources=["src/SHA256.c"]), - Extension("Crypto.Hash._SHA224", + Extension("Crypto.Hash.SHA224", include_dirs=['src/'], sources=["src/SHA224.c"]), - Extension("Crypto.Hash._SHA384", + Extension("Crypto.Hash.SHA384", include_dirs=['src/'], sources=["src/SHA384.c"]), - Extension("Crypto.Hash._SHA512", + Extension("Crypto.Hash.SHA512", include_dirs=['src/'], sources=["src/SHA512.c"]), - Extension("Crypto.Hash._RIPEMD160", + Extension("Crypto.Hash.RIPEMD160", include_dirs=['src/'], sources=["src/RIPEMD160.c"], define_macros=[endianness_macro()]), @@ -31,21 +31,26 @@ #include <string.h> #include "pycrypto_compat.h" -#define MODULE_NAME _MD2 -#define ALGORITHM_NAME "MD2" +#define MODULE_NAME MD2 #define DIGEST_SIZE 16 #define BLOCK_SIZE 64 -/** - * id-md2 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) rsadsi(113549) - * digestAlgorithm(2) 2 - * } - */ -static const char md2_oid[] = { 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x02 }; - -#define DER_OID ((void*)&md2_oid) -#define DER_OID_SIZE (sizeof md2_oid) +static char MODULE__doc__[] = + "MD2 cryptographic hash algorithm.\n" + "\n" + "MD2 is specified in RFC1319_ and it produces the 128 bit digest of a message.\n" + "\n" + " >>> from Crypto.Hash import MD2\n" + " >>>\n" + " >>> h = MD2.new()\n" + " >>> h.update(b'Hello')\n" + " >>> print h.hexdigest()\n" + "\n" + "MD2 stand for Message Digest version 2, and it was invented by Rivest in 1989.\n" + "\n" + "This algorithm is both slow and insecure. Do not use it for new designs.\n" + "\n" + ".. _RFC1319: http://tools.ietf.org/html/rfc1319\n"; typedef unsigned char U8; typedef unsigned int U32; @@ -31,11 +31,27 @@ #include <string.h> #include "pycrypto_compat.h" -#define MODULE_NAME _MD4 -#define ALGORITHM_NAME "MD4" +#define MODULE_NAME MD4 #define DIGEST_SIZE 16 #define BLOCK_SIZE 64 +static char MODULE__doc__[] = + "MD4 cryptographic hash algorithm.\n" + "\n" + "MD4 is specified in RFC1320_ and produces the 128 bit digest of a message.\n" + "\n" + " >>> from Crypto.Hash import MD4\n" + " >>>\n" + " >>> h = MD4.new()\n" + " >>> h.update(b'Hello')\n" + " >>> print h.hexdigest()\n" + "\n" + "MD4 stand for Message Digest version 4, and it was invented by Rivest in 1990.\n" + "\n" + "This algorithm is insecure. Do not use it for new designs.\n" + "\n" + ".. _RFC1320: http://tools.ietf.org/html/rfc1320\n"; + typedef unsigned int U32; typedef unsigned char U8; #define U32_MAX (U32)4294967295 diff --git a/src/RIPEMD160.c b/src/RIPEMD160.c index 37d4c73..9593fc8 100644 --- a/src/RIPEMD160.c +++ b/src/RIPEMD160.c @@ -61,6 +61,26 @@ #define RIPEMD160_DIGEST_SIZE 20 #define BLOCK_SIZE 64 +static char MODULE__doc__[] = + "RIPEMD-160 cryptographic hash algorithm.\n" + "\n" + "RIPEMD-160_ produces the 160 bit digest of a message.\n" + "\n" + " >>> from Crypto.Hash import RIPEMD160\n" + " >>>\n" + " >>> h = RIPEMD160.new()\n" + " >>> h.update(b'Hello')\n" + " >>> print h.hexdigest()\n" + "\n" + "RIPEMD-160 stands for RACE Integrity Primitives Evaluation Message Digest\n" + "with a 160 bit digest. It was invented by Dobbertin, Bosselaers, and Preneel.\n" + "\n" + "This algorithm is considered secure, although it has not been scrutinized as\n" + "extensively as SHA-1. Moreover, it provides an informal security level of just\n" + "80bits.\n" + "\n" + ".. _RIPEMD-160: http://homes.esat.kuleuven.be/~bosselae/ripemd160.html\n"; + #define RIPEMD160_MAGIC 0x9f19dd68u typedef struct { uint32_t magic; @@ -401,8 +421,7 @@ static int ripemd160_digest(const ripemd160_state *self, unsigned char *out) } /* Template definitions */ -#define MODULE_NAME _RIPEMD160 -#define ALGORITHM_NAME "RIPEMD160" +#define MODULE_NAME RIPEMD160 #define DIGEST_SIZE RIPEMD160_DIGEST_SIZE #define hash_state ripemd160_state #define hash_init ripemd160_init diff --git a/src/SHA224.c b/src/SHA224.c index 99e2f7c..86591cf 100644 --- a/src/SHA224.c +++ b/src/SHA224.c @@ -27,13 +27,28 @@ * */ -#define MODULE_NAME _SHA224 -#define ALGORITHM_NAME "SHA224" +#define MODULE_NAME SHA224 #define DIGEST_SIZE (224/8) #define BLOCK_SIZE (512/8) #define WORD_SIZE 4 #define SCHEDULE_SIZE 64 +static char MODULE__doc__[] = + "SHA-224 cryptographic hash algorithm.\n" + "\n" + "SHA-224 belongs to the SHA-2_ family of cryptographic hashes.\n" + "It produces the 224 bit digest of a message.\n" + "\n" + " >>> from Crypto.Hash import SHA224\n" + " >>>\n" + " >>> h = SHA224.new()\n" + " >>> h.update(b'Hello')\n" + " >>> print h.hexdigest()\n" + "\n" + "*SHA* stands for Secure Hash Algorithm.\n" + "\n" + ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\n"; + #include "hash_SHA2.h" /* Initial Values H */ diff --git a/src/SHA256.c b/src/SHA256.c index 8cc3265..9473abc 100644 --- a/src/SHA256.c +++ b/src/SHA256.c @@ -26,13 +26,28 @@ * =================================================================== * */ -#define MODULE_NAME _SHA256 -#define ALGORITHM_NAME "SHA256" +#define MODULE_NAME SHA256 #define DIGEST_SIZE (256/8) #define BLOCK_SIZE (512/8) #define WORD_SIZE 4 #define SCHEDULE_SIZE 64 - + +static char MODULE__doc__[] = + "SHA-256 cryptographic hash algorithm.\n" + "\n" + "SHA-256 belongs to the SHA-2_ family of cryptographic hashes.\n" + "It produces the 256 bit digest of a message.\n" + "\n" + " >>> from Crypto.Hash import SHA256\n" + " >>>\n" + " >>> h = SHA256.new()\n" + " >>> h.update(b'Hello')\n" + " >>> print h.hexdigest()\n" + "\n" + "*SHA* stands for Secure Hash Algorithm.\n" + "\n" + ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\n"; + #include "hash_SHA2.h" /* Initial Values H */ diff --git a/src/SHA384.c b/src/SHA384.c index 24b200c..eb7051e 100644 --- a/src/SHA384.c +++ b/src/SHA384.c @@ -27,13 +27,28 @@ * */ -#define MODULE_NAME _SHA384 -#define ALGORITHM_NAME "SHA384" +#define MODULE_NAME SHA384 #define DIGEST_SIZE (384/8) #define BLOCK_SIZE (1024/8) #define WORD_SIZE 8 #define SCHEDULE_SIZE 80 +static char MODULE__doc__[] = + "SHA-384 cryptographic hash algorithm.\n" + "\n" + "SHA-384 belongs to the SHA-2_ family of cryptographic hashes.\n" + "It produces the 384 bit digest of a message.\n" + "\n" + " >>> from Crypto.Hash import SHA384\n" + " >>>\n" + " >>> h = SHA384.new()\n" + " >>> h.update(b'Hello')\n" + " >>> print h.hexdigest()\n" + "\n" + "*SHA* stands for Secure Hash Algorithm.\n" + "\n" + ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\n"; + #include "hash_SHA2.h" /* Initial Values H */ diff --git a/src/SHA512.c b/src/SHA512.c index 3b227ab..f12755c 100644 --- a/src/SHA512.c +++ b/src/SHA512.c @@ -27,13 +27,28 @@ * */ -#define MODULE_NAME _SHA512 -#define ALGORITHM_NAME "SHA512" +#define MODULE_NAME SHA512 #define DIGEST_SIZE (512/8) #define BLOCK_SIZE (1024/8) #define WORD_SIZE 8 #define SCHEDULE_SIZE 80 +static char MODULE__doc__[] = + "SHA-512 cryptographic hash algorithm.\n" + "\n" + "SHA-512 belongs to the SHA-2_ family of cryptographic hashes.\n" + "It produces the 512 bit digest of a message.\n" + "\n" + " >>> from Crypto.Hash import SHA512\n" + " >>>\n" + " >>> h = SHA512.new()\n" + " >>> h.update(b'Hello')\n" + " >>> print h.hexdigest()\n" + "\n" + "*SHA* stands for Secure Hash Algorithm.\n" + "\n" + ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\n"; + #include "hash_SHA2.h" /* Initial Values H */ diff --git a/src/hash_template.c b/src/hash_template.c index afffbfb..d085bb8 100644 --- a/src/hash_template.c +++ b/src/hash_template.c @@ -210,12 +210,12 @@ ALG_getattr(PyObject *self, char *name) if (PyUnicode_CompareWithASCIIString(attr, "digest_size")==0) return PyLong_FromLong(DIGEST_SIZE); if (PyUnicode_CompareWithASCIIString(attr, "name")==0) - return PyUnicode_FromString(ALGORITHM_NAME); + return PyUnicode_FromString(_MODULE_STRING); /* we should try to be compatible with hashlib here */ #else if (strcmp(name, "digest_size")==0) return PyInt_FromLong(DIGEST_SIZE); if (strcmp(name, "name")==0) - return PyString_FromString(ALGORITHM_NAME); + return PyString_FromString(_MODULE_STRING); /* we should try to be compatible with hashlib here */ #endif #ifdef IS_PY3K @@ -313,14 +313,14 @@ static struct PyMethodDef ALG_functions[] = { #ifdef IS_PY3K static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, - "Crypto.Hash." _MODULE_STRING, - NULL, - -1, - ALG_functions, - NULL, - NULL, - NULL, - NULL + "Crypto.Hash." _MODULE_STRING, /* m_name */ + MODULE__doc__, /* m_doc */ + -1, /* m_size */ + ALG_functions, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ }; #endif @@ -353,7 +353,7 @@ _MODULE_NAME (void) return NULL; #else ALGtype.ob_type = &PyType_Type; - m = Py_InitModule("Crypto.Hash." _MODULE_STRING, ALG_functions); + m = Py_InitModule3("Crypto.Hash." _MODULE_STRING, ALG_functions, MODULE__doc__); #endif /* Add some symbolic constants to the module */ |