diff options
25 files changed, 180 insertions, 86 deletions
diff --git a/lib/Crypto/Hash/HMAC.py b/lib/Crypto/Hash/HMAC.py index 333d563..cbdf1bd 100644 --- a/lib/Crypto/Hash/HMAC.py +++ b/lib/Crypto/Hash/HMAC.py @@ -63,7 +63,7 @@ class HMAC: msg: Initial input for the hash, if provided. digestmod: A module supporting PEP 247. Defaults to the md5 module. """ - if digestmod == None: + if digestmod is None: import MD5 digestmod = MD5 diff --git a/lib/Crypto/PublicKey/DSA.py b/lib/Crypto/PublicKey/DSA.py index baac1f0..5c349a9 100644 --- a/lib/Crypto/PublicKey/DSA.py +++ b/lib/Crypto/PublicKey/DSA.py @@ -29,7 +29,7 @@ __revision__ = "$Id$" __all__ = ['generate', 'construct', 'error'] import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.PublicKey import _DSA, _slowmath, pubkey diff --git a/lib/Crypto/PublicKey/RSA.py b/lib/Crypto/PublicKey/RSA.py index 3866324..d95f2cf 100644 --- a/lib/Crypto/PublicKey/RSA.py +++ b/lib/Crypto/PublicKey/RSA.py @@ -29,7 +29,7 @@ __revision__ = "$Id$" __all__ = ['generate', 'construct', 'error', 'importKey' ] import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * diff --git a/lib/Crypto/PublicKey/_slowmath.py b/lib/Crypto/PublicKey/_slowmath.py index c72a242..478b530 100644 --- a/lib/Crypto/PublicKey/_slowmath.py +++ b/lib/Crypto/PublicKey/_slowmath.py @@ -29,9 +29,9 @@ __revision__ = "$Id$" __all__ = ['rsa_construct'] import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: - from Crypto.Util.py21compat import * +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * from Crypto.Util.number import size, inverse class error(Exception): diff --git a/lib/Crypto/Random/Fortuna/FortunaAccumulator.py b/lib/Crypto/Random/Fortuna/FortunaAccumulator.py index 9935a0b..5ebbe2b 100644 --- a/lib/Crypto/Random/Fortuna/FortunaAccumulator.py +++ b/lib/Crypto/Random/Fortuna/FortunaAccumulator.py @@ -25,7 +25,7 @@ __revision__ = "$Id$" import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * @@ -62,7 +62,7 @@ class FortunaPool(object): return self._h.digest() def hexdigest(self): - if sys.version_info[0] is 2: + if sys.version_info[0] == 2: return b2a_hex(self.digest()) else: return b2a_hex(self.digest()).decode() diff --git a/lib/Crypto/Random/Fortuna/SHAd256.py b/lib/Crypto/Random/Fortuna/SHAd256.py index ac95fca..c28e5ba 100644 --- a/lib/Crypto/Random/Fortuna/SHAd256.py +++ b/lib/Crypto/Random/Fortuna/SHAd256.py @@ -32,7 +32,7 @@ __revision__ = "$Id$" __all__ = ['new', 'digest_size'] import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * @@ -74,7 +74,7 @@ class _SHAd256(object): """Return the hash value of this object as a (lowercase) hexadecimal string""" retval = b2a_hex(self.digest()) assert len(retval) == 64 - if sys.version_info[0] is 2: + if sys.version_info[0] == 2: return retval else: return retval.decode() @@ -89,7 +89,7 @@ digest_size = _SHAd256.digest_size # PEP 247 module-level "new" function def new(data=None): """Return a new SHAd256 hashing object""" - if data == None: + if data is None: data=b("") return _SHAd256(_SHAd256._internal, SHA256.new(data)) diff --git a/lib/Crypto/Random/OSRNG/rng_base.py b/lib/Crypto/Random/OSRNG/rng_base.py index ef037b8..54c3aa0 100644 --- a/lib/Crypto/Random/OSRNG/rng_base.py +++ b/lib/Crypto/Random/OSRNG/rng_base.py @@ -24,7 +24,7 @@ __revision__ = "$Id$" import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * class BaseRNG(object): diff --git a/lib/Crypto/Random/_UserFriendlyRNG.py b/lib/Crypto/Random/_UserFriendlyRNG.py index d6ab8c6..c2a2eae 100644 --- a/lib/Crypto/Random/_UserFriendlyRNG.py +++ b/lib/Crypto/Random/_UserFriendlyRNG.py @@ -25,7 +25,7 @@ __revision__ = "$Id$" import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * import os diff --git a/lib/Crypto/Random/random.py b/lib/Crypto/Random/random.py index fa1352a..28a99ea 100644 --- a/lib/Crypto/Random/random.py +++ b/lib/Crypto/Random/random.py @@ -29,7 +29,7 @@ __all__ = ['StrongRandom', 'getrandbits', 'randrange', 'randint', 'choice', 'shu from Crypto import Random import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * class StrongRandom(object): diff --git a/lib/Crypto/SelfTest/Hash/common.py b/lib/Crypto/SelfTest/Hash/common.py index 6095008..5f51142 100644 --- a/lib/Crypto/SelfTest/Hash/common.py +++ b/lib/Crypto/SelfTest/Hash/common.py @@ -67,7 +67,7 @@ class HashSelfTest(unittest.TestCase): # PY3K: hexdigest() should return str(), and digest() bytes self.assertEqual(self.expected, out1) # h = .new(); h.update(data); h.digest() - if sys.version_info[0] is 2: + if sys.version_info[0] == 2: self.assertEqual(self.expected, out2) # h = .new(); h.update(data); h.hexdigest() self.assertEqual(self.expected, out3) # h = .new(data); h.hexdigest() else: @@ -115,7 +115,7 @@ class MACSelfTest(unittest.TestCase): # PY3K: hexdigest() should return str(), and digest() bytes self.assertEqual(expected, out1) - if sys.version_info[0] is 2: + if sys.version_info[0] == 2: self.assertEqual(expected, out2) self.assertEqual(expected, out3) else: diff --git a/lib/Crypto/SelfTest/PublicKey/test_DSA.py b/lib/Crypto/SelfTest/PublicKey/test_DSA.py index a518a78..1186664 100644 --- a/lib/Crypto/SelfTest/PublicKey/test_DSA.py +++ b/lib/Crypto/SelfTest/PublicKey/test_DSA.py @@ -27,9 +27,10 @@ __revision__ = "$Id$" import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * +import os import unittest from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex @@ -224,7 +225,15 @@ def get_tests(config={}): from Crypto.PublicKey import _fastmath tests += list_test_cases(DSAFastMathTest) except ImportError: - pass + from distutils.sysconfig import get_config_var + import inspect + _fm_path = os.path.normpath(os.path.dirname(os.path.abspath( + inspect.getfile(inspect.currentframe()))) + +"/../../PublicKey/_fastmath"+get_config_var("SO")) + if os.path.exists(_fm_path): + raise ImportError("While the _fastmath module exists, importing "+ + "it failed. This may point to the gmp or mpir shared library "+ + "not being in the path. _fastmath was found at "+_fm_path) tests += list_test_cases(DSASlowMathTest) return tests diff --git a/lib/Crypto/SelfTest/PublicKey/test_RSA.py b/lib/Crypto/SelfTest/PublicKey/test_RSA.py index e659e2a..a93d752 100644 --- a/lib/Crypto/SelfTest/PublicKey/test_RSA.py +++ b/lib/Crypto/SelfTest/PublicKey/test_RSA.py @@ -27,7 +27,7 @@ __revision__ = "$Id$" import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * @@ -373,7 +373,15 @@ def get_tests(config={}): from Crypto.PublicKey import _fastmath tests += list_test_cases(RSAFastMathTest) except ImportError: - pass + from distutils.sysconfig import get_config_var + import inspect + _fm_path = os.path.normpath(os.path.dirname(os.path.abspath( + inspect.getfile(inspect.currentframe()))) + +"/../../PublicKey/_fastmath"+get_config_var("SO")) + if os.path.exists(_fm_path): + raise ImportError("While the _fastmath module exists, importing "+ + "it failed. This may point to the gmp or mpir shared library "+ + "not being in the path. _fastmath was found at "+_fm_path) tests += list_test_cases(RSASlowMathTest) return tests diff --git a/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py b/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py index 1b673d7..05a14c0 100644 --- a/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py +++ b/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py @@ -27,7 +27,7 @@ __revision__ = "$Id$" import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * diff --git a/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.py b/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.py index 518526a..d41bb02 100644 --- a/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.py +++ b/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.py @@ -27,7 +27,7 @@ __revision__ = "$Id$" import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * diff --git a/lib/Crypto/SelfTest/Util/test_Counter.py b/lib/Crypto/SelfTest/Util/test_Counter.py index 9a4ea77..33c9bd7 100644 --- a/lib/Crypto/SelfTest/Util/test_Counter.py +++ b/lib/Crypto/SelfTest/Util/test_Counter.py @@ -27,7 +27,7 @@ __revision__ = "$Id$" import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * diff --git a/lib/Crypto/SelfTest/Util/test_number.py b/lib/Crypto/SelfTest/Util/test_number.py index 35450eb..8397efd 100644 --- a/lib/Crypto/SelfTest/Util/test_number.py +++ b/lib/Crypto/SelfTest/Util/test_number.py @@ -27,7 +27,7 @@ __revision__ = "$Id$" import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * import unittest diff --git a/lib/Crypto/SelfTest/st_common.py b/lib/Crypto/SelfTest/st_common.py index 871a022..1cdcc1e 100644 --- a/lib/Crypto/SelfTest/st_common.py +++ b/lib/Crypto/SelfTest/st_common.py @@ -29,7 +29,7 @@ __revision__ = "$Id$" import unittest import binascii import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * diff --git a/lib/Crypto/Util/Counter.py b/lib/Crypto/Util/Counter.py index a10ec92..f00099b 100644 --- a/lib/Crypto/Util/Counter.py +++ b/lib/Crypto/Util/Counter.py @@ -23,7 +23,7 @@ # =================================================================== import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * diff --git a/lib/Crypto/Util/_number_new.py b/lib/Crypto/Util/_number_new.py index 83d2b9c..b040025 100644 --- a/lib/Crypto/Util/_number_new.py +++ b/lib/Crypto/Util/_number_new.py @@ -28,7 +28,7 @@ __revision__ = "$Id$" __all__ = ['ceil_shift', 'ceil_div', 'floor_div', 'exact_log2', 'exact_div'] import sys -if sys.version_info[0] is 2 and sys.version_info[1] is 1: +if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * def ceil_shift(n, b): diff --git a/lib/Crypto/Util/asn1.py b/lib/Crypto/Util/asn1.py index dcee6f3..1cbd529 100644 --- a/lib/Crypto/Util/asn1.py +++ b/lib/Crypto/Util/asn1.py @@ -103,7 +103,7 @@ class DerSequence(DerObject): return self._seq[n] def __setitem__(self, key, value): self._seq[key] = value - if sys.version_info[0] is 2: + if sys.version_info[0] == 2: def __setslice__(self,i,j,sequence): self._seq[i:j] = sequence def __delslice__(self,i,j): diff --git a/lib/Crypto/Util/number.py b/lib/Crypto/Util/number.py index 87bdc45..38cb973 100644 --- a/lib/Crypto/Util/number.py +++ b/lib/Crypto/Util/number.py @@ -35,6 +35,20 @@ bignum = long try: from Crypto.PublicKey import _fastmath except ImportError: + # For production, we are going to let import issues due to gmp/mpir shared + # libraries not loading slide silently and use slowmath. If you'd rather + # see an exception raised if _fastmath exists but cannot be imported, + # uncomment the below + # + # from distutils.sysconfig import get_config_var + # import inspect, os + # _fm_path = os.path.normpath(os.path.dirname(os.path.abspath( + # inspect.getfile(inspect.currentframe()))) + # +"/../../PublicKey/_fastmath"+get_config_var("SO")) + # if os.path.exists(_fm_path): + # raise ImportError("While the _fastmath module exists, importing "+ + # "it failed. This may point to the gmp or mpir shared library "+ + # "not being in the path. _fastmath was found at "+_fm_path) _fastmath = None # New functions @@ -64,7 +78,8 @@ def size (N): def getRandomNumber(N, randfunc=None): """Deprecated. Use getRandomInteger or getRandomNBitInteger instead.""" - warnings.warn("Crypto.Util.number.getRandomNumber has confusing semantics and has been deprecated. Use getRandomInteger or getRandomNBitInteger instead.", + warnings.warn("Crypto.Util.number.getRandomNumber has confusing semantics"+ + "and has been deprecated. Use getRandomInteger or getRandomNBitInteger instead.", GetRandomNumber_DeprecationWarning) return getRandomNBitInteger(N, randfunc) @@ -241,7 +256,8 @@ def getStrongPrime(N, e=0, false_positive_prob=1e-6, randfunc=None): # Use the accelerator if available if _fastmath is not None: - return _fastmath.getStrongPrime(long(N), long(e), false_positive_prob, randfunc) + return _fastmath.getStrongPrime(long(N), long(e), false_positive_prob, + randfunc) if (N < 512) or ((N % 128) != 0): raise ValueError ("bits must be multiple of 128 and > 512") @@ -420,7 +436,8 @@ def str2long(s): return bytes_to_long(s) def _import_Random(): - # This is called in a function instead of at the module level in order to avoid problems with recursive imports + # This is called in a function instead of at the module level in order to + # avoid problems with recursive imports global Random, StrongRandom from Crypto import Random from Crypto.Random.random import StrongRandom diff --git a/lib/Crypto/Util/py3compat.py b/lib/Crypto/Util/py3compat.py index 0d313d7..7c90de2 100755 --- a/lib/Crypto/Util/py3compat.py +++ b/lib/Crypto/Util/py3compat.py @@ -29,7 +29,7 @@ __revision__ = "$Id$" import sys -if sys.version_info[0] is 2: +if sys.version_info[0] == 2: def b(s): return s def bchr(s): diff --git a/python-3-changes.txt b/python-3-changes.txt index 51f9455..2b7b164 100755 --- a/python-3-changes.txt +++ b/python-3-changes.txt @@ -1,75 +1,112 @@ Py code:
-setup.py invokes 2to3 automatically. This handles int/long and print issues, among others.
-setup.py will touch nt.py on win32 after build and build again. This is necessary so 2to3 can do its magic on that file.
-
-There are still a lot of places in the code that need manual attention even with 2to3. They mostly have to do with string (2.x) vs. byte/unicode (3.x) representation
-
-Use "if sys.version_info[0] is 2:" where needed. Ideally, most of the conditional code can be in py3compat.
-
-Replace str(x) with bstr(x) if bytes were intended. Becomes str(x) in 2.x and bytes(x) in 3.x through py3compat module.
-Replace chr(x) with bchr(x) if bytes were intended. Becomes chr(x) in 2.x and bytes([x]) in 3.x through py3compat module.
-Replace ord(x) with bord(x) if bytes were intended. Becomes ord(x) in 2.x and x in 3.x through py3compat module.
-
-Comparing a string index to a string literal needs to be changed in 3.x, as b'string'[0] returns an integer, not b's'.
-The comparison can be fixed by indexing the right side, too: "if s[0]==b('\x30')[0]:" or "if self.typeTag!=self.typeTags['SEQUENCE'][0]:"
+setup.py invokes 2to3 automatically. This handles int/long and print issues,
+ among others.
+setup.py will touch nt.py on win32 after build and build again. This is
+ necessary so 2to3 can do its magic on that file.
+
+There are still a lot of places in the code that need manual attention even
+ with 2to3. They mostly have to do with string (2.x) vs. byte/unicode (3.x)
+ representation
+
+Use "if sys.version_info[0] == 2:" where needed. Ideally, most of the
+ conditional code can be in py3compat.
+
+Replace str(x) with bstr(x) if bytes were intended. Becomes str(x) in 2.x and
+ bytes(x) in 3.x through py3compat module.
+Replace chr(x) with bchr(x) if bytes were intended. Becomes chr(x) in 2.x and
+ bytes([x]) in 3.x through py3compat module.
+Replace ord(x) with bord(x) if bytes were intended. Becomes ord(x) in 2.x and
+ x in 3.x through py3compat module.
+
+Comparing a string index to a string literal needs to be changed in 3.x, as
+ b'string'[0] returns an integer, not b's'.
+The comparison can be fixed by indexing the right side, too:
+ "if s[0]==b('\x30')[0]:" or "if self.typeTag!=self.typeTags['SEQUENCE'][0]:"
String literals need to be bytes if bytes were intended.
-Replace "x" with b("x") if bytes were intended. Becomes "x" in 2.x, and s.encode("x","latin-1") in 3.x through py3compat module.
-For example, '"".join' is replaced by 'b("").join', and 's = ""' becomes 's = b("")'.
+Replace "x" with b("x") if bytes were intended. Becomes "x" in 2.x, and
+ s.encode("x","latin-1") in 3.x through py3compat module.
+For example, '"".join' is replaced by 'b("").join', and 's = ""' becomes
+ 's = b("")'.
Search for \x to find literals that may have been intended as byte strings
-!! However, where a human-readable ASCII text string output was intended, such as in AllOrNothing.undigest(), leave as a string literal !!
+!! However, where a human-readable ASCII text string output was intended,
+ such as in AllOrNothing.undigest(), leave as a string literal !!
-Only load python_compat.py "if sys.version_info[0] is 2 and sys.version_info[1] is 1:" .
-The assignment to True, False generates syntax errors in 3.x, and >= 2.2 don't need the compatibility code.
+Only load py21compat.py
+ "if sys.version_info[0] == 2 and sys.version_info[1] == 1:" .
+ The assignment to True, False generates syntax errors in 3.x, and >= 2.2 don't
+ need the compatibility code.
-Where print is used with >> to redirect, use a separate function instead. See setup.py for an example
+Where print is used with >> to redirect, use a separate function instead.
+ See setup.py for an example
-The string module has been changed in 3.x. It lost join and split, maketrans now expects bytes, and so on.
+The string module has been changed in 3.x. It lost join and split, maketrans
+ now expects bytes, and so on.
Replace string.join(a,b) with b.join(a).
Replace string.split(a) with a.split().
Replace body of white-space-stripping functions with 'return "".join(s.split())'
-Integer division via the "/" operator can return a float in 3.x. This causes issues in Util.number.getStrongPrime. As 2.1 does not support
-the "//" operator, divmod(a,b)[0] is used instead, to conform with an existing practice throughout the rest of the pycrypto code base.
+Integer division via the "/" operator can return a float in 3.x. This causes
+ issues in Util.number.getStrongPrime. As 2.1 does not support the "//"
+ operator, divmod(a,b)[0] is used instead, to conform with an existing practice
+ throughout the rest of the pycrypto code base.
-Do not use assert_/failUnless or failIf. These are deprecated and are scheduled to be removed in Python 3.3 and 3.4.
-Use instead assertEqual(expr,True) for assert_ and assertEqual(expr,False) for failIf
+Do not use assert_/failUnless or failIf. These are deprecated and are scheduled
+ to be removed in Python 3.3 and 3.4.
+Use instead assertEqual(expr,True) for assert_ and assertEqual(expr,False) for
+ failIf
C code:
-Extended "pycrypto_compat.h". It handles #define's for Python 3.x forward compatibility
+Extended "pycrypto_compat.h". It handles #define's for Python 3.x forward
+ compatibility
#include "pycrypto_compat.h"
-// All other local includes after this, so they can benefit from the definitions in pycrypto_compat.h
+// All other local includes after this, so they can benefit from the
+// definitions in pycrypto_compat.h
The compat header #defines IS_PY3K if compiling on 3.x
-The compat header #defines PyBytes_*, PyUnicode_*, PyBytesObject to resolve to their PyString* counterparts if compiling on 2.x.
-PyLong_* can be dangerous depending on code construct (think an if that runs PyInt_* with else PyLong_*),
+The compat header #defines PyBytes_*, PyUnicode_*, PyBytesObject to resolve to
+ their PyString* counterparts if compiling on 2.x.
+PyLong_* can be dangerous depending on code construct (think an if that runs
+ PyInt_* with else PyLong_*),
therefore it is #defined in each individual module if needed and safe to do so.
PyString_* has been replaced with PyBytes_* or PyUnicode_* depending on intent
-PyStringObject has been replaced with PyBytesObject or PyUnicodeObject depending on intent.
+PyStringObject has been replaced with PyBytesObject or PyUnicodeObject
+ depending on intent.
PyInt_* has been replaced with PyLong_*, where safe to do (in all cases so far)
The C code uses "#ifdef IS_PY3K" liberally.
Code duplication has been avoided.
-Module initialization and module structure differ significantly in 3.x. Conditionals take care of it.
+Module initialization and module structure differ significantly in 3.x.
+ Conditionals take care of it.
myModuleType.ob_type assignment conditionally becomes PyTypeReady for 3.x.
-getattr cannot be used to check against custom attributes in 3.x. For 3.x, conditional code uses getattro
-and PyUnicode_CompareWithASCIIString instead of strcmp
+getattr cannot be used to check against custom attributes in 3.x. For 3.x,
+ conditional code uses getattro and PyUnicode_CompareWithASCIIString instead
+ of strcmp
hexdigest() needed to be changed to return a Unicode object with 3.x
TODO:
-- Check for type of string in functions and throw an error when it's not correct. While at it, ensure that functions observe the guidelines below re type.
+- Check for type of string in functions and throw an error when it's not
+ correct. While at it, ensure that functions observe the guidelines below
+ re type.
This is friendlier than just relying on Python's errors.
-- Document the expected types for functions. The cipher, the key and the input texts are byte-strings. Plaintext decodes are byte-strings currently, this needs review.
- In keeping with how Python 3.x's hash functions work, the input MODE is a text string. hexdigest() returns a text string, and digest() returns a byte-string.
+- Document the expected types for functions.
+ The cipher, the key and the input texts are byte-strings.
+ Plaintext decodes are byte-strings. (?? Not true for all functions ??)
+ In keeping with how Python 3.x's hash functions work, the input MODE is a
+ text string.
+ hexdigest() returns a text string
+ digest() returns a byte-string.
- Look into LIBPATH/%LIB% and /NODEFAULTLIB:LIBCMT in setup.py for libgmp/libmpir
- Go through test cases and see which modules are not covered
-- Look into exclusions in setup.py
+- Make sure DerSequence slicing is tested, since I took the explicit slice functions
+ away in 3.x
+- Test install on all tested Python versions
@@ -36,9 +36,10 @@ __revision__ = "$Id$" -from distutils import core, fancy_getopt +from distutils import core from distutils.core import Extension, Command from distutils.command.build_ext import build_ext + import os, sys import struct @@ -59,7 +60,8 @@ else: plat_ext = [] # For test development: Set this to 1 to build with gcov support. -# Use "gcov -p -o build/temp.*/src build/temp.*/src/*.gcda" to build the .gcov files +# Use "gcov -p -o build/temp.*/src build/temp.*/src/*.gcda" to build the +# .gcov files USE_GCOV = 0 @@ -71,16 +73,16 @@ except ImportError: from distutils.command.build_py import build_py # List of pure Python modules that will be excluded from the binary packages. # The list consists of (package, module_name) tuples -if sys.version_info[0] is 2: - EXCLUDE_PY = [ - ('Crypto.Hash'), # Included for your amusement, but the C version is much faster. - ] +if sys.version_info[0] == 2: + EXCLUDE_PY = [] else: EXCLUDE_PY = [ - ('Crypto.Hash', 'Crypto.Util.python_compat'), # Included for your amusement, but the C version is much faster. Also, we don't want Py3k to choke on the 2.x compat code +# We don't want Py3k to choke on the 2.x compat code + ('Crypto.Util', 'py21compat'), ] -# Work around the print / print() issue with Python 2.x and 3.x. We only need to print at one point of the code, which makes this easy +# Work around the print / print() issue with Python 2.x and 3.x. We only need +# to print at one point of the code, which makes this easy def PrintErr(*args, **kwd): fout = kwd.get("file", sys.stderr) @@ -165,7 +167,8 @@ class PCTBuildExt (build_ext): self.__add_compiler_option("-fomit-frame-pointer") # Don't include debug symbols unless debugging self.__remove_compiler_option("-g") - # Don't include profiling information (incompatible with -fomit-frame-pointer) + # Don't include profiling information (incompatible with + # -fomit-frame-pointer) self.__remove_compiler_option("-pg") if USE_GCOV: self.__add_compiler_option("-fprofile-arcs") @@ -182,12 +185,28 @@ class PCTBuildExt (build_ext): # Detect libgmp or libmpir and don't build _fastmath if both are missing. lib_dirs = self.compiler.library_dirs + ['/lib', '/usr/lib'] - if not (self.compiler.find_library_file(lib_dirs, 'gmp') or self.compiler.find_library_file(lib_dirs, 'mpir')): - PrintErr ("warning: GMP or MPIR library not found; Not building Crypto.PublicKey._fastmath.") + if not (self.compiler.find_library_file(lib_dirs, 'gmp') or + self.compiler.find_library_file(lib_dirs, 'mpir')): + PrintErr ("warning: GMP or MPIR library not found; Not building "+ + "Crypto.PublicKey._fastmath.") self.__remove_extensions(["Crypto.PublicKey._fastmath"]) # Change library to libmpir if libgmp is missing elif not (self.compiler.find_library_file(lib_dirs, 'gmp')): - self.__change_extension_lib(["Crypto.PublicKey._fastmath"],['mpir']) + self.__change_extension_lib(["Crypto.PublicKey._fastmath"], + ['mpir']) + # And if this is Windows, we need to add a linker option + # to make a static libmpir link well into a dynamic _fastmath + if sys.platform == 'win32': + self.__add_extension_link_option(["Crypto.PublicKey._fastmath"], + ["/NODEFAULTLIB:LIBCMT"]) + + def __add_extension_link_option(self, names, options): + """Add linker options for the specified extension(s)""" + i = 0 + while i < len(self.extensions): + if self.extensions[i].name in names: + self.extensions[i].extra_link_args = options + i += 1 def __change_extension_lib(self, names, libs): """Change the libraries to be used for the specified extension(s)""" @@ -198,7 +217,8 @@ class PCTBuildExt (build_ext): i += 1 def __remove_extensions(self, names): - """Remove the specified extension(s) from the list of extensions to build""" + """Remove the specified extension(s) from the list of extensions + to build""" i = 0 while i < len(self.extensions): if self.extensions[i].name in names: @@ -228,7 +248,8 @@ class PCTBuildExt (build_ext): class PCTBuildPy(build_py): def find_package_modules(self, package, package_dir, *args, **kwargs): - modules = build_py.find_package_modules(self, package, package_dir, *args, **kwargs) + modules = build_py.find_package_modules(self, package, package_dir, + *args, **kwargs) # Exclude certain modules retval = [] @@ -264,7 +285,8 @@ class TestCommand(Command): try: sys.path.insert(0, self.build_dir) from Crypto import SelfTest - SelfTest.run(verbosity=self.verbose, stream=sys.stdout, config=self.config) + SelfTest.run(verbosity=self.verbose, stream=sys.stdout, + config=self.config) finally: # Restore sys.path sys.path[:] = old_path @@ -279,7 +301,8 @@ kw = {'name':"pycrypto", 'author_email':"dlitz@dlitz.net", 'url':"http://www.pycrypto.org/", - 'cmdclass' : {'build_ext':PCTBuildExt, 'build_py': PCTBuildPy, 'test': TestCommand }, + 'cmdclass' : {'build_ext':PCTBuildExt, 'build_py': PCTBuildPy, + 'test': TestCommand }, 'packages' : ["Crypto", "Crypto.Hash", "Crypto.Cipher", "Crypto.Util", "Crypto.Random", "Crypto.Random.Fortuna", @@ -298,7 +321,7 @@ kw = {'name':"pycrypto", 'ext_modules': plat_ext + [ # _fastmath (uses GNU mp library) Extension("Crypto.PublicKey._fastmath", - include_dirs=['src/'], + include_dirs=['src/','/usr/include/'], libraries=['gmp'], sources=["src/_fastmath.c"]), @@ -384,7 +407,8 @@ if hasattr(core, 'setup_keywords'): core.setup(**kw) #PY3K: Workaround for winrandom.pyd not existing during the first pass. # It needs to be there for 2to3 to fix the import in nt.py -if sys.platform == 'win32' and sys.version_info[0] is 3 and 'build' in sys.argv[1:]: +if (sys.platform == 'win32' and sys.version_info[0] == 3 and + 'build' in sys.argv[1:]): PrintErr("\nSecond pass to allow 2to3 to fix nt.py. No cause for alarm.\n") touch("./lib/Crypto/Random/OSRNG/nt.py") core.setup(**kw) diff --git a/src/_fastmath.c b/src/_fastmath.c index f3922cf..fe3fde3 100755 --- a/src/_fastmath.c +++ b/src/_fastmath.c @@ -1,4 +1,3 @@ - /* * _fastmath.c: Accelerator module that uses GMP for faster numerics. * |